Xaml Islands Tests now work properly with UIThread.

Many other Xaml Islands fixes.
This commit is contained in:
Alexandre Zollinger Chohfi 2020-04-03 01:06:42 -07:00
Родитель 8b9a3ba459
Коммит 8f81e73475
37 изменённых файлов: 1327 добавлений и 139 удалений

Просмотреть файл

@ -76,7 +76,7 @@ namespace Microsoft.Toolkit.Uwp.SampleApp
await RunAppInitialization(e?.Arguments);
}
SystemInformation.Instance.TrackAppUse(e);
SystemInformation.Instance.TrackAppUse(e, Window.Current.Content.XamlRoot);
}
/// <summary>

Просмотреть файл

@ -246,11 +246,11 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls.Primitives
{
cell.Measure(new Size(column.ActualMaxWidth, measureHeight));
this.OwningGrid.AutoSizeColumn(column, cell.DesiredSize.Width);
column.ComputeLayoutRoundedWidth(totalDisplayWidth);
column.ComputeLayoutRoundedWidth(totalDisplayWidth, GetScale());
}
else if (!this.OwningGrid.UsesStarSizing)
{
column.ComputeLayoutRoundedWidth(scrollingLeftEdge);
column.ComputeLayoutRoundedWidth(scrollingLeftEdge, GetScale());
cell.Measure(new Size(column.LayoutRoundedWidth, measureHeight));
}
@ -283,7 +283,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls.Primitives
foreach (DataGridColumn column in this.OwningGrid.ColumnsInternal.GetVisibleColumns())
{
DataGridCell cell = this.OwningRow.Cells[column.Index];
column.ComputeLayoutRoundedWidth(leftEdge);
column.ComputeLayoutRoundedWidth(leftEdge, GetScale());
cell.Measure(new Size(column.LayoutRoundedWidth, measureHeight));
if (autoSizeHeight)
{
@ -302,6 +302,18 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls.Primitives
return new Size(this.OwningGrid.ColumnsInternal.VisibleEdgedColumnsWidth, this.DesiredHeight);
}
private double GetScale()
{
if (OwningGrid.XamlRoot != null)
{
return OwningGrid.XamlRoot.RasterizationScale;
}
else
{
return Windows.Graphics.Display.DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel;
}
}
internal void Recycle()
{
// Clear out the cached desired height so it is not reused for other rows

Просмотреть файл

@ -1055,11 +1055,10 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
/// rounding process, so we need to do it ourselves. If we don't, then we'll end up with some
/// pixel gaps and/or overlaps between columns.
/// </summary>
internal void ComputeLayoutRoundedWidth(double leftEdge)
internal void ComputeLayoutRoundedWidth(double leftEdge, double scale)
{
if (this.OwningGrid != null && this.OwningGrid.UseLayoutRounding)
{
double scale = Windows.Graphics.Display.DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel;
double roundedLeftEdge = Math.Floor((scale * leftEdge) + 0.5) / scale;
double roundedRightEdge = Math.Floor((scale * (leftEdge + this.ActualWidth)) + 0.5) / scale;
this.LayoutRoundedWidth = roundedRightEdge - roundedLeftEdge;

Просмотреть файл

@ -338,11 +338,11 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls.Primitives
{
columnHeader.Measure(new Size(column.ActualMaxWidth, double.PositiveInfinity));
this.OwningGrid.AutoSizeColumn(column, columnHeader.DesiredSize.Width);
column.ComputeLayoutRoundedWidth(totalDisplayWidth);
column.ComputeLayoutRoundedWidth(totalDisplayWidth, GetScale());
}
else if (!this.OwningGrid.UsesStarSizing)
{
column.ComputeLayoutRoundedWidth(totalDisplayWidth);
column.ComputeLayoutRoundedWidth(totalDisplayWidth, GetScale());
columnHeader.Measure(new Size(column.LayoutRoundedWidth, double.PositiveInfinity));
}
@ -367,7 +367,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls.Primitives
double leftEdge = 0;
foreach (var column in this.OwningGrid.ColumnsInternal.GetVisibleColumns())
{
column.ComputeLayoutRoundedWidth(leftEdge);
column.ComputeLayoutRoundedWidth(leftEdge, GetScale());
column.HeaderCell.Measure(new Size(column.LayoutRoundedWidth, double.PositiveInfinity));
if (autoSizeHeight)
{
@ -407,6 +407,18 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls.Primitives
return new Size(this.OwningGrid.ColumnsInternal.VisibleEdgedColumnsWidth, height);
}
private double GetScale()
{
if (OwningGrid.XamlRoot != null)
{
return OwningGrid.XamlRoot.RasterizationScale;
}
else
{
return Windows.Graphics.Display.DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel;
}
}
/// <summary>
/// Creates AutomationPeer (<see cref="UIElement.OnCreateAutomationPeer"/>)
/// </summary>

Просмотреть файл

@ -36,7 +36,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
UpdatePreview(x, y);
}
private void UpadateWorkArea()
private void UpdateWorkArea()
{
if (_targetGrid == null)
{
@ -50,9 +50,20 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
else
{
var left = WorkArea.Left;
var right = Window.Current.Bounds.Width - WorkArea.Right;
var top = WorkArea.Top;
var bottom = Window.Current.Bounds.Height - WorkArea.Bottom;
double right;
double bottom;
if (_popup.XamlRoot != null)
{
right = _popup.XamlRoot.Size.Width - WorkArea.Right;
bottom = _popup.XamlRoot.Size.Height - WorkArea.Bottom;
}
else
{
right = Window.Current.Bounds.Width - WorkArea.Right;
bottom = Window.Current.Bounds.Height - WorkArea.Bottom;
}
_targetGrid.Margin = new Thickness(left, top, right, bottom);
}
}
@ -98,12 +109,30 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
internal async Task UpdateAppScreenshotAsync()
{
double scale;
double width;
double height;
UIElement content;
if (_popup.XamlRoot != null)
{
scale = _popup.XamlRoot.RasterizationScale;
width = _popup.XamlRoot.Size.Width;
height = _popup.XamlRoot.Size.Width;
content = _popup.XamlRoot.Content;
}
else
{
var displayInfo = DisplayInformation.GetForCurrentView();
scale = displayInfo.RawPixelsPerViewPixel;
width = Window.Current.Bounds.Width;
height = Window.Current.Bounds.Width;
content = Window.Current.Content;
}
var renderTarget = new RenderTargetBitmap();
var diaplayInfo = DisplayInformation.GetForCurrentView();
var scale = diaplayInfo.RawPixelsPerViewPixel;
var scaleWidth = (int)Math.Ceiling(Window.Current.Bounds.Width / scale);
var scaleHeight = (int)Math.Ceiling(Window.Current.Bounds.Height / scale);
await renderTarget.RenderAsync(Window.Current.Content, scaleWidth, scaleHeight);
var scaleWidth = (int)Math.Ceiling(width / scale);
var scaleHeight = (int)Math.Ceiling(height / scale);
await renderTarget.RenderAsync(content, scaleWidth, scaleHeight);
var pixels = await renderTarget.GetPixelsAsync();
_appScreenshot = CanvasBitmap.CreateFromBytes(_device, pixels, renderTarget.PixelWidth, renderTarget.PixelHeight, DirectXPixelFormat.B8G8R8A8UIntNormalized);
}

Просмотреть файл

@ -71,7 +71,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
{
if (d is Eyedropper eyedropper)
{
eyedropper.UpadateWorkArea();
eyedropper.UpdateWorkArea();
}
}
}

Просмотреть файл

@ -45,7 +45,8 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
/// <summary>
/// Initializes a new instance of the <see cref="Eyedropper"/> class.
/// </summary>
public Eyedropper()
/// <param name="xamlRoot">The XamlRoot object that will be used for the Eyedropper. This is required for Xaml Islands.</param>
public Eyedropper(XamlRoot xamlRoot = null)
{
DefaultStyleKey = typeof(Eyedropper);
_rootGrid = new Grid();
@ -57,6 +58,11 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
{
Child = _rootGrid
};
if (xamlRoot != null)
{
_popup.XamlRoot = xamlRoot;
}
RenderTransform = _layoutTransform;
_previewImageSource = new CanvasImageSource(_device, PreviewPixelsPerRawPixel * PixelCountPerRow, PreviewPixelsPerRawPixel * PixelCountPerRow, 96f);
Preview = _previewImageSource;
@ -100,9 +106,18 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
_rootGrid.Children.Add(_targetGrid);
_rootGrid.Children.Add(this);
_rootGrid.Width = Window.Current.Bounds.Width;
_rootGrid.Height = Window.Current.Bounds.Height;
UpadateWorkArea();
if (_popup.XamlRoot != null)
{
_rootGrid.Width = _popup.XamlRoot.Size.Width;
_rootGrid.Height = _popup.XamlRoot.Size.Height;
}
else
{
_rootGrid.Width = Window.Current.Bounds.Width;
_rootGrid.Height = Window.Current.Bounds.Height;
}
UpdateWorkArea();
_popup.IsOpen = true;
var result = await _taskSource.Task;
_taskSource = null;
@ -124,21 +139,55 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
private void HookUpEvents()
{
Unloaded -= Eyedropper_Unloaded;
Unloaded += Eyedropper_Unloaded;
Window.Current.SizeChanged += Window_SizeChanged;
DisplayInformation.GetForCurrentView().DpiChanged += Eyedropper_DpiChanged;
if (XamlRoot != null)
{
XamlRoot.Changed -= XamlRoot_Changed;
XamlRoot.Changed += XamlRoot_Changed;
}
else
{
var window = Window.Current;
window.SizeChanged -= Window_SizeChanged;
window.SizeChanged += Window_SizeChanged;
var displayInformation = DisplayInformation.GetForCurrentView();
displayInformation.DpiChanged -= Eyedropper_DpiChanged;
displayInformation.DpiChanged += Eyedropper_DpiChanged;
}
_targetGrid.PointerEntered -= TargetGrid_PointerEntered;
_targetGrid.PointerEntered += TargetGrid_PointerEntered;
_targetGrid.PointerExited -= TargetGrid_PointerExited;
_targetGrid.PointerExited += TargetGrid_PointerExited;
_targetGrid.PointerPressed -= TargetGrid_PointerPressed;
_targetGrid.PointerPressed += TargetGrid_PointerPressed;
_targetGrid.PointerMoved -= TargetGrid_PointerMoved;
_targetGrid.PointerMoved += TargetGrid_PointerMoved;
_targetGrid.PointerReleased -= TargetGrid_PointerReleased;
_targetGrid.PointerReleased += TargetGrid_PointerReleased;
}
private async void XamlRoot_Changed(XamlRoot sender, XamlRootChangedEventArgs args)
{
UpdateRootGridSize(sender.Size.Width, sender.Size.Height);
await UpdateAppScreenshotAsync();
}
private void UnhookEvents()
{
Unloaded -= Eyedropper_Unloaded;
Window.Current.SizeChanged -= Window_SizeChanged;
DisplayInformation.GetForCurrentView().DpiChanged -= Eyedropper_DpiChanged;
if (XamlRoot != null)
{
XamlRoot.Changed -= XamlRoot_Changed;
}
else
{
Window.Current.SizeChanged -= Window_SizeChanged;
DisplayInformation.GetForCurrentView().DpiChanged -= Eyedropper_DpiChanged;
}
if (_targetGrid != null)
{
_targetGrid.PointerEntered -= TargetGrid_PointerEntered;
@ -177,16 +226,20 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
private async void TargetGrid_PointerReleased(object sender, PointerRoutedEventArgs e)
{
var pointer = e.Pointer;
if (pointer.PointerId == _pointerId)
var point = e.GetCurrentPoint(_rootGrid);
await InternalPointerReleasedAsync(e.Pointer.PointerId, point.Position);
}
internal async Task InternalPointerReleasedAsync(uint pointerId, Point position)
{
if (pointerId == _pointerId)
{
var point = e.GetCurrentPoint(_rootGrid);
if (_appScreenshot == null)
{
await UpdateAppScreenshotAsync();
}
UpdateEyedropper(point.Position);
UpdateEyedropper(position);
PickCompleted?.Invoke(this, EventArgs.Empty);
_pointerId = null;
if (!_taskSource.Task.IsCanceled)
@ -208,13 +261,18 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
private async void TargetGrid_PointerPressed(object sender, PointerRoutedEventArgs e)
{
_pointerId = e.Pointer.PointerId;
var point = e.GetCurrentPoint(_rootGrid);
await InternalPointerPressedAsync(e.Pointer.PointerId, point.Position, e.Pointer.PointerDeviceType);
}
internal async Task InternalPointerPressedAsync(uint pointerId, Point position, Windows.Devices.Input.PointerDeviceType pointerDeviceType)
{
_pointerId = pointerId;
PickStarted?.Invoke(this, EventArgs.Empty);
await UpdateAppScreenshotAsync();
UpdateEyedropper(point.Position);
UpdateEyedropper(position);
if (e.Pointer.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Touch)
if (pointerDeviceType == Windows.Devices.Input.PointerDeviceType.Touch)
{
VisualStateManager.GoToState(this, TouchState, false);
}
@ -244,11 +302,16 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
}
private void Window_SizeChanged(object sender, WindowSizeChangedEventArgs e)
{
UpdateRootGridSize(Window.Current.Bounds.Width, Window.Current.Bounds.Height);
}
private void UpdateRootGridSize(double width, double height)
{
if (_rootGrid != null)
{
_rootGrid.Width = Window.Current.Bounds.Width;
_rootGrid.Height = Window.Current.Bounds.Height;
_rootGrid.Width = width;
_rootGrid.Height = height;
}
}
}

Просмотреть файл

@ -78,7 +78,15 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
internal void SetScale(float zoomFactor)
{
_screenScale = DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel;
if (XamlRoot != null)
{
_screenScale = XamlRoot.RasterizationScale;
}
else
{
_screenScale = DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel;
}
var scale = _screenScale * zoomFactor;
_surfaceBrush.Scale = new Vector2((float)(1 / scale));
_surfaceBrush.BitmapInterpolationMode = CompositionBitmapInterpolationMode.NearestNeighbor;

Просмотреть файл

@ -9,4 +9,5 @@ using System.Runtime.CompilerServices;
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: InternalsVisibleTo("UnitTests")]
[assembly: InternalsVisibleTo("UnitTests.XamlIslands")]
[assembly: NeutralResourcesLanguage("en-US")]

Просмотреть файл

@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using Windows.ApplicationModel.Resources;
using Windows.UI;
namespace Microsoft.Toolkit.Uwp.Extensions
{
@ -17,17 +18,39 @@ namespace Microsoft.Toolkit.Uwp.Extensions
/// Retrieves the provided resource for the current view context.
/// </summary>
/// <param name="resourceKey">Resource key to retrieve.</param>
/// <param name="uiContext">UIContext to use </param>
/// <returns>string value for given resource or empty string if not found.</returns>
public static string GetViewLocalized(this string resourceKey)
=> ResourceLoader.GetForCurrentView().GetString(resourceKey);
public static string GetViewLocalized(this string resourceKey, UIContext uiContext = null)
{
if (uiContext != null)
{
var resourceLoader = ResourceLoader.GetForUIContext(uiContext);
return resourceLoader.GetString(resourceKey);
}
else
{
return ResourceLoader.GetForCurrentView().GetString(resourceKey);
}
}
/// <summary>
/// Retrieves the provided resource for the given key for use independent of the UI thread.
/// </summary>
/// <param name="resourceKey">Resource key to retrieve.</param>
/// <param name="uiContext">UIContext to use </param>
/// <returns>string value for given resource or empty string if not found.</returns>
public static string GetLocalized(this string resourceKey)
=> IndependentLoader.GetString(resourceKey);
public static string GetLocalized(this string resourceKey, UIContext uiContext = null)
{
if (uiContext != null)
{
var resourceLoader = ResourceLoader.GetForUIContext(uiContext);
return resourceLoader.GetString(resourceKey);
}
else
{
return IndependentLoader.GetString(resourceKey);
}
}
/// <summary>
/// Retrieves the provided resource for the given key for use independent of the UI thread.

Просмотреть файл

@ -31,9 +31,6 @@ namespace Microsoft.Toolkit.Uwp.Helpers
/* Run the function directly when we have thread access.
* Also reuse Task.CompletedTask in case of success,
* to skip an unnecessary heap allocation for every invocation. */
// Ignoring for now, but need to map the CurrentThreadID for all dispatcher queue code we have
/*
if (dispatcher.HasThreadAccess)
{
try
@ -47,7 +44,6 @@ namespace Microsoft.Toolkit.Uwp.Helpers
return Task.FromException(e);
}
}
*/
var taskCompletionSource = new TaskCompletionSource<object>();
@ -84,9 +80,6 @@ namespace Microsoft.Toolkit.Uwp.Helpers
throw new ArgumentNullException(nameof(function));
}
// Skip the dispatch, if posssible
// Ignoring for now, but need to map the CurrentThreadID for all dispatcher queue code we have
/*
if (dispatcher.HasThreadAccess)
{
try
@ -98,7 +91,6 @@ namespace Microsoft.Toolkit.Uwp.Helpers
return Task.FromException<T>(e);
}
}
*/
var taskCompletionSource = new TaskCompletionSource<T>();
@ -136,9 +128,6 @@ namespace Microsoft.Toolkit.Uwp.Helpers
* We don't use ConfigureAwait(false) in this case, in order
* to let the caller continue its execution on the same thread
* after awaiting the task returned by this function. */
// Ignoring for now, but need to map the CurrentThreadID for all dispatcher queue code we have
/*
if (dispatcher.HasThreadAccess)
{
try
@ -155,7 +144,6 @@ namespace Microsoft.Toolkit.Uwp.Helpers
return Task.FromException(e);
}
}
*/
var taskCompletionSource = new TaskCompletionSource<object>();
@ -199,9 +187,6 @@ namespace Microsoft.Toolkit.Uwp.Helpers
throw new ArgumentNullException(nameof(function));
}
// Skip the dispatch, if posssible
// Ignoring for now, but need to map the CurrentThreadID for all dispatcher queue code we have
/*
if (dispatcher.HasThreadAccess)
{
try
@ -218,7 +203,6 @@ namespace Microsoft.Toolkit.Uwp.Helpers
return Task.FromException<T>(e);
}
}
*/
var taskCompletionSource = new TaskCompletionSource<T>();

Просмотреть файл

@ -4,6 +4,7 @@
using System;
using Windows.Graphics.Display;
using Windows.UI.Xaml;
namespace Microsoft.Toolkit.Uwp.Helpers
{
@ -22,8 +23,9 @@ namespace Microsoft.Toolkit.Uwp.Helpers
/// <param name="from">Start unit</param>
/// <param name="to">End unit</param>
/// <param name="value">The value to convert (using start unit)</param>
/// <param name="xamlRoot">The XamlRoot that will be used to get the screen scale. Required on Xaml Islands.</param>
/// <returns>The result of the conversion</returns>
public static float Convert(ScreenUnit from, ScreenUnit to, float value)
public static float Convert(ScreenUnit from, ScreenUnit to, float value, XamlRoot xamlRoot = null)
{
if (from == to)
{
@ -45,7 +47,7 @@ namespace Microsoft.Toolkit.Uwp.Helpers
if (to == ScreenUnit.EffectivePixel)
{
return value / (float)DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel;
return value / GetScale(xamlRoot);
}
throw new ArgumentOutOfRangeException(nameof(to));
@ -79,7 +81,7 @@ namespace Microsoft.Toolkit.Uwp.Helpers
case ScreenUnit.EffectivePixel:
if (to == ScreenUnit.Pixel)
{
return value * (float)DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel;
return value * GetScale(xamlRoot);
}
throw new ArgumentOutOfRangeException(nameof(to));
@ -88,5 +90,17 @@ namespace Microsoft.Toolkit.Uwp.Helpers
throw new ArgumentOutOfRangeException(nameof(from));
}
}
private static float GetScale(XamlRoot xamlRoot)
{
if (xamlRoot != null)
{
return (float)xamlRoot.RasterizationScale;
}
else
{
return (float)DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel;
}
}
}
}

Просмотреть файл

@ -12,6 +12,7 @@ using Windows.Security.ExchangeActiveSyncProvisioning;
using Windows.System;
using Windows.System.Profile;
using Windows.System.UserProfile;
using Windows.UI.Xaml;
namespace Microsoft.Toolkit.Uwp.Helpers
{
@ -180,7 +181,8 @@ namespace Microsoft.Toolkit.Uwp.Helpers
/// Tracks information about the app's launch.
/// </summary>
/// <param name="args">Details about the launch request and process.</param>
public void TrackAppUse(LaunchActivatedEventArgs args)
/// <param name="xamlRoot">The XamlRoot object from your visual tree.</param>
public void TrackAppUse(IActivatedEventArgs args, XamlRoot xamlRoot = null)
{
if (args.PreviousExecutionState == ApplicationExecutionState.ClosedByUser
|| args.PreviousExecutionState == ApplicationExecutionState.NotRunning)
@ -213,24 +215,42 @@ namespace Microsoft.Toolkit.Uwp.Helpers
: DateTime.MinValue;
}
void App_VisibilityChanged(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.VisibilityChangedEventArgs e)
if (xamlRoot != null)
{
if (e.Visible)
void XamlRoot_Changed(XamlRoot sender, XamlRootChangedEventArgs e)
{
_sessionStart = DateTime.UtcNow;
UpdateVisibility(sender.IsHostVisible);
}
else
{
var subsessionLength = DateTime.UtcNow.Subtract(_sessionStart).Ticks;
var uptimeSoFar = _localObjectStorageHelper.Read<long>(nameof(AppUptime));
_localObjectStorageHelper.Save(nameof(AppUptime), uptimeSoFar + subsessionLength);
}
xamlRoot.Changed -= XamlRoot_Changed;
xamlRoot.Changed += XamlRoot_Changed;
}
else
{
void App_VisibilityChanged(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.VisibilityChangedEventArgs e)
{
UpdateVisibility(e.Visible);
}
Windows.UI.Core.CoreWindow.GetForCurrentThread().VisibilityChanged -= App_VisibilityChanged;
Windows.UI.Core.CoreWindow.GetForCurrentThread().VisibilityChanged += App_VisibilityChanged;
Windows.UI.Core.CoreWindow.GetForCurrentThread().VisibilityChanged -= App_VisibilityChanged;
Windows.UI.Core.CoreWindow.GetForCurrentThread().VisibilityChanged += App_VisibilityChanged;
}
}
private void UpdateVisibility(bool visible)
{
if (visible)
{
_sessionStart = DateTime.UtcNow;
}
else
{
var subsessionLength = DateTime.UtcNow.Subtract(_sessionStart).Ticks;
var uptimeSoFar = _localObjectStorageHelper.Read<long>(nameof(AppUptime));
_localObjectStorageHelper.Save(nameof(AppUptime), uptimeSoFar + subsessionLength);
}
}
/// <summary>

Просмотреть файл

@ -13,6 +13,7 @@ using Microsoft.Toolkit.Uwp.Helpers;
namespace UnitTests.Helpers
{
#pragma warning disable CS0612 // Type or member is obsolete
[TestClass]
public class Test_DispatcherHelper
{
@ -30,9 +31,9 @@ namespace UnitTests.Helpers
{
DispatcherHelper.ExecuteOnUIThreadAsync(() =>
{
var textBlock = new TextBlock { Text = nameof(Test_DispatcherHelper_Action_Ok_NonUIThread) };
var textBlock = new TextBlock { Text = nameof(Test_DispatcherHelper_Action_Ok_UIThread) };
Assert.AreEqual(textBlock.Text, nameof(Test_DispatcherHelper_Action_Ok_NonUIThread));
Assert.AreEqual(textBlock.Text, nameof(Test_DispatcherHelper_Action_Ok_UIThread));
}).Wait();
}
@ -77,10 +78,10 @@ namespace UnitTests.Helpers
{
var textBlock = DispatcherHelper.ExecuteOnUIThreadAsync(() =>
{
return new TextBlock { Text = nameof(Test_DispatcherHelper_FuncOfT_Ok_NonUIThread) };
return new TextBlock { Text = nameof(Test_DispatcherHelper_FuncOfT_Ok_UIThread) };
}).Result;
Assert.AreEqual(textBlock.Text, nameof(Test_DispatcherHelper_FuncOfT_Ok_NonUIThread));
Assert.AreEqual(textBlock.Text, nameof(Test_DispatcherHelper_FuncOfT_Ok_UIThread));
}
[TestCategory("Helpers")]
@ -128,9 +129,9 @@ namespace UnitTests.Helpers
{
DispatcherHelper.ExecuteOnUIThreadAsync(() =>
{
var textBlock = new TextBlock { Text = nameof(Test_DispatcherHelper_FuncOfTask_Ok_NonUIThread) };
var textBlock = new TextBlock { Text = nameof(Test_DispatcherHelper_FuncOfTask_Ok_UIThread) };
Assert.AreEqual(textBlock.Text, nameof(Test_DispatcherHelper_FuncOfTask_Ok_NonUIThread));
Assert.AreEqual(textBlock.Text, nameof(Test_DispatcherHelper_FuncOfTask_Ok_UIThread));
return Task.CompletedTask;
}).Wait();
@ -179,9 +180,9 @@ namespace UnitTests.Helpers
{
DispatcherHelper.ExecuteOnUIThreadAsync(() =>
{
var textBlock = new TextBlock { Text = nameof(Test_DispatcherHelper_FuncOfTaskOfT_Ok_NonUIThread) };
var textBlock = new TextBlock { Text = nameof(Test_DispatcherHelper_FuncOfTaskOfT_Ok_UIThread) };
Assert.AreEqual(textBlock.Text, nameof(Test_DispatcherHelper_FuncOfTaskOfT_Ok_NonUIThread));
Assert.AreEqual(textBlock.Text, nameof(Test_DispatcherHelper_FuncOfTaskOfT_Ok_UIThread));
return Task.FromResult(1);
}).Wait();
@ -218,4 +219,5 @@ namespace UnitTests.Helpers
Assert.IsInstanceOfType(task.Exception.InnerExceptions.FirstOrDefault(), typeof(ArgumentException));
}
}
#pragma warning restore CS0612 // Type or member is obsolete
}

Просмотреть файл

@ -0,0 +1,292 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics.CodeAnalysis;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer;
using System.Linq;
using System.Threading.Tasks;
using Windows.UI.Xaml.Controls;
using Microsoft.Toolkit.Uwp.Helpers;
using Windows.ApplicationModel.Core;
using Windows.UI.Core;
using Windows.System;
namespace UnitTests.Helpers
{
[TestClass]
public class Test_DispatcherQueueHelper
{
private const int TIME_OUT = 5000;
[TestCategory("Helpers")]
[UITestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void Test_DispatcherQueueHelper_Action_Null()
{
DispatcherQueueHelper.ExecuteOnUIThreadAsync(DispatcherQueue.GetForCurrentThread(), default(Action));
}
[TestCategory("Helpers")]
[UITestMethod]
public void Test_DispatcherQueueHelper_Action_Ok_UIThread()
{
DispatcherQueueHelper.ExecuteOnUIThreadAsync(DispatcherQueue.GetForCurrentThread(), () =>
{
var textBlock = new TextBlock { Text = nameof(Test_DispatcherQueueHelper_Action_Ok_UIThread) };
Assert.AreEqual(textBlock.Text, nameof(Test_DispatcherQueueHelper_Action_Ok_UIThread));
}).Wait();
}
[TestCategory("Helpers")]
[TestMethod]
public async Task Test_DispatcherQueueHelper_Action_Ok_NonUIThread()
{
var taskSource = new TaskCompletionSource<object>();
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
CoreDispatcherPriority.Normal, async () =>
{
try
{
var dispatcherQueue = DispatcherQueue.GetForCurrentThread();
await Task.Run(async () =>
{
await DispatcherQueueHelper.ExecuteOnUIThreadAsync(dispatcherQueue, () =>
{
var textBlock = new TextBlock { Text = nameof(Test_DispatcherQueueHelper_Action_Ok_NonUIThread) };
Assert.AreEqual(textBlock.Text, nameof(Test_DispatcherQueueHelper_Action_Ok_NonUIThread));
taskSource.SetResult(null);
});
});
}
catch (Exception e)
{
taskSource.SetException(e);
}
});
await taskSource.Task;
}
[TestCategory("Helpers")]
[UITestMethod]
public void Test_DispatcherQueueHelper_Action_Exception()
{
var task = DispatcherQueueHelper.ExecuteOnUIThreadAsync(DispatcherQueue.GetForCurrentThread(), () =>
{
throw new ArgumentException(nameof(this.Test_DispatcherQueueHelper_Action_Exception));
});
Assert.IsNotNull(task);
Assert.AreEqual(task.Status, TaskStatus.Faulted);
Assert.IsNotNull(task.Exception);
Assert.IsInstanceOfType(task.Exception.InnerExceptions.FirstOrDefault(), typeof(ArgumentException));
}
[TestCategory("Helpers")]
[UITestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void Test_DispatcherQueueHelper_FuncOfT_Null()
{
DispatcherQueueHelper.ExecuteOnUIThreadAsync(DispatcherQueue.GetForCurrentThread(), default(Func<int>));
}
[TestCategory("Helpers")]
[UITestMethod]
public void Test_DispatcherQueueHelper_FuncOfT_Ok_UIThread()
{
var textBlock = DispatcherQueueHelper.ExecuteOnUIThreadAsync(DispatcherQueue.GetForCurrentThread(), () =>
{
return new TextBlock { Text = nameof(Test_DispatcherQueueHelper_FuncOfT_Ok_UIThread) };
}).Result;
Assert.AreEqual(textBlock.Text, nameof(Test_DispatcherQueueHelper_FuncOfT_Ok_UIThread));
}
[TestCategory("Helpers")]
[TestMethod]
public async Task Test_DispatcherQueueHelper_FuncOfT_Ok_NonUIThread()
{
var taskSource = new TaskCompletionSource<object>();
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
CoreDispatcherPriority.Normal, async () =>
{
try
{
var dispatcherQueue = DispatcherQueue.GetForCurrentThread();
await Task.Run(async () =>
{
var textBlock = await DispatcherQueueHelper.ExecuteOnUIThreadAsync(dispatcherQueue, () =>
{
return new TextBlock { Text = nameof(Test_DispatcherQueueHelper_FuncOfT_Ok_NonUIThread) };
});
await DispatcherQueueHelper.ExecuteOnUIThreadAsync(dispatcherQueue, () =>
{
Assert.AreEqual(textBlock.Text, nameof(Test_DispatcherQueueHelper_FuncOfT_Ok_NonUIThread));
taskSource.SetResult(null);
});
});
}
catch (Exception e)
{
taskSource.SetException(e);
}
});
await taskSource.Task;
}
[TestCategory("Helpers")]
[UITestMethod]
public void Test_DispatcherQueueHelper_FuncOfT_Exception()
{
var task = DispatcherQueueHelper.ExecuteOnUIThreadAsync(DispatcherQueue.GetForCurrentThread(), new Func<int>(() =>
{
throw new ArgumentException(nameof(this.Test_DispatcherQueueHelper_FuncOfT_Exception));
}));
Assert.IsNotNull(task);
Assert.AreEqual(task.Status, TaskStatus.Faulted);
Assert.IsNotNull(task.Exception);
Assert.IsInstanceOfType(task.Exception.InnerExceptions.FirstOrDefault(), typeof(ArgumentException));
}
[TestCategory("Helpers")]
[UITestMethod]
[ExpectedException(typeof(ArgumentNullException))]
[SuppressMessage("Style", "IDE0034", Justification = "Explicit overload for clarity")]
public void Test_DispatcherQueueHelper_FuncOfTask_Null()
{
DispatcherQueueHelper.ExecuteOnUIThreadAsync(DispatcherQueue.GetForCurrentThread(), default(Func<Task>));
}
[TestCategory("Helpers")]
[UITestMethod]
public void Test_DispatcherQueueHelper_FuncOfTask_Ok_UIThread()
{
DispatcherQueueHelper.ExecuteOnUIThreadAsync(DispatcherQueue.GetForCurrentThread(), () =>
{
var textBlock = new TextBlock { Text = nameof(Test_DispatcherQueueHelper_FuncOfTask_Ok_UIThread) };
Assert.AreEqual(textBlock.Text, nameof(Test_DispatcherQueueHelper_FuncOfTask_Ok_UIThread));
return Task.CompletedTask;
}).Wait();
}
[TestCategory("Helpers")]
[TestMethod]
public async Task Test_DispatcherQueueHelper_FuncOfTask_Ok_NonUIThread()
{
var taskSource = new TaskCompletionSource<object>();
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
CoreDispatcherPriority.Normal, async () =>
{
try
{
await DispatcherQueueHelper.ExecuteOnUIThreadAsync(DispatcherQueue.GetForCurrentThread(), async () =>
{
await Task.Yield();
var textBlock = new TextBlock { Text = nameof(Test_DispatcherQueueHelper_FuncOfTask_Ok_NonUIThread) };
Assert.AreEqual(textBlock.Text, nameof(Test_DispatcherQueueHelper_FuncOfTask_Ok_NonUIThread));
taskSource.SetResult(null);
});
}
catch (Exception e)
{
taskSource.SetException(e);
}
});
await taskSource.Task;
}
[TestCategory("Helpers")]
[UITestMethod]
public void Test_DispatcherQueueHelper_FuncOfTask_Exception()
{
var task = DispatcherQueueHelper.ExecuteOnUIThreadAsync(DispatcherQueue.GetForCurrentThread(), new Func<Task>(() =>
{
throw new ArgumentException(nameof(this.Test_DispatcherQueueHelper_FuncOfTask_Exception));
}));
Assert.IsNotNull(task);
Assert.AreEqual(task.Status, TaskStatus.Faulted);
Assert.IsNotNull(task.Exception);
Assert.IsInstanceOfType(task.Exception.InnerExceptions.FirstOrDefault(), typeof(ArgumentException));
}
[TestCategory("Helpers")]
[UITestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void Test_DispatcherQueueHelper_FuncOfTaskOfT_Null()
{
DispatcherQueueHelper.ExecuteOnUIThreadAsync(DispatcherQueue.GetForCurrentThread(), default(Func<Task<int>>));
}
[TestCategory("Helpers")]
[UITestMethod]
public void Test_DispatcherQueueHelper_FuncOfTaskOfT_Ok_UIThread()
{
DispatcherQueueHelper.ExecuteOnUIThreadAsync(DispatcherQueue.GetForCurrentThread(), () =>
{
var textBlock = new TextBlock { Text = nameof(Test_DispatcherQueueHelper_FuncOfTaskOfT_Ok_UIThread) };
Assert.AreEqual(textBlock.Text, nameof(Test_DispatcherQueueHelper_FuncOfTaskOfT_Ok_UIThread));
return Task.FromResult(1);
}).Wait();
}
[TestCategory("Helpers")]
[TestMethod]
public async Task Test_DispatcherQueueHelper_FuncOfTaskOfT_Ok_NonUIThread()
{
var taskSource = new TaskCompletionSource<object>();
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
CoreDispatcherPriority.Normal, async () =>
{
try
{
await DispatcherQueueHelper.ExecuteOnUIThreadAsync(DispatcherQueue.GetForCurrentThread(), async () =>
{
await Task.Yield();
var textBlock = new TextBlock { Text = nameof(Test_DispatcherQueueHelper_FuncOfTaskOfT_Ok_NonUIThread) };
Assert.AreEqual(textBlock.Text, nameof(Test_DispatcherQueueHelper_FuncOfTaskOfT_Ok_NonUIThread));
taskSource.SetResult(null);
return textBlock;
});
}
catch (Exception e)
{
taskSource.SetException(e);
}
});
await taskSource.Task;
}
[TestCategory("Helpers")]
[UITestMethod]
public void Test_DispatcherQueueHelper_FuncOfTaskOfT_Exception()
{
var task = DispatcherQueueHelper.ExecuteOnUIThreadAsync(DispatcherQueue.GetForCurrentThread(), new Func<Task<int>>(() =>
{
throw new ArgumentException(nameof(this.Test_DispatcherQueueHelper_FuncOfTaskOfT_Exception));
}));
Assert.IsNotNull(task);
Assert.AreEqual(task.Status, TaskStatus.Faulted);
Assert.IsNotNull(task.Exception);
Assert.IsInstanceOfType(task.Exception.InnerExceptions.FirstOrDefault(), typeof(ArgumentException));
}
}
}

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.4 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 7.5 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.9 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.6 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.2 KiB

Двоичные данные
UnitTests/UnitTests.XamlIslands.Package/Images/StoreLogo.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.4 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.1 KiB

Просмотреть файл

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap rescap">
<Identity
Name="e9b2d6ff-2c1a-456b-9ebb-813a54796bc9"
Publisher="CN=alzollin"
Version="1.0.0.0" />
<Properties>
<DisplayName>UnitTests.XamlIslands.Package</DisplayName>
<PublisherDisplayName>alzollin</PublisherDisplayName>
<Logo>Images\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.14393.0" MaxVersionTested="10.0.14393.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate"/>
</Resources>
<Applications>
<Application Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="$targetentrypoint$">
<uap:VisualElements
DisplayName="UnitTests.XamlIslands.Package"
Description="UnitTests.XamlIslands.Package"
BackgroundColor="transparent"
Square150x150Logo="Images\Square150x150Logo.png"
Square44x44Logo="Images\Square44x44Logo.png">
<uap:DefaultTile Wide310x150Logo="Images\Wide310x150Logo.png" />
<uap:SplashScreen Image="Images\SplashScreen.png" />
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
<rescap:Capability Name="runFullTrust" />
</Capabilities>
</Package>

Просмотреть файл

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="abc" xml:space="preserve">
<value>ABCDEF</value>
</data>
</root>

Просмотреть файл

@ -0,0 +1,99 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '15.0'">
<VisualStudioVersion>15.0</VisualStudioVersion>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x86">
<Configuration>Debug</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x86">
<Configuration>Release</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|AnyCPU">
<Configuration>Debug</Configuration>
<Platform>AnyCPU</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|AnyCPU">
<Configuration>Release</Configuration>
<Platform>AnyCPU</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup>
<WapProjPath Condition="'$(WapProjPath)'==''">$(MSBuildExtensionsPath)\Microsoft\DesktopBridge\</WapProjPath>
</PropertyGroup>
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.props" />
<PropertyGroup>
<ProjectGuid>dcfbf9f1-2bbe-498d-b6c9-8ade50c06cdc</ProjectGuid>
<TargetPlatformVersion>10.0.18362.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.18362.0</TargetPlatformMinVersion>
<DefaultLanguage>en-US</DefaultLanguage>
<AppxPackageSigningEnabled>false</AppxPackageSigningEnabled>
<EntryPointProjectUniqueName>..\UnitTests.XamlIslands\UnitTests.XamlIslands.csproj</EntryPointProjectUniqueName>
</PropertyGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
<SubType>Designer</SubType>
</AppxManifest>
</ItemGroup>
<ItemGroup>
<Content Include="Images\SplashScreen.scale-200.png" />
<Content Include="Images\LockScreenLogo.scale-200.png" />
<Content Include="Images\Square150x150Logo.scale-200.png" />
<Content Include="Images\Square44x44Logo.scale-200.png" />
<Content Include="Images\Square44x44Logo.targetsize-24_altform-unplated.png" />
<Content Include="Images\StoreLogo.png" />
<Content Include="Images\Wide310x150Logo.scale-200.png" />
<PRIResource Include="Strings\en-us\Resources.resw" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\UnitTests.XamlIslands\UnitTests.XamlIslands.csproj">
<SkipGetTargetFrameworkProperties>True</SkipGetTargetFrameworkProperties>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<SDKReference Include="Microsoft.VCLibs,Version=14.0">
<TargetedSDKConfiguration Condition="'$(Configuration)'!='Debug'">Retail</TargetedSDKConfiguration>
<TargetedSDKConfiguration Condition="'$(Configuration)'=='Debug'">Debug</TargetedSDKConfiguration>
<TargetedSDKArchitecture>$(PlatformShortName)</TargetedSDKArchitecture>
<Implicit>true</Implicit>
</SDKReference>
</ItemGroup>
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.targets" />
<Target Name="_StompSourceProjectForWapProject" BeforeTargets="_ConvertItems">
<ItemGroup>
<_TemporaryFilteredWapProjOutput Include="@(_FilteredNonWapProjProjectOutput)" />
<_FilteredNonWapProjProjectOutput Remove="@(_TemporaryFilteredWapProjOutput)" />
<_FilteredNonWapProjProjectOutput Include="@(_TemporaryFilteredWapProjOutput)">
<SourceProject>
</SourceProject>
</_FilteredNonWapProjProjectOutput>
</ItemGroup>
</Target>
</Project>

Просмотреть файл

@ -3,45 +3,85 @@
// See the LICENSE file in the project root for more information.
using System;
using Windows.UI.Xaml.Hosting;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.Toolkit.Win32.UI.XamlHost;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using System.Reflection;
using Windows.System;
using System.Diagnostics;
using System.Windows.Forms;
using Microsoft.Toolkit.Forms.UI.XamlHost;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI;
namespace UnitTests.XamlIslands
{
class Program
{
private static IXamlMetadataContainer _metadataContainer;
internal static DispatcherQueue _dispatcher;
internal static DispatcherQueue Dispatcher;
internal static MainForm MainFormInstance;
[STAThread]
public static void Main()
{
_metadataContainer = XamlApplicationExtensions.GetOrCreateXamlMetadataContainer();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
MainFormInstance = new MainForm();
Application.Run(MainFormInstance);
using (var xamlSource = new DesktopWindowXamlSource())
WriteLineColor("Press any key to close this window . . .");
Console.Read();
}
public class MainForm : Form
{
public WindowsXamlHost xamlHost = new WindowsXamlHost();
public MainForm()
{
var frame = UWPTypeFactory.CreateXamlContentByType("Windows.UI.Xaml.Controls.Frame");
xamlSource.Content = frame;
SuspendLayout();
xamlHost.AutoSizeMode = AutoSizeMode.GrowOnly;
xamlHost.Location = new System.Drawing.Point(0, 0);
xamlHost.Name = "xamlHost";
xamlHost.Size = new System.Drawing.Size(800, 800);
xamlHost.TabIndex = 0;
xamlHost.Text = "xamlHost";
xamlHost.Dock = DockStyle.Fill;
xamlHost.ChildChanged += XamlHost_ChildChanged;
xamlHost.InitialTypeName = "Windows.UI.Xaml.Controls.Frame";
//
// Form1
//
AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new System.Drawing.Size(800, 600);
Controls.Add(xamlHost);
Name = "MainForm";
Text = "Xaml Islands";
ResumeLayout(false);
}
_dispatcher = DispatcherQueue.GetForCurrentThread();
private async void XamlHost_ChildChanged(object sender, EventArgs e)
{
(xamlHost.Child as Frame).Background = new SolidColorBrush(Colors.CornflowerBlue);
_dispatcher.TryEnqueue(DispatcherQueuePriority.Normal, async () =>
Dispatcher = DispatcherQueue.GetForCurrentThread();
await Task.Delay(1000);
_ = Task.Run(async () =>
//_dispatcher.TryEnqueue(DispatcherQueuePriority.Normal, async () =>
{
TestResult testResult = default;
Stopwatch sw = new Stopwatch();
ConsoleWriteLineColor("--- Starting Tests Execution ---");
WriteLineColor("--- Starting Tests Execution ---");
sw.Start();
foreach (var testClass in typeof(XamlIslandsTest_ThemeListener_Threading).Assembly.GetTypes())
foreach (var testClass in typeof(XamlIslandsTest_SystemInformation).Assembly.GetTypes())
{
Attribute[] attributes = Attribute.GetCustomAttributes(testClass);
@ -60,16 +100,11 @@ namespace UnitTests.XamlIslands
var color = testResult.Failed == 0 ? ConsoleColor.Green : ConsoleColor.Red;
ConsoleWriteLineColor($"--- Finished Tests Execution ({testResult.Passed}/{testResult.Count}) ---", color);
ConsoleWriteLineColor($"--- Duration - {sw.Elapsed} ---");
WriteLineColor($"--- Finished Tests Execution ({testResult.Passed}/{testResult.Count}) ---", color);
WriteLineColor($"--- Duration - {sw.Elapsed} ---");
Window.Current.CoreWindow.Close();
System.Windows.Application.Current.Shutdown();
Application.Exit();
});
// This is just to have a Win32 message loop so the dispatcher processes it's events. This is not WPF or WinForms specific.
var app = new System.Windows.Application();
app.Run();
}
}
@ -89,8 +124,11 @@ namespace UnitTests.XamlIslands
if (attribute is STATestMethodAttribute || attribute is TestMethodAttribute)
{
count++;
var top = Console.CursorTop;
try
{
WriteLineColor($"{type.FullName}.{method.Name}\t - \t Running...");
var instance = Activator.CreateInstance(type);
if (initMethod != null)
@ -116,13 +154,14 @@ namespace UnitTests.XamlIslands
await taskCleanup;
}
}
TestPass(type, method);
Console.SetCursorPosition(0, top);
WriteLineColor($"{type.FullName}.{method.Name}\t - \t PASS ", ConsoleColor.Green);
passed++;
}
catch (Exception ex)
{
TestFail(type, method, ex);
Console.SetCursorPosition(0, top);
WriteLineColor($"{type.FullName}.{method.Name}\t - \t FAIL :{Environment.NewLine}{ex}", ConsoleColor.Red);
}
break;
}
@ -146,20 +185,11 @@ namespace UnitTests.XamlIslands
public static TestResult operator +(TestResult a, TestResult b) => new TestResult(a.Count + b.Count, a.Passed + b.Passed);
}
private static void TestPass(Type type, MethodInfo method)
{
ConsoleWriteLineColor($"{type.FullName}.{method.Name}\t - \tPASS", ConsoleColor.Green);
}
private static void TestFail(Type type, MethodInfo method, Exception ex)
{
ConsoleWriteLineColor($"{type.FullName}.{method.Name}\t - \tFAIL:{Environment.NewLine}{ex}", ConsoleColor.Red);
}
private static void ConsoleWriteLineColor(string message, ConsoleColor color = ConsoleColor.White)
private static void WriteLineColor(string message, ConsoleColor color = ConsoleColor.White)
{
Console.ForegroundColor = color;
Console.WriteLine(message);
Debug.WriteLine(message);
Console.ResetColor();
}

Просмотреть файл

@ -1,31 +1,51 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<Platforms>x86</Platforms>
<IsPackable>false</IsPackable>
<OutputType>Exe</OutputType>
<UseWpf>true</UseWpf>
<RuntimeIdentifiers>win-x86</RuntimeIdentifiers>
<OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<Platforms>x64;x86</Platforms>
<!--<IsPackable>false</IsPackable>-->
<RuntimeIdentifiers>win-x64;win-x86</RuntimeIdentifiers>
<UseWindowsForms>true</UseWindowsForms>
<AssetTargetFallback>uap10.0.18362</AssetTargetFallback>
<ApplicationManifest>app.manifest</ApplicationManifest>
<StartupObject>UnitTests.XamlIslands.Program</StartupObject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ColorCode.Core" Version="2.0.6" />
<PackageReference Include="ColorCode.UWP" Version="2.0.6" />
<PackageReference Include="Microsoft.Windows.SDK.Contracts" Version="10.0.18362.2005" />
<PackageReference Include="Microsoft.Toolkit.UI.XamlHost" Version="6.0.0" />
<PackageReference Include="Microsoft.VCRTForwarders.140" Version="1.0.5" />
<PackageReference Include="Microsoft.Toolkit.Forms.UI.XamlHost" Version="6.0.0" />
<!--<PackageReference Include="Microsoft.VCRTForwarders.140" Version="1.0.5" />-->
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.1.0" />
<PackageReference Include="MSTest.TestFramework" Version="2.1.0" />
<PackageReference Include="Win2D.uwp" Version="1.24.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Microsoft.Toolkit.Uwp.UI.Controls\Microsoft.Toolkit.Uwp.UI.Controls.csproj" />
<ProjectReference Include="..\..\Microsoft.Toolkit.Uwp.UI\Microsoft.Toolkit.Uwp.UI.csproj" />
<ProjectReference Include="..\..\Microsoft.Toolkit.Uwp\Microsoft.Toolkit.Uwp.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,44 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.Toolkit.Uwp.Helpers;
using Microsoft.Toolkit.Uwp.UI.Controls;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Threading.Tasks;
using Windows.Devices.Input;
using Windows.Foundation;
using Windows.UI;
namespace UnitTests.XamlIslands
{
[STATestClass]
public partial class XamlIslandsTest_Eyedropper
{
[TestMethod]
public async Task Eyedropper_DoesntCrash()
{
Eyedropper eyedropper = null;
Color? color = null;
_ = Program.Dispatcher.ExecuteOnUIThreadAsync(async () =>
{
var xamlRoot = Program.MainFormInstance.xamlHost.Child.XamlRoot;
eyedropper = new Eyedropper(xamlRoot);
color = await eyedropper.Open();
});
await Program.Dispatcher.ExecuteOnUIThreadAsync(async () =>
{
var pos = new Point(100, 100);
await eyedropper.InternalPointerPressedAsync(1, pos, PointerDeviceType.Mouse);
await Task.Delay(5000);
await eyedropper.InternalPointerReleasedAsync(1, pos);
await Task.Delay(1000);
Assert.AreEqual(Colors.CornflowerBlue, color);
});
}
}
}

Просмотреть файл

@ -0,0 +1,18 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace UnitTests.XamlIslands
{
[STATestClass]
public partial class XamlIslandsTest_ObjectStorageHelper
{
[TestMethod]
public void LocalObjectStorageHelper_Writes()
{
}
}
}

Просмотреть файл

@ -0,0 +1,44 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.Toolkit.Uwp.Extensions;
using Microsoft.Toolkit.Uwp.Helpers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Threading.Tasks;
namespace UnitTests.XamlIslands
{
[STATestClass]
public partial class XamlIslandsTest_StringExtensions
{
[TestMethod]
public async Task StringExtensions_GetViewLocalized()
{
await Program.Dispatcher.ExecuteOnUIThreadAsync(() =>
{
var xamlRoot = Program.MainFormInstance.xamlHost.Child.XamlRoot;
var str = StringExtensions.GetViewLocalized("abc", xamlRoot.UIContext);
Assert.AreEqual("ABCDEF", str);
});
}
[TestMethod]
public async Task StringExtensions_GetLocalized()
{
await Program.Dispatcher.ExecuteOnUIThreadAsync(() =>
{
var xamlRoot = Program.MainFormInstance.xamlHost.Child.XamlRoot;
var str = StringExtensions.GetLocalized("abc", xamlRoot.UIContext);
Assert.AreEqual("ABCDEF", str);
});
}
[TestMethod]
public void StringExtensions_GetLocalizedWithResourcePath()
{
var str = StringExtensions.GetLocalized("TextToolbarStrings_OkLabel", "Microsoft.Toolkit.Uwp.UI.Controls/Resources");
Assert.AreEqual("Ok", str);
}
}
}

Просмотреть файл

@ -0,0 +1,38 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.Toolkit.Uwp.Helpers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Threading.Tasks;
using Windows.ApplicationModel.Activation;
namespace UnitTests.XamlIslands
{
[STATestClass]
public partial class XamlIslandsTest_SystemInformation
{
[TestMethod]
public async Task SystemInformationTrackAppUse()
{
await Program.Dispatcher.ExecuteOnUIThreadAsync(() =>
{
var e = new FakeArgs
{
PreviousExecutionState = ApplicationExecutionState.NotRunning
};
var xamlRoot = Program.MainFormInstance.xamlHost.Child.XamlRoot;
SystemInformation.Instance.TrackAppUse(e, xamlRoot);
});
}
class FakeArgs : IActivatedEventArgs
{
public ActivationKind Kind { get; set; }
public ApplicationExecutionState PreviousExecutionState { get; set; }
public SplashScreen SplashScreen { get; set; }
}
}
}

Просмотреть файл

@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Threading.Tasks;
using Microsoft.Toolkit.Uwp.Helpers;
using Microsoft.Toolkit.Uwp.UI.Helpers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Windows.UI.Xaml;
@ -16,25 +17,28 @@ namespace UnitTests.XamlIslands
private ThemeListener _themeListener = null;
[TestInitialize]
public void Init()
public Task Init()
{
Application.Current.RequestedTheme = ApplicationTheme.Light;
_taskCompletionSource = new TaskCompletionSource<object>();
_themeListener = new ThemeListener();
_themeListener.ThemeChanged += (s) =>
return Program.Dispatcher.ExecuteOnUIThreadAsync(() =>
{
_taskCompletionSource.TrySetResult(null);
};
Application.Current.RequestedTheme = ApplicationTheme.Light;
Application.Current.RequestedTheme = ApplicationTheme.Dark;
_taskCompletionSource = new TaskCompletionSource<object>();
_themeListener = new ThemeListener();
_themeListener.ThemeChanged += (s) =>
{
_taskCompletionSource.TrySetResult(null);
};
Application.Current.RequestedTheme = ApplicationTheme.Dark;
});
}
[TestMethod]
public async Task ThemeListenerDispatcherTestAsync()
{
_ = _themeListener.OnColorValuesChanged();
await _themeListener.OnColorValuesChanged();
await _taskCompletionSource.Task;
}
@ -44,10 +48,9 @@ namespace UnitTests.XamlIslands
{
await Task.Run(async () =>
{
_ = _themeListener.OnColorValuesChanged();
await _taskCompletionSource.Task;
await _themeListener.OnColorValuesChanged();
});
await _taskCompletionSource.Task;
}
}
}

Просмотреть файл

@ -1,6 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<asmv3:file name="Microsoft.Graphics.Canvas.dll">
<activatableClass
name="Microsoft.Graphics.Canvas.CanvasDevice"
threadingModel="both"
xmlns="urn:schemas-microsoft-com:winrt.v1" />
<activatableClass
name="Microsoft.Graphics.Canvas.UI.Xaml.CanvasImageSource"
threadingModel="both"
xmlns="urn:schemas-microsoft-com:winrt.v1" />
<activatableClass
name="Microsoft.Graphics.Canvas.CanvasBitmap"
threadingModel="both"
xmlns="urn:schemas-microsoft-com:winrt.v1" />
</asmv3:file>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">

72
UnitTests/UnitTests.XamlIslands/resources.Designer.cs сгенерированный Normal file
Просмотреть файл

@ -0,0 +1,72 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace UnitTests.XamlIslands {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("UnitTests.XamlIslands.resources", typeof(resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to ABC.
/// </summary>
internal static string abc {
get {
return ResourceManager.GetString("abc", resourceCulture);
}
}
}
}

Просмотреть файл

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="abc" xml:space="preserve">
<value>ABC</value>
</data>
</root>

Просмотреть файл

@ -136,6 +136,7 @@
<Compile Include="GlobalSuppressions.cs" />
<Compile Include="Helpers\TestCollectionCapableDeepLinkParser.cs" />
<Compile Include="Helpers\TestDeepLinkParser.cs" />
<Compile Include="Helpers\Test_DispatcherQueueHelper.cs" />
<Compile Include="Helpers\Test_DispatcherHelper.cs" />
<Compile Include="Helpers\Test_AdvancedCollectionView.cs" />
<Compile Include="Helpers\Test_BackgroundTaskHelper.cs" />

Просмотреть файл

@ -92,6 +92,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Toolkit.Uwp.UI.Me
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests.XamlIslands", "UnitTests\UnitTests.XamlIslands\UnitTests.XamlIslands.csproj", "{F5929F8E-7BC5-4A7B-A92A-AC751F7906E4}"
EndProject
Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "UnitTests.XamlIslands.Package", "UnitTests\UnitTests.XamlIslands.Package\UnitTests.XamlIslands.Package.wapproj", "{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
UnitTests\UnitTests.Notifications.Shared\UnitTests.Notifications.Shared.projitems*{982cc826-aacd-4855-9075-430bb6ce40a9}*SharedItemsImports = 13
@ -809,7 +811,8 @@ Global
{F5929F8E-7BC5-4A7B-A92A-AC751F7906E4}.Debug|Any CPU.ActiveCfg = Debug|x86
{F5929F8E-7BC5-4A7B-A92A-AC751F7906E4}.Debug|ARM.ActiveCfg = Debug|x86
{F5929F8E-7BC5-4A7B-A92A-AC751F7906E4}.Debug|ARM64.ActiveCfg = Debug|x86
{F5929F8E-7BC5-4A7B-A92A-AC751F7906E4}.Debug|x64.ActiveCfg = Debug|x86
{F5929F8E-7BC5-4A7B-A92A-AC751F7906E4}.Debug|x64.ActiveCfg = Debug|x64
{F5929F8E-7BC5-4A7B-A92A-AC751F7906E4}.Debug|x64.Build.0 = Debug|x64
{F5929F8E-7BC5-4A7B-A92A-AC751F7906E4}.Debug|x86.ActiveCfg = Debug|x86
{F5929F8E-7BC5-4A7B-A92A-AC751F7906E4}.Debug|x86.Build.0 = Debug|x86
{F5929F8E-7BC5-4A7B-A92A-AC751F7906E4}.Native|Any CPU.ActiveCfg = Release|x86
@ -823,6 +826,51 @@ Global
{F5929F8E-7BC5-4A7B-A92A-AC751F7906E4}.Release|x64.ActiveCfg = Release|x86
{F5929F8E-7BC5-4A7B-A92A-AC751F7906E4}.Release|x86.ActiveCfg = Release|x86
{F5929F8E-7BC5-4A7B-A92A-AC751F7906E4}.Release|x86.Build.0 = Release|x86
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Debug|ARM.ActiveCfg = Debug|ARM
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Debug|ARM.Build.0 = Debug|ARM
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Debug|ARM.Deploy.0 = Debug|ARM
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Debug|ARM64.ActiveCfg = Debug|ARM64
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Debug|ARM64.Build.0 = Debug|ARM64
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Debug|ARM64.Deploy.0 = Debug|ARM64
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Debug|x64.ActiveCfg = Debug|x64
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Debug|x64.Build.0 = Debug|x64
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Debug|x64.Deploy.0 = Debug|x64
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Debug|x86.ActiveCfg = Debug|x86
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Debug|x86.Build.0 = Debug|x86
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Debug|x86.Deploy.0 = Debug|x86
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Native|Any CPU.ActiveCfg = Debug|Any CPU
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Native|Any CPU.Build.0 = Debug|Any CPU
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Native|Any CPU.Deploy.0 = Debug|Any CPU
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Native|ARM.ActiveCfg = Release|ARM
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Native|ARM.Build.0 = Release|ARM
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Native|ARM.Deploy.0 = Release|ARM
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Native|ARM64.ActiveCfg = Release|ARM64
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Native|ARM64.Build.0 = Release|ARM64
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Native|ARM64.Deploy.0 = Release|ARM64
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Native|x64.ActiveCfg = Release|x64
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Native|x64.Build.0 = Release|x64
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Native|x64.Deploy.0 = Release|x64
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Native|x86.ActiveCfg = Release|x86
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Native|x86.Build.0 = Release|x86
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Native|x86.Deploy.0 = Release|x86
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Release|Any CPU.Build.0 = Release|Any CPU
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Release|Any CPU.Deploy.0 = Release|Any CPU
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Release|ARM.ActiveCfg = Release|ARM
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Release|ARM.Build.0 = Release|ARM
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Release|ARM.Deploy.0 = Release|ARM
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Release|ARM64.ActiveCfg = Release|ARM64
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Release|ARM64.Build.0 = Release|ARM64
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Release|ARM64.Deploy.0 = Release|ARM64
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Release|x64.ActiveCfg = Release|x64
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Release|x64.Build.0 = Release|x64
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Release|x64.Deploy.0 = Release|x64
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Release|x86.ActiveCfg = Release|x86
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Release|x86.Build.0 = Release|x86
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC}.Release|x86.Deploy.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -847,6 +895,7 @@ Global
{A122EA02-4DE7-413D-BFBF-AF7DFC668DD6} = {B30036C4-D514-4E5B-A323-587A061772CE}
{75F9EE44-3EFA-47BC-AEDD-351B9834A0AF} = {F1AFFFA7-28FE-4770-BA48-10D76F3E59BC}
{F5929F8E-7BC5-4A7B-A92A-AC751F7906E4} = {B30036C4-D514-4E5B-A323-587A061772CE}
{DCFBF9F1-2BBE-498D-B6C9-8ADE50C06CDC} = {B30036C4-D514-4E5B-A323-587A061772CE}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {5403B0C4-F244-4F73-A35C-FE664D0F4345}