Skip to content

Commit a53d444

Browse files
Merge pull request #3206 from windows-toolkit/xamlIslandsFixes
Xaml Islands Fixes.
2 parents fab5e1e + 24d1b5c commit a53d444

File tree

99 files changed

+2923
-252
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

99 files changed

+2923
-252
lines changed

Directory.Build.props

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,16 @@
4040
</When>
4141
</Choose>
4242

43+
<Choose>
44+
<When Condition="'$(Configuration)' == 'Debug' and '$(IsDesignProject)' != 'true'">
45+
<!-- Debug builds have this turned on by default, but it breaks our Xaml Islands Scenarios -->
46+
<PropertyGroup>
47+
<EnableTypeInfoReflection>false</EnableTypeInfoReflection>
48+
<EnableXBindDiagnostics>false</EnableXBindDiagnostics>
49+
</PropertyGroup>
50+
</When>
51+
</Choose>
52+
4353
<Choose>
4454
<When Condition="'$(IsTestProject)' != 'true' and '$(SourceLinkEnabled)' != 'false' and '$(IsSampleProject)' != 'true' and '$(IsDesignProject)' != 'true'">
4555
<PropertyGroup>

GazeInputTest/GazeInputTest.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@
150150
</ItemGroup>
151151
<ItemGroup>
152152
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
153-
<Version>6.2.9</Version>
153+
<Version>6.2.10</Version>
154154
</PackageReference>
155155
<PackageReference Include="StyleCop.Analyzers">
156156
<Version>1.0.2</Version>

Microsoft.Toolkit.Uwp.Connectivity/BluetoothLEHelper/BluetoothLEHelper.cs

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88
using System.Linq;
99
using System.Threading;
1010
using System.Threading.Tasks;
11-
using Windows.ApplicationModel.Core;
11+
using Microsoft.Toolkit.Uwp.Helpers;
1212
using Windows.Devices.Bluetooth;
1313
using Windows.Devices.Bluetooth.Advertisement;
1414
using Windows.Devices.Enumeration;
1515
using Windows.Foundation.Metadata;
16-
using Windows.UI.Core;
16+
using Windows.System;
1717

1818
namespace Microsoft.Toolkit.Uwp.Connectivity
1919
{
@@ -59,11 +59,19 @@ public class BluetoothLEHelper
5959
/// </summary>
6060
private BluetoothAdapter _adapter;
6161

62+
/// <summary>
63+
/// Gets or sets which DispatcherQueue is used to dispatch UI updates.
64+
/// </summary>
65+
public DispatcherQueue DispatcherQueue { get; set; }
66+
6267
/// <summary>
6368
/// Prevents a default instance of the <see cref="BluetoothLEHelper" /> class from being created.
6469
/// </summary>
65-
private BluetoothLEHelper()
70+
/// <param name="dispatcherQueue">The DispatcherQueue that should be used to dispatch UI updates, or null if this is being called from the UI thread.</param>
71+
private BluetoothLEHelper(DispatcherQueue dispatcherQueue = null)
6672
{
73+
DispatcherQueue = dispatcherQueue ?? DispatcherQueue.GetForCurrentThread();
74+
6775
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
6876
Init();
6977
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
@@ -201,8 +209,7 @@ private async Task Init()
201209
/// <param name="args">The advertisement.</param>
202210
private async void AdvertisementWatcher_Received(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
203211
{
204-
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
205-
CoreDispatcherPriority.Normal,
212+
await DispatcherQueue.ExecuteOnUIThreadAsync(
206213
() =>
207214
{
208215
if (_readerWriterLockSlim.TryEnterReadLock(TimeSpan.FromSeconds(1)))
@@ -217,7 +224,7 @@ await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
217224

218225
_readerWriterLockSlim.ExitReadLock();
219226
}
220-
});
227+
}, DispatcherQueuePriority.Normal);
221228
}
222229

223230
/// <summary>
@@ -286,19 +293,20 @@ private async void DeviceWatcher_Removed(DeviceWatcher sender, DeviceInformation
286293
// Protect against race condition if the task runs after the app stopped the deviceWatcher.
287294
if (sender == _deviceWatcher)
288295
{
289-
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
290-
{
291-
if (_readerWriterLockSlim.TryEnterWriteLock(TimeSpan.FromSeconds(1)))
296+
await DispatcherQueue.ExecuteOnUIThreadAsync(
297+
() =>
292298
{
293-
var device = BluetoothLeDevices.FirstOrDefault(i => i.DeviceInfo.Id == deviceInfoUpdate.Id);
294-
BluetoothLeDevices.Remove(device);
299+
if (_readerWriterLockSlim.TryEnterWriteLock(TimeSpan.FromSeconds(1)))
300+
{
301+
var device = BluetoothLeDevices.FirstOrDefault(i => i.DeviceInfo.Id == deviceInfoUpdate.Id);
302+
BluetoothLeDevices.Remove(device);
295303

296-
var unusedDevice = _unusedDevices.FirstOrDefault(i => i.Id == deviceInfoUpdate.Id);
297-
_unusedDevices?.Remove(unusedDevice);
304+
var unusedDevice = _unusedDevices.FirstOrDefault(i => i.Id == deviceInfoUpdate.Id);
305+
_unusedDevices?.Remove(unusedDevice);
298306

299-
_readerWriterLockSlim.ExitWriteLock();
300-
}
301-
});
307+
_readerWriterLockSlim.ExitWriteLock();
308+
}
309+
}, DispatcherQueuePriority.Normal);
302310
}
303311
}
304312

@@ -327,16 +335,15 @@ private async Task AddDeviceToList(DeviceInformation deviceInfo)
327335
// Make sure device name isn't blank or already present in the list.
328336
if (!string.IsNullOrEmpty(deviceInfo?.Name))
329337
{
330-
var device = new ObservableBluetoothLEDevice(deviceInfo);
338+
var device = new ObservableBluetoothLEDevice(deviceInfo, DispatcherQueue);
331339
var connectable = (device.DeviceInfo.Properties.Keys.Contains("System.Devices.Aep.Bluetooth.Le.IsConnectable") &&
332340
(bool)device.DeviceInfo.Properties["System.Devices.Aep.Bluetooth.Le.IsConnectable"]) ||
333341
(device.DeviceInfo.Properties.Keys.Contains("System.Devices.Aep.IsConnected") &&
334342
(bool)device.DeviceInfo.Properties["System.Devices.Aep.IsConnected"]);
335343

336344
if (connectable)
337345
{
338-
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
339-
CoreDispatcherPriority.Normal,
346+
await DispatcherQueue.ExecuteOnUIThreadAsync(
340347
() =>
341348
{
342349
if (_readerWriterLockSlim.TryEnterWriteLock(TimeSpan.FromSeconds(1)))
@@ -348,7 +355,7 @@ await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
348355

349356
_readerWriterLockSlim.ExitWriteLock();
350357
}
351-
});
358+
}, DispatcherQueuePriority.Normal);
352359

353360
return;
354361
}

Microsoft.Toolkit.Uwp.Connectivity/BluetoothLEHelper/ObservableBluetoothLEDevice.cs

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@
1111
using System.Runtime.CompilerServices;
1212
using System.Threading;
1313
using System.Threading.Tasks;
14-
using Windows.ApplicationModel.Core;
14+
using Microsoft.Toolkit.Uwp.Helpers;
1515
using Windows.Devices.Bluetooth;
1616
using Windows.Devices.Bluetooth.GenericAttributeProfile;
1717
using Windows.Devices.Enumeration;
18+
using Windows.System;
1819
using Windows.UI.Core;
1920
using Windows.UI.Xaml.Media.Imaging;
2021

@@ -134,17 +135,25 @@ public int Compare(object x, object y)
134135
private ObservableCollection<ObservableGattDeviceService> _services =
135136
new ObservableCollection<ObservableGattDeviceService>();
136137

138+
/// <summary>
139+
/// Gets or sets which DispatcherQueue is used to dispatch UI updates.
140+
/// </summary>
141+
public DispatcherQueue DispatcherQueue { get; set; }
142+
137143
/// <summary>
138144
/// Initializes a new instance of the <see cref="ObservableBluetoothLEDevice"/> class.
139145
/// </summary>
140146
/// <param name="deviceInfo">The device information.</param>
141-
public ObservableBluetoothLEDevice(DeviceInformation deviceInfo)
147+
/// <param name="dispatcherQueue">The DispatcherQueue that should be used to dispatch UI updates for this BluetoothLE Device, or null if this is being called from the UI thread.</param>
148+
public ObservableBluetoothLEDevice(DeviceInformation deviceInfo, DispatcherQueue dispatcherQueue = null)
142149
{
143150
DeviceInfo = deviceInfo;
144151
Name = DeviceInfo.Name;
145152

146153
IsPaired = DeviceInfo.Pairing.IsPaired;
147154

155+
DispatcherQueue = dispatcherQueue ?? DispatcherQueue.GetForCurrentThread();
156+
148157
LoadGlyph();
149158

150159
this.PropertyChanged += ObservableBluetoothLEDevice_PropertyChanged;
@@ -395,7 +404,8 @@ private void ObservableBluetoothLEDevice_PropertyChanged(object sender, Property
395404
/// <exception cref="Exception">Thorws Exception when no permission to access device</exception>
396405
public async Task ConnectAsync()
397406
{
398-
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
407+
await DispatcherQueue.ExecuteOnUIThreadAsync(
408+
async () =>
399409
{
400410
if (BluetoothLEDevice == null)
401411
{
@@ -442,7 +452,7 @@ await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPrio
442452
throw new Exception(_result.ProtocolError.GetErrorString());
443453
}
444454
}
445-
});
455+
}, DispatcherQueuePriority.Normal);
446456
}
447457

448458
/// <summary>
@@ -468,8 +478,7 @@ public async Task DoInAppPairingAsync()
468478
/// <returns>The task of the update.</returns>
469479
public async Task UpdateAsync(DeviceInformationUpdate deviceUpdate)
470480
{
471-
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
472-
CoreDispatcherPriority.Normal,
481+
await DispatcherQueue.ExecuteOnUIThreadAsync(
473482
() =>
474483
{
475484
DeviceInfo.Update(deviceUpdate);
@@ -479,7 +488,7 @@ await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
479488

480489
LoadGlyph();
481490
OnPropertyChanged("DeviceInfo");
482-
});
491+
}, DispatcherQueuePriority.Normal);
483492
}
484493

485494
/// <summary>
@@ -512,9 +521,7 @@ protected virtual void OnPropertyChanged([CallerMemberName] string propertyName
512521
/// <param name="args">The arguments.</param>
513522
private async void BluetoothLEDevice_NameChanged(BluetoothLEDevice sender, object args)
514523
{
515-
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
516-
CoreDispatcherPriority.Normal,
517-
() => { Name = BluetoothLEDevice.Name; });
524+
await DispatcherQueue.ExecuteOnUIThreadAsync(() => { Name = BluetoothLEDevice.Name; }, DispatcherQueuePriority.Normal);
518525
}
519526

520527
/// <summary>
@@ -524,29 +531,27 @@ await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
524531
/// <param name="args">The arguments.</param>
525532
private async void BluetoothLEDevice_ConnectionStatusChanged(BluetoothLEDevice sender, object args)
526533
{
527-
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
528-
CoreDispatcherPriority.Normal,
534+
await DispatcherQueue.ExecuteOnUIThreadAsync(
529535
() =>
530536
{
531537
IsPaired = DeviceInfo.Pairing.IsPaired;
532538
IsConnected = BluetoothLEDevice.ConnectionStatus == BluetoothConnectionStatus.Connected;
533-
});
539+
}, DispatcherQueuePriority.Normal);
534540
}
535541

536542
/// <summary>
537543
/// Load the glyph for this device
538544
/// </summary>
539545
private async void LoadGlyph()
540546
{
541-
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
542-
CoreDispatcherPriority.Normal,
547+
await DispatcherQueue.ExecuteOnUIThreadAsync(
543548
async () =>
544549
{
545550
var deviceThumbnail = await DeviceInfo.GetGlyphThumbnailAsync();
546551
var glyphBitmapImage = new BitmapImage();
547552
await glyphBitmapImage.SetSourceAsync(deviceThumbnail);
548553
Glyph = glyphBitmapImage;
549-
});
554+
}, DispatcherQueuePriority.Normal);
550555
}
551556
}
552557
}

Microsoft.Toolkit.Uwp.Connectivity/BluetoothLEHelper/ObservableGattCharacteristics.cs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77
using System.Linq;
88
using System.Runtime.CompilerServices;
99
using System.Threading.Tasks;
10+
using Microsoft.Toolkit.Uwp.Helpers;
1011
using Windows.Devices.Bluetooth;
1112
using Windows.Devices.Bluetooth.GenericAttributeProfile;
1213
using Windows.Security.Cryptography;
1314
using Windows.Storage.Streams;
15+
using Windows.System;
1416

1517
namespace Microsoft.Toolkit.Uwp.Connectivity
1618
{
@@ -110,13 +112,21 @@ public enum DisplayTypes
110112
/// </summary>
111113
private string _value;
112114

115+
/// <summary>
116+
/// Gets or sets which DispatcherQueue is used to dispatch UI updates.
117+
/// </summary>
118+
public DispatcherQueue DispatcherQueue { get; set; }
119+
113120
/// <summary>
114121
/// Initializes a new instance of the <see cref="ObservableGattCharacteristics"/> class.
115122
/// </summary>
116123
/// <param name="characteristic">The characteristic.</param>
117124
/// <param name="parent">The parent.</param>
118-
public ObservableGattCharacteristics(GattCharacteristic characteristic, ObservableGattDeviceService parent)
125+
/// <param name="dispatcherQueue">The DispatcherQueue that should be used to dispatch UI updates, or null if this is being called from the UI thread.</param>
126+
public ObservableGattCharacteristics(GattCharacteristic characteristic, ObservableGattDeviceService parent, DispatcherQueue dispatcherQueue = null)
119127
{
128+
DispatcherQueue = dispatcherQueue ?? DispatcherQueue.GetForCurrentThread();
129+
120130
Characteristic = characteristic;
121131
Parent = parent;
122132
Name = GattUuidsService.ConvertUuidToName(Characteristic.Uuid);
@@ -459,9 +469,7 @@ protected virtual void OnPropertyChanged([CallerMemberName] string propertyName
459469
/// <param name="args">The <see cref="GattValueChangedEventArgs"/> instance containing the event data.</param>
460470
private async void Characteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
461471
{
462-
await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
463-
Windows.UI.Core.CoreDispatcherPriority.Normal,
464-
() => { SetValue(args.CharacteristicValue); });
472+
await DispatcherQueue.ExecuteOnUIThreadAsync(() => { SetValue(args.CharacteristicValue); }, DispatcherQueuePriority.Normal);
465473
}
466474

467475
/// <summary>

Microsoft.Toolkit.Uwp.SampleApp/Controls/CodeRenderer.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,14 @@ protected override void OnApplyTemplate()
8787

8888
private void RenderDocument()
8989
{
90-
_codeView?.Blocks?.Clear();
91-
_formatter = new RichTextBlockFormatter(_theme);
92-
_formatter.FormatRichTextBlock(_displayedText, _language, _codeView);
93-
_rendered = true;
90+
if (_codeView != null)
91+
{
92+
_codeView.Blocks?.Clear();
93+
_formatter = new RichTextBlockFormatter(_theme);
94+
95+
_formatter.FormatRichTextBlock(_displayedText, _language, _codeView);
96+
_rendered = true;
97+
}
9498
}
9599

96100
private void CopyButton_Click(object sender, RoutedEventArgs e)

Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@
106106
</PropertyGroup>
107107
<ItemGroup>
108108
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
109-
<Version>6.2.9</Version>
109+
<Version>6.2.10</Version>
110110
</PackageReference>
111111
<PackageReference Include="Microsoft.Services.Store.Engagement">
112112
<Version>10.1901.28001</Version>
@@ -292,7 +292,7 @@
292292
<Content Include="SamplePages\CameraHelper\CameraHelper.png" />
293293
<Content Include="SamplePages\Connected Animations\ConnectedAnimations.png" />
294294
<Content Include="SamplePages\DataGrid\DataGrid.png" />
295-
<Content Include="SamplePages\DispatcherHelper\DispatchHelper.png" />
295+
<Content Include="SamplePages\DispatcherQueueHelper\DispatchQueueHelper.png" />
296296
<Content Include="SamplePages\DockPanel\DockPanel.png" />
297297
<Content Include="SamplePages\Facebook Service\FacebookLogo.png" />
298298
<Content Include="SamplePages\LoginButton\LoginButton.png" />
@@ -456,7 +456,7 @@
456456
<Content Include="SamplePages\InAppNotification\InAppNotificationXaml.bind" />
457457
<Content Include="SamplePages\ListViewExtensions\ListViewExtensionsCode.bind" />
458458
<Content Include="SamplePages\Implicit Animations\ImplicitAnimationsCode.bind" />
459-
<Content Include="SamplePages\DispatcherHelper\DispatcherHelperCode.bind" />
459+
<Content Include="SamplePages\DispatcherQueueHelper\DispatcherQueueHelperCode.bind" />
460460
<Content Include="SamplePages\TextToolbar\TextToolbar.bind" />
461461
<Content Include="SamplePages\DockPanel\DockPanel.bind">
462462
<SubType>Designer</SubType>
@@ -726,8 +726,8 @@
726726
<Compile Include="SamplePages\BackgroundTaskHelper\BackgroundTaskHelperPage.xaml.cs">
727727
<DependentUpon>BackgroundTaskHelperPage.xaml</DependentUpon>
728728
</Compile>
729-
<Compile Include="SamplePages\DispatcherHelper\DispatcherHelperPage.xaml.cs">
730-
<DependentUpon>DispatcherHelperPage.xaml</DependentUpon>
729+
<Compile Include="SamplePages\DispatcherQueueHelper\DispatcherQueueHelperPage.xaml.cs">
730+
<DependentUpon>DispatcherQueueHelperPage.xaml</DependentUpon>
731731
</Compile>
732732
<Compile Include="SamplePages\DropShadowPanel\DropShadowPanelPage.xaml.cs">
733733
<DependentUpon>DropShadowPanelPage.xaml</DependentUpon>
@@ -1151,7 +1151,7 @@
11511151
<SubType>Designer</SubType>
11521152
<Generator>MSBuild:Compile</Generator>
11531153
</Page>
1154-
<Page Include="SamplePages\DispatcherHelper\DispatcherHelperPage.xaml">
1154+
<Page Include="SamplePages\DispatcherQueueHelper\DispatcherQueueHelperPage.xaml">
11551155
<SubType>Designer</SubType>
11561156
<Generator>MSBuild:Compile</Generator>
11571157
</Page>

Microsoft.Toolkit.Uwp.SampleApp/SamplePages/DispatcherHelper/DispatcherHelperCode.bind renamed to Microsoft.Toolkit.Uwp.SampleApp/SamplePages/DispatcherQueueHelper/DispatcherQueueHelperCode.bind

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1+
// From a UI thread, capture the DispatcherQueue once:
2+
var dispatcherQueue = DispatcherQueue.GetForCurrentThread();
3+
4+
// The use it from any other thread
15
int crossThreadReturnedValue = await Task.Run<int>( async () =>
26
{
37
// Task.Run() will guarantee the given piece of code be executed on a seperate thread pool.
48
// This is used to simulate the scenario of updating the UI element from a different thread.
5-
int returnedFromUIThread = await DispatcherHelper.ExecuteOnUIThreadAsync<int>(() =>
9+
int returnedFromUIThread = await dispatcherQueue.ExecuteOnUIThreadAsync<int>(() =>
610
{
711
NormalTextBlock.Text = "Updated from a random thread!";
812
return 1;

Microsoft.Toolkit.Uwp.SampleApp/SamplePages/DispatcherHelper/DispatcherHelperPage.xaml renamed to Microsoft.Toolkit.Uwp.SampleApp/SamplePages/DispatcherQueueHelper/DispatcherQueueHelperPage.xaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Page x:Class="Microsoft.Toolkit.Uwp.SampleApp.SamplePages.DispatcherHelperPage"
1+
<Page x:Class="Microsoft.Toolkit.Uwp.SampleApp.SamplePages.DispatcherQueueHelperPage"
22
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
33
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
44
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

0 commit comments

Comments
 (0)