Merge pull request #85 from windows-toolkit/Update19H1.rel6

Update to support 19H1, customization of the Xaml application and support for 3rd party control authors
This commit is contained in:
Oscar Calvo 2019-03-05 13:26:39 -08:00 коммит произвёл GitHub
Родитель 537a56d64f 83c9e8e6b3
Коммит 1dbafae37f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
41 изменённых файлов: 1019 добавлений и 528 удалений

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

@ -46,7 +46,7 @@
./build/Install-WindowsSDKISO.ps1 18327
-->
<TargetPlatformVersion>10.0.18327.0</TargetPlatformVersion>
<!-- XAML Islands require SDK 18226 -->
<!-- XAML Islands require SDK 18226 -->
<TargetPlatformMinVersion>10.0.18226.0</TargetPlatformMinVersion>
<!-- Compiler -->

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

@ -0,0 +1,43 @@
// 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.Runtime.InteropServices;
using WUX = Windows.UI.Xaml;
namespace Microsoft.Toolkit.Win32.UI.XamlHost
{
/// <summary>
/// Enables access to native methods on DesktopWindowXamlSourceNative version 2 for RS5
/// </summary>
/// <remarks>
/// Includes the method used to set the window handle of the <see cref="WUX.Hosting.DesktopWindowXamlSource" /> instance.
/// </remarks>
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("e3dcd8c7-3057-4692-99c3-7b7720afda31")]
internal partial interface IDesktopWindowXamlSourceNative2
{
/// <summary>
/// Attaches the <see cref="WUX.Hosting.DesktopWindowXamlSource" /> to a window using a window handle.
/// </summary>
/// <param name="parentWnd">pointer to parent Wnd</param>
/// <remarks>
/// The associated window will be used to parent UWP XAML visuals, appearing
/// as UWP XAML's logical render target.
/// </remarks>
void AttachToWindow(IntPtr parentWnd);
/// <summary>
/// Gets the handle associated with the <see cref="WUX.Hosting.DesktopWindowXamlSource" /> instance.
/// </summary>
IntPtr WindowHandle { get; }
/// <summary>
/// Sends the <paramref name="message"/> to the internal <see cref="WUX.Hosting.DesktopWindowXamlSource" /> window handle.
/// </summary>
/// <returns>True if the <paramref name="message"/> was handled</returns>
bool PreTranslateMessage(ref System.Windows.Forms.Message message);
}
}

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

@ -26,9 +26,9 @@
</ItemGroup>
<ItemGroup>
<Compile Include="..\Microsoft.Toolkit.Win32.UI.XamlHost\**\*.cs" />
<Compile Include="..\Microsoft.Toolkit.Win32.UI.Controls\Interop\Win32\ExternDll.cs" Link="Interop\Win32\ExternDll.cs" />
<Compile Include="..\Microsoft.Toolkit.Win32.UI.Controls\Interop\Win32\WM.cs" Link="Interop\Win32\WM.cs" />
<Compile Include="..\Microsoft.Toolkit.Wpf.UI.XamlHost\GlobalSuppressions.cs" Link="GlobalSuppressions.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net462'">
@ -69,4 +69,8 @@
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Microsoft.Toolkit.Win32.UI.XamlHost\Microsoft.Toolkit.Win32.UI.XamlHost.csproj" />
</ItemGroup>
</Project>

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

@ -6,6 +6,7 @@ using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Microsoft.Toolkit.Forms.UI.XamlHost.Interop.Win32;
using Microsoft.Toolkit.Win32.UI.XamlHost;
using windows = Windows;
namespace Microsoft.Toolkit.Forms.UI.XamlHost
@ -83,16 +84,34 @@ namespace Microsoft.Toolkit.Forms.UI.XamlHost
}
else
{
// Temporary Focus handling for Redstone 5
// Call windows.UI.Xaml.Input.FocusManager.TryMoveFocus Next or Previous and return
windows.UI.Xaml.Input.FocusNavigationDirection navigationDirection =
forward ? windows.UI.Xaml.Input.FocusNavigationDirection.Next : windows.UI.Xaml.Input.FocusNavigationDirection.Previous;
return windows.UI.Xaml.Input.FocusManager.TryMoveFocus(navigationDirection);
}
}
/// <summary>
/// In order to handle keyboard accelerators and TAB input, we must give a chance to <seealso cref="windows.UI.Xaml.Hosting.DesktopWindowXamlSource"/>
/// to handle the <paramref name="msg"/> using <seealso cref="IDesktopWindowXamlSourceNative2.PreTranslateMessage(ref Message)"/>
/// </summary>
/// <param name="msg">The current incomming message in the queue</param>
/// <returns>True if <seealso cref="_xamlSource"/> was able to handle the <paramref name="msg"/></returns>
public override bool PreProcessMessage(ref Message msg)
{
var desktopXamlSourceNative = this._xamlSource.GetInterop<IDesktopWindowXamlSourceNative2>();
if (desktopXamlSourceNative != null)
{
var result = desktopXamlSourceNative.PreTranslateMessage(ref msg);
if (result)
{
return true;
}
}
return base.PreProcessMessage(ref msg);
}
/// <summary>
/// Responds to DesktopWindowsXamlSource TakeFocusRequested event
/// </summary>

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

@ -8,9 +8,7 @@ using System.Drawing;
using System.Windows.Forms;
using Microsoft.Toolkit.Win32.UI.XamlHost;
using Windows.Foundation.Metadata;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media;
using windows = Windows;
using WUX = Windows.UI.Xaml;
namespace Microsoft.Toolkit.Forms.UI.XamlHost
{
@ -20,38 +18,45 @@ namespace Microsoft.Toolkit.Forms.UI.XamlHost
[System.ComponentModel.DesignerCategory("code")]
public abstract partial class WindowsXamlHostBase : ContainerControl
{
#pragma warning disable CA1051 // Do not declare visible instance fields
#pragma warning disable SA1401 // Fields must be private
/// <summary>
/// An instance of <seealso cref="IXamlMetadataContainer"/>. Required to
/// probe at runtime for custom UWP XAML type information.
/// This must be implemented by the instance of <seealso cref="WUX.Application"/>
/// </summary>
/// <remarks>
/// <seealso cref="WUX.Application"/> object is required for loading custom control metadata. If a custom
/// Application object is not provided by the application, the host control will create an instance of <seealso cref="XamlApplication"/>.
/// Instantiation of the application object must occur before creating the DesktopWindowXamlSource instance.
/// If no Application object is created before DesktopWindowXamlSource is created, DestkopWindowXamlSource
/// will create an instance of <seealso cref="XamlApplication"/> that implements <seealso cref="IXamlMetadataContainer"/>.
/// </remarks>
private static readonly IXamlMetadataContainer _metadataContainer = XamlApplication.GetOrCreateXamlMetadataContainer();
/// <summary>
/// DesktopWindowXamlSource instance
/// </summary>
protected internal readonly windows.UI.Xaml.Hosting.DesktopWindowXamlSource _xamlSource;
private readonly WUX.Hosting.DesktopWindowXamlSource _xamlSource;
/// <summary>
/// A render transform to scale the UWP XAML content should be applied
/// </summary>
protected internal bool _dpiScalingRenderTransformEnabled = false;
#pragma warning restore SA1401 // Fields must be private
#pragma warning restore CA1051 // Do not declare visible instance fields
private bool _dpiScalingRenderTransformEnabled = false;
/// <summary>
/// A reference count on the UWP XAML framework is tied to WindowsXamlManager's
/// lifetime. UWP XAML is spun up on the first WindowsXamlManager creation and
/// deinitialized when the last instance of WindowsXamlManager is destroyed.
/// Gets the current instance of <seealso cref="XamlApplication"/>
/// </summary>
private readonly windows.UI.Xaml.Hosting.WindowsXamlManager _windowsXamlManager;
/// <summary>
/// UWP XAML Application instance and root UWP XamlMetadataProvider. Custom implementation required to
/// probe at runtime for custom UWP XAML type information. This must be created before
/// creating any DesktopWindowXamlSource instances if custom UWP XAML types are required.
/// </summary>
private readonly windows.UI.Xaml.Application _application;
protected static IXamlMetadataContainer MetadataContainer
{
get
{
return _metadataContainer;
}
}
/// <summary>
/// Private field that backs ChildInternal property.
/// </summary>
private UIElement _childInternal;
private WUX.UIElement _childInternal;
/// <summary>
/// Last preferredSize returned by UWP XAML during WinForms layout pass
@ -73,15 +78,6 @@ namespace Microsoft.Toolkit.Forms.UI.XamlHost
/// </summary>
private double _lastDpi = 96.0f;
/// <summary>
/// When a window containing Xaml content moves, Xaml closes all open popups. We need the same behavior for Xaml
/// content in the DesktopWindowXamlSource. Since the DesktopWindowXamlSource itself is not notified when the
/// Form moves, we attach handlers to the Form's SizeChanged and LocationChanged events and use the Xaml
/// VisualTreeHelper API to close all open popups in an event handler. The Form is not reachable until after
/// this control is created. This field tracks the Form so we can detach the event handlers during cleanup.
/// </summary>
private Form _form;
/// <summary>
/// Fired when XAML content has been updated
/// </summary>
@ -115,23 +111,8 @@ namespace Microsoft.Toolkit.Forms.UI.XamlHost
// Respond to size changes on this Control
SizeChanged += OnWindowXamlHostSizeChanged;
// Windows.UI.Xaml.Application object is required for loading custom control metadata. If a custom
// Application object is not provided by the application, the host control will create one (XamlApplication).
// Instantiation of the application object must occur before creating the DesktopWindowXamlSource instance.
// If no Application object is created before DesktopWindowXamlSource is created, DestkopWindowXamlSource
// will create a generic Application object unable to load custom UWP XAML metadata.
Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication.GetOrCreateXamlApplicationInstance(ref _application);
// Create an instance of the WindowsXamlManager. This initializes and holds a
// reference on the UWP XAML DXamlCore and must be explicitly created before
// any UWP XAML types are programmatically created. If WindowsXamlManager has
// not been created before creating DesktopWindowXamlSource, DesktopWindowXaml source
// will create an instance of WindowsXamlManager internally. (Creation is explicit
// here to illustrate how to initialize UWP XAML before initializing the DesktopWindowXamlSource.)
_windowsXamlManager = windows.UI.Xaml.Hosting.WindowsXamlManager.InitializeForCurrentThread();
// Create DesktopWindowXamlSource, host for UWP XAML content
_xamlSource = new windows.UI.Xaml.Hosting.DesktopWindowXamlSource();
_xamlSource = new WUX.Hosting.DesktopWindowXamlSource();
// Hook up method for DesktopWindowXamlSource Focus handling
_xamlSource.TakeFocusRequested += this.OnTakeFocusRequested;
@ -141,8 +122,6 @@ namespace Microsoft.Toolkit.Forms.UI.XamlHost
// Add scaling panel as the root XAML element
_xamlSource.Content = new DpiScalingPanel();
HandleCreated += WindowsXamlHostBase_HandleCreated;
}
protected WindowsXamlHostBase(string typeName)
@ -155,48 +134,6 @@ namespace Microsoft.Toolkit.Forms.UI.XamlHost
}
}
/// <summary>
/// Attaches event handlers to Form.SizeChanged and Form.LocationChanged to close all popups opened by the
/// Xaml content inside the DesktopWindowXamlSource.
/// </summary>
private void WindowsXamlHostBase_HandleCreated(object sender, EventArgs e)
{
if (_form == null)
{
_form = FindForm();
_form.LocationChanged += OnFormLocationChanged;
}
}
/// <summary>
/// Close all popups opened by the Xaml content inside the DesktopWindowXamlSource.
/// </summary>
private void OnFormLocationChanged(object sender, EventArgs e)
{
#pragma warning disable 8305 // Experimental API
XamlRoot xamlRoot = _childInternal.XamlRoot;
var openPopups = VisualTreeHelper.GetOpenPopupsForXamlRoot(xamlRoot);
foreach (windows.UI.Xaml.Controls.Primitives.Popup popup in openPopups)
{
// Toggle the CompositeMode property, which will force all windowed Popups
// to reposition themselves relative to the new position of the host window.
var compositeMode = popup.CompositeMode;
// Set CompositeMode to some value it currently isn't set to.
if (compositeMode == ElementCompositeMode.SourceOver)
{
popup.CompositeMode = ElementCompositeMode.MinBlend;
}
else
{
popup.CompositeMode = ElementCompositeMode.SourceOver;
}
// Restore CompositeMode to whatever it was originally set to.
popup.CompositeMode = compositeMode;
}
}
/// <summary>
/// Exposes ChildInternal without exposing its actual Type.
/// </summary>
@ -211,7 +148,7 @@ namespace Microsoft.Toolkit.Forms.UI.XamlHost
/// </summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
protected windows.UI.Xaml.UIElement ChildInternal
protected WUX.UIElement ChildInternal
{
get => _childInternal;
@ -224,8 +161,8 @@ namespace Microsoft.Toolkit.Forms.UI.XamlHost
return;
}
var newFrameworkElement = value as windows.UI.Xaml.FrameworkElement;
var oldFrameworkElement = ChildInternal as windows.UI.Xaml.FrameworkElement;
var newFrameworkElement = value as WUX.FrameworkElement;
var oldFrameworkElement = ChildInternal as WUX.FrameworkElement;
if (oldFrameworkElement != null)
{
@ -257,7 +194,7 @@ namespace Microsoft.Toolkit.Forms.UI.XamlHost
/// Sets the root UWP XAML element on DesktopWindowXamlSource
/// </summary>
/// <param name="newValue">A UWP XAML Framework element</param>
protected virtual void SetContent(windows.UI.Xaml.UIElement newValue)
protected virtual void SetContent(WUX.UIElement newValue)
{
if (_xamlSource != null)
{
@ -302,20 +239,12 @@ namespace Microsoft.Toolkit.Forms.UI.XamlHost
SizeChanged -= OnWindowXamlHostSizeChanged;
ChildInternal?.ClearWrapper();
if (_form != null)
{
_form.LocationChanged -= OnFormLocationChanged;
_form = null;
}
// Required by CA2213: _xamlSource?.Dispose() is insufficient.
if (_xamlSource != null)
{
_xamlSource.TakeFocusRequested -= OnTakeFocusRequested;
_xamlSource.Dispose();
}
_windowsXamlManager?.Dispose();
}
base.Dispose(disposing);
@ -332,7 +261,7 @@ namespace Microsoft.Toolkit.Forms.UI.XamlHost
if (!DesignMode)
{
// Attach window to DesktopWindowXamSource as a render target
var desktopWindowXamlSourceNative = _xamlSource.GetInterop();
var desktopWindowXamlSourceNative = _xamlSource.GetInterop<IDesktopWindowXamlSourceNative>();
desktopWindowXamlSourceNative.AttachToWindow(Handle);
_xamlIslandWindowHandle = desktopWindowXamlSourceNative.WindowHandle;

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

@ -5,13 +5,14 @@
using Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT;
using System;
using System.Windows.Forms;
using WUX = Windows.UI.Xaml;
using windows = Windows;
namespace Microsoft.Toolkit.Win32.Samples.WinForms.App
{
public partial class Form1 : Form
{
private windows.UI.Xaml.Controls.ContentDialog _contentDialog;
private WUX.Controls.ContentDialog _contentDialog;
public Form1()
{
@ -22,58 +23,58 @@ namespace Microsoft.Toolkit.Win32.Samples.WinForms.App
{
inkCanvas1.InkPresenter.InputDeviceTypes = CoreInputDeviceTypes.Pen | CoreInputDeviceTypes.Mouse | CoreInputDeviceTypes.Touch;
windows.UI.Xaml.Controls.StackPanel stackPanel = new windows.UI.Xaml.Controls.StackPanel()
WUX.Controls.StackPanel stackPanel = new WUX.Controls.StackPanel()
{
Background = new windows.UI.Xaml.Media.SolidColorBrush(windows.UI.Colors.Black),
Background = new WUX.Media.SolidColorBrush(windows.UI.Colors.Black),
};
stackPanel.Children.Add(new windows.UI.Xaml.Shapes.Rectangle()
stackPanel.Children.Add(new WUX.Shapes.Rectangle()
{
Width = 50,
Height = 75,
Fill = new windows.UI.Xaml.Media.SolidColorBrush(windows.UI.Colors.Blue),
Fill = new WUX.Media.SolidColorBrush(global::Windows.UI.Colors.Blue),
});
stackPanel.Children.Add(new windows.UI.Xaml.Shapes.Rectangle()
stackPanel.Children.Add(new WUX.Shapes.Rectangle()
{
Width = 200,
Height = 30,
Fill = new windows.UI.Xaml.Media.SolidColorBrush(windows.UI.Colors.Red),
Fill = new WUX.Media.SolidColorBrush(global::Windows.UI.Colors.Red),
});
var button = new windows.UI.Xaml.Controls.Button
var button = new WUX.Controls.Button
{
Width = 160,
Height = 60,
HorizontalAlignment = windows.UI.Xaml.HorizontalAlignment.Center,
HorizontalAlignment = WUX.HorizontalAlignment.Center,
Content = "ContentDialog UWP Button",
};
button.Tapped += Button_Tapped;
stackPanel.Children.Add(button);
stackPanel.Children.Add(new windows.UI.Xaml.Shapes.Rectangle()
stackPanel.Children.Add(new WUX.Shapes.Rectangle()
{
Width = 25,
Height = 100,
Fill = new windows.UI.Xaml.Media.SolidColorBrush(windows.UI.Colors.Green),
Fill = new WUX.Media.SolidColorBrush(global::Windows.UI.Colors.Green),
});
windows.UI.Xaml.Controls.Flyout flyout = new windows.UI.Xaml.Controls.Flyout();
flyout.Content = new windows.UI.Xaml.Controls.TextBlock() { Text = "Flyout content", };
WUX.Controls.Flyout flyout = new WUX.Controls.Flyout();
flyout.Content = new WUX.Controls.TextBlock() { Text = "Flyout content", };
var button2 = new windows.UI.Xaml.Controls.Button()
var button2 = new WUX.Controls.Button()
{
Width = 300,
Height = 40,
HorizontalAlignment = windows.UI.Xaml.HorizontalAlignment.Center,
HorizontalAlignment = WUX.HorizontalAlignment.Center,
Content = "Long UWP Button with Flyout",
Flyout = flyout,
};
stackPanel.Children.Add(button2);
var comboBox = new windows.UI.Xaml.Controls.ComboBox()
var comboBox = new WUX.Controls.ComboBox()
{
HorizontalAlignment = windows.UI.Xaml.HorizontalAlignment.Center,
HorizontalAlignment = WUX.HorizontalAlignment.Center,
};
comboBox.Items.Add("One");
comboBox.Items.Add("Two");
@ -81,28 +82,28 @@ namespace Microsoft.Toolkit.Win32.Samples.WinForms.App
comboBox.Items.Add("Four");
stackPanel.Children.Add(comboBox);
windows.UI.Xaml.Controls.Grid grid = new windows.UI.Xaml.Controls.Grid();
WUX.Controls.Grid grid = new WUX.Controls.Grid();
stackPanel.Children.Add(grid);
_contentDialog = new windows.UI.Xaml.Controls.ContentDialog();
_contentDialog.Content = new windows.UI.Xaml.Controls.TextBlock() { Text = "ContentDialog content", };
_contentDialog = new WUX.Controls.ContentDialog();
_contentDialog.Content = new WUX.Controls.TextBlock() { Text = "ContentDialog content", };
stackPanel.Children.Add(_contentDialog);
var popup = new windows.UI.Xaml.Controls.Primitives.Popup()
var popup = new WUX.Controls.Primitives.Popup()
{
Width = 50,
Height = 50,
ShouldConstrainToRootBounds = false,
Child = new windows.UI.Xaml.Controls.TextBlock() { Text = "Popup child", },
Child = new WUX.Controls.TextBlock() { Text = "Popup child", },
};
grid.Children.Add(popup);
windowsXamlHost.Child = stackPanel;
popup.IsOpen = true;
}
private async void Button_Tapped(object sender, windows.UI.Xaml.Input.TappedRoutedEventArgs e)
private async void Button_Tapped(object sender, WUX.Input.TappedRoutedEventArgs e)
{
await _contentDialog.ShowAsync(windows.UI.Xaml.Controls.ContentDialogPlacement.Popup);
await _contentDialog.ShowAsync(WUX.Controls.ContentDialogPlacement.Popup);
}
}
}

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

@ -9,7 +9,7 @@
<Description>Sample Code for Windows Community Toolkit Controls</Description>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net462'">
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
@ -34,8 +34,12 @@
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
<PackageReference Include="System.Runtime.WindowsRuntime" Version="4.6.0-preview.19073.11" />
<PackageReference Include="System.Runtime.WindowsRuntime.UI.Xaml" Version="4.6.0-preview.19073.11" />
<Reference Include="System.Runtime.WindowsRuntime">
<HintPath>$(WINDIR)\Microsoft.NET\Framework\v4.0.30319\System.Runtime.WindowsRuntime.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.WindowsRuntime.UI.Xaml">
<HintPath>$(WINDIR)\Microsoft.NET\Framework\v4.0.30319\System.Runtime.WindowsRuntime.UI.Xaml.dll</HintPath>
</Reference>
<Reference Include="Windows">
<HintPath>$(MSBuildProgramFiles32)\Windows Kits\10\UnionMetadata\10.0.18327.0\Windows.winmd</HintPath>
<IsWinMDFile>true</IsWinMDFile>
@ -60,6 +64,10 @@
<Project>{b4911490-d52e-4cf2-bd14-ba487bdf2240}</Project>
<Name>Microsoft.Toolkit.Forms.UI.XamlHost</Name>
</ProjectReference>
<ProjectReference Include="..\Microsoft.Toolkit.Win32.UI.XamlHost\Microsoft.Toolkit.Win32.UI.XamlHost.csproj">
<Project>{f87edd34-af48-45c7-9342-49023b882da1}</Project>
<Name>Microsoft.Toolkit.Win32.UI.XamlHost</Name>
</ProjectReference>
</ItemGroup>
<Target Name="Pack">
<!-- No-op to avoid build error when packing solution from commandline -->

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

@ -3,10 +3,8 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using WUX = Windows.UI.Xaml;
namespace Microsoft.Toolkit.Win32.Samples.WinForms.App
{
@ -18,9 +16,15 @@ namespace Microsoft.Toolkit.Win32.Samples.WinForms.App
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(true);
Application.Run(new Form1());
using (new UI.XamlHost.XamlApplication()
{
RequestedTheme = WUX.ApplicationTheme.Light,
})
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(true);
Application.Run(new Form1());
}
}
}
}

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

@ -4,28 +4,21 @@
<OutputType>WinExe</OutputType>
<TargetFrameworks>net462;netcoreapp3.0</TargetFrameworks>
<ApplicationManifest>app.manifest</ApplicationManifest>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<AssemblyTitle>Windows Community Toolkit Controls (Sample Xaml Island Wrapper Controls for .NET WPF)</AssemblyTitle>
<Description>Sample Code for Windows Community Toolkit Controls</Description>
<UseWPF>true</UseWPF>
<StartupObject>Microsoft.Toolkit.Sample.Wpf.App.Program</StartupObject>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
<PackageReference Include="System.Runtime.WindowsRuntime" Version="4.6.0-preview.19073.11" />
<PackageReference Include="System.Runtime.WindowsRuntime.UI.Xaml" Version="4.6.0-preview.19073.11" />
<Reference Include="Windows">
<HintPath>$(MSBuildProgramFiles32)\Windows Kits\10\UnionMetadata\10.0.18327.0\Windows.winmd</HintPath>
<IsWinMDFile>true</IsWinMDFile>
<Private>false</Private>
</Reference>
</ItemGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugType>full</DebugType>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
</PropertyGroup>
<Target Name="Pack">
<!-- No-op to avoid build error when packing solution from commandline -->
</Target>
<ItemGroup Condition="'$(TargetFramework)' == 'net462'">
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data.DataSetExtensions" />
@ -38,9 +31,23 @@
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
<None Remove="App.xaml" />
<None Remove="MainWindow.xaml" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
</ApplicationDefinition>
</ItemGroup>
<ItemGroup>
<None Include="app.manifest" />
</ItemGroup>
<ItemGroup>
<Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Microsoft.Toolkit.Wpf.UI.Controls.WebView\Microsoft.Toolkit.Wpf.UI.Controls.WebView.csproj" />
<ProjectReference Include="..\Microsoft.Toolkit.Wpf.UI.Controls\Microsoft.Toolkit.Wpf.UI.Controls.csproj" />
@ -49,4 +56,17 @@
<ItemGroup>
<Resource Include="Assets\storelogo-sdk.png" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Settings.Designer.cs">
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<None Update="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
</Project>

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

@ -0,0 +1,103 @@
// 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.Linq;
using Windows.UI.Xaml.Markup;
namespace Microsoft.Toolkit.Sample.Wpf.App
{
public class MyControl : Toolkit.Wpf.UI.XamlHost.WindowsXamlHostBase
{
static MyControl()
{
if (MetadataContainer != null)
{
MetadataContainer.MetadataProviders.Add(new MyMetadataProvider());
}
else
{
#pragma warning disable CA1065 // Do not raise exceptions in unexpected locations
throw new InvalidOperationException($"{typeof(MyControl).Name} only supported for {typeof(global::Windows.UI.Xaml.Application).FullName} instances that implements {typeof(Win32.UI.XamlHost.IXamlMetadataContainer).FullName}");
#pragma warning restore CA1065 // Do not raise exceptions in unexpected locations
}
}
public MyControl()
{
}
}
public sealed class MyMetadataProvider : IXamlMetadataProvider
{
public IXamlType GetXamlType(Type type)
{
return null;
}
public IXamlType GetXamlType(string fullName)
{
return null;
}
public XmlnsDefinition[] GetXmlnsDefinitions()
{
return System.Linq.Enumerable.Empty<XmlnsDefinition>().ToArray();
}
}
public static class Program
{
enum StartupKind
{
MultiThread,
CustomAppSettings,
Normal,
};
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
public static void Main()
{
var startupKind = StartupKind.Normal;
if (startupKind == StartupKind.CustomAppSettings)
{
using (var xamlApp = new Win32.UI.XamlHost.XamlApplication()
{
Resources = new global::Windows.UI.Xaml.ResourceDictionary()
{
{ "MyResourceKey", "MyValue" },
},
MetadataProviders = {
new MyMetadataProvider(),
},
})
{
var app = new Microsoft.Toolkit.Sample.Wpf.App.App();
app.InitializeComponent();
app.Run();
}
}
else if (startupKind == StartupKind.MultiThread)
{
using (var xamlApp = new Win32.UI.XamlHost.XamlApplication())
{
var appOwnedWindowsXamlManager = xamlApp.WindowsXamlManager;
var app = new Microsoft.Toolkit.Sample.Wpf.App.App();
app.InitializeComponent();
app.Run();
}
}
else
{
var app = new Microsoft.Toolkit.Sample.Wpf.App.App();
app.InitializeComponent();
app.Run();
}
}
}
}

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

@ -12,7 +12,7 @@ namespace Microsoft.Toolkit.Sample.Wpf.App.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.8.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));

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

@ -4,29 +4,31 @@
using System;
using System.Runtime.InteropServices;
using windows = Windows;
using WUX = Windows.UI.Xaml;
namespace Microsoft.Toolkit.Win32.UI.XamlHost
{
/// <summary>
/// COM wrapper required to access native-only methods on <see cref="windows.UI.Xaml.Hosting.DesktopWindowXamlSource" />
/// COM wrapper required to access native-only methods on <see cref="WUX.Hosting.DesktopWindowXamlSource" />
/// </summary>
public static class DesktopWindowXamlSourceExtensions
static partial class DesktopWindowXamlSourceExtensions
{
/// <summary>
/// Gets the <see cref="IDesktopWindowXamlSourceNative" /> interface from a <see cref="windows.UI.Xaml.Hosting.DesktopWindowXamlSource" /> instance.
/// Gets the <see cref="IDesktopWindowXamlSourceNative" /> interface from a <see cref="WUX.Hosting.DesktopWindowXamlSource" /> instance.
/// </summary>
/// <typeparam name="TInterface">The interface to cast to</typeparam>
/// <param name="desktopWindowXamlSource">The DesktopWindowXamlSource instance to get the interface from</param>
/// <returns><see cref="IDesktopWindowXamlSourceNative" /> interface pointer</returns>
/// <remarks>
/// This interface is the only way to set DesktopWindowXamlSource's target window for rendering.
/// </remarks>
public static IDesktopWindowXamlSourceNative GetInterop(this windows.UI.Xaml.Hosting.DesktopWindowXamlSource desktopWindowXamlSource)
public static TInterface GetInterop<TInterface>(this WUX.Hosting.DesktopWindowXamlSource desktopWindowXamlSource)
where TInterface : class
{
var win32XamlSourceIntPtr = Marshal.GetIUnknownForObject(desktopWindowXamlSource);
try
{
var win32XamlSource = Marshal.GetTypedObjectForIUnknown(win32XamlSourceIntPtr, typeof(IDesktopWindowXamlSourceNative)) as IDesktopWindowXamlSourceNative;
var win32XamlSource = Marshal.GetTypedObjectForIUnknown(win32XamlSourceIntPtr, typeof(TInterface)) as TInterface;
return win32XamlSource;
}
finally

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

@ -0,0 +1,26 @@
// 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.
// This file is used by Code Analysis to maintain SuppressMessage
// attributes that are applied to this project.
// Project-level suppressions either have no target or are given
// a specific target and scoped to a namespace, type, member, etc.
//
// To add a suppression to this file, right-click the message in the
// Code Analysis results, point to "Suppress Message", and click
// "In Suppression File".
// You do not need to add suppressions to this file manually.
#pragma warning disable SA1404 // Code analysis suppression must have justification
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1205:Partial elements must declare access", Scope = "type", Target = "~T:Microsoft.Toolkit.Win32.UI.XamlHost.DesktopWindowXamlSourceExtensions")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1601:Partial elements must be documented", Scope = "type", Target = "~T:Microsoft.Toolkit.Win32.UI.XamlHost.IDesktopWindowXamlSourceNative")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1205:Partial elements must declare access", Scope = "type", Target = "~T:Microsoft.Toolkit.Win32.UI.XamlHost.IDesktopWindowXamlSourceNative")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1601:Partial elements must be documented", Scope = "type", Target = "~T:Microsoft.Toolkit.Win32.UI.XamlHost.DesktopWindowXamlSourceExtensions")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1205:Partial elements must declare access", Scope = "type", Target = "~T:Microsoft.Toolkit.Win32.UI.XamlHost.IDesktopWindowXamlSourceNative2")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1601:Partial elements must be documented", Scope = "type", Target = "~T:Microsoft.Toolkit.Win32.UI.XamlHost.IDesktopWindowXamlSourceNative2")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1205:Partial elements must declare access", Scope = "type", Target = "~T:Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1601:Partial elements must be documented", Scope = "type", Target = "~T:Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1205:Partial elements must declare access", Scope = "type", Target = "~T:Microsoft.Toolkit.Win32.UI.XamlHost.UWPTypeFactory")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1601:Partial elements must be documented", Justification = "<Pending>", Scope = "type", Target = "~T:Microsoft.Toolkit.Win32.UI.XamlHost.UWPTypeFactory")]
#pragma warning restore SA1404 // Code analysis suppression must have justification

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

@ -0,0 +1,20 @@
// 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.
namespace Microsoft.Toolkit.Win32.UI.XamlHost
{
/// <summary>
/// Defines assembly visibility for <seealso cref="IDesktopWindowXamlSourceNative"/>
/// </summary>
public partial interface IDesktopWindowXamlSourceNative
{
}
/// <summary>
/// Defines assembly visibility for <seealso cref="DesktopWindowXamlSourceExtensions"/>
/// </summary>
public static partial class DesktopWindowXamlSourceExtensions
{
}
}

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

@ -4,7 +4,7 @@
using System;
using System.Runtime.InteropServices;
using windows = Windows;
using WUX = Windows.UI.Xaml;
namespace Microsoft.Toolkit.Win32.UI.XamlHost
{
@ -12,15 +12,15 @@ namespace Microsoft.Toolkit.Win32.UI.XamlHost
/// Enables access to native methods on DesktopWindowXamlSourceNative
/// </summary>
/// <remarks>
/// Includes the method used to set the window handle of the <see cref="windows.UI.Xaml.Hosting.DesktopWindowXamlSource" /> instance.
/// Includes the method used to set the window handle of the <see cref="WUX.Hosting.DesktopWindowXamlSource" /> instance.
/// </remarks>
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("3cbcf1bf-2f76-4e9c-96ab-e84b37972554")]
public interface IDesktopWindowXamlSourceNative
partial interface IDesktopWindowXamlSourceNative
{
/// <summary>
/// Attaches the <see cref="windows.UI.Xaml.Hosting.DesktopWindowXamlSource" /> to a window using a window handle.
/// Attaches the <see cref="WUX.Hosting.DesktopWindowXamlSource" /> to a window using a window handle.
/// </summary>
/// <param name="parentWnd">pointer to parent Wnd</param>
/// <remarks>
@ -30,7 +30,7 @@ namespace Microsoft.Toolkit.Win32.UI.XamlHost
void AttachToWindow(IntPtr parentWnd);
/// <summary>
/// Gets the handle associated with the <see cref="windows.UI.Xaml.Hosting.DesktopWindowXamlSource" /> instance.
/// Gets the handle associated with the <see cref="WUX.Hosting.DesktopWindowXamlSource" /> instance.
/// </summary>
IntPtr WindowHandle { get; }
}

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

@ -0,0 +1,20 @@
// 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.Collections.Generic;
using WUX = Windows.UI.Xaml;
namespace Microsoft.Toolkit.Win32.UI.XamlHost
{
/// <summary>
/// Enables access to active set of <seealso cref="WUX.Markup.IXamlMetadataProvider"/>
/// </summary>
public partial interface IXamlMetadataContainer
{
/// <summary>
/// Gets the list of active <seealso cref="WUX.Markup.IXamlMetadataProvider"/>
/// </summary>
List<WUX.Markup.IXamlMetadataProvider> MetadataProviders { get; }
}
}

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

@ -7,7 +7,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Windows.UI.Xaml.Markup;
using WUX = Windows.UI.Xaml;
namespace Microsoft.Toolkit.Win32.UI.XamlHost
{
@ -20,15 +20,22 @@ namespace Microsoft.Toolkit.Win32.UI.XamlHost
/// </summary>
internal static class MetadataProviderDiscovery
{
private static readonly List<Type> FilteredTypes = new List<Type>
{
typeof(XamlApplication),
typeof(WUX.Markup.IXamlMetadataProvider)
};
/// <summary>
/// Probes working directory for all available metadata providers
/// </summary>
/// <param name="filteredTypes">Types to ignore</param>
/// <returns>List of UWP XAML metadata providers</returns>
internal static List<IXamlMetadataProvider> DiscoverMetadataProviders(List<Type> filteredTypes)
internal static List<WUX.Markup.IXamlMetadataProvider> DiscoverMetadataProviders()
{
var filteredTypes = FilteredTypes;
// List of discovered UWP XAML metadata providers
var metadataProviders = new List<IXamlMetadataProvider>();
var metadataProviders = new List<WUX.Markup.IXamlMetadataProvider>();
// Get all assemblies loaded in app domain and placed side-by-side from all DLL and EXE
var loadedAssemblies = GetAssemblies();
@ -101,7 +108,7 @@ namespace Microsoft.Toolkit.Win32.UI.XamlHost
/// <param name="assembly">Target assembly to load types from</param>
/// <param name="metadataProviders">List of metadata providers</param>
/// <param name="filteredTypes">List of types to ignore</param>
private static void LoadTypesFromAssembly(Assembly assembly, ref List<IXamlMetadataProvider> metadataProviders, ref List<Type> filteredTypes)
private static void LoadTypesFromAssembly(Assembly assembly, ref List<WUX.Markup.IXamlMetadataProvider> metadataProviders, ref List<Type> filteredTypes)
{
// Load types inside the executing assembly
foreach (var type in GetLoadableTypes(assembly))
@ -113,9 +120,9 @@ namespace Microsoft.Toolkit.Win32.UI.XamlHost
// TODO: More type checking here
// Not interface, not abstract, not generic, etc.
if (typeof(IXamlMetadataProvider).IsAssignableFrom(type))
if (typeof(WUX.Markup.IXamlMetadataProvider).IsAssignableFrom(type))
{
var provider = (IXamlMetadataProvider)Activator.CreateInstance(type);
var provider = (WUX.Markup.IXamlMetadataProvider)Activator.CreateInstance(type);
metadataProviders.Add(provider);
}
}

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

@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<TargetFrameworks>net462;netcoreapp3.0</TargetFrameworks>
<RootNamespace>Microsoft.Toolkit.UI.XamlHost</RootNamespace>
<AssemblyName>Microsoft.Toolkit.Win32.UI.XamlHost</AssemblyName>
<Title>Windows Community Toolkit XAMLHost</Title>
<Description>This library provides XAML islands common helpers for WPF and WinForms. It is part of the Windows Community Toolkit.</Description>
<PackageTags>XAML Islands XAMLHost</PackageTags>
<PackageId>Microsoft.Toolkit.UI.XamlHost</PackageId>
<IsWpfProject>true</IsWpfProject>
</PropertyGroup>
</Project>

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

@ -0,0 +1,9 @@
// 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.Resources;
using System.Runtime.InteropServices;
[assembly: ComVisible(false)]
[assembly: NeutralResourcesLanguage("en-US")]

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

@ -0,0 +1,10 @@
// 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.
namespace Microsoft.Toolkit.Win32.UI.XamlHost
{
public static partial class UWPTypeFactory
{
}
}

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

@ -4,10 +4,14 @@
using System;
using windows = Windows;
using WUX = Windows.UI.Xaml;
namespace Microsoft.Toolkit.Win32.UI.XamlHost
{
public static class UWPTypeFactory
/// <summary>
/// Provides factory methods for type registered with <seealso cref="WUX.Application"/>
/// </summary>
static partial class UWPTypeFactory
{
/// <summary>
/// Creates UWP XAML type instance from WinRT type name

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

@ -0,0 +1,66 @@
// 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 WUX = Windows.UI.Xaml;
namespace Microsoft.Toolkit.Win32.UI.XamlHost
{
/// <summary>
/// XamlApplication is a custom <see cref="WUX.Application" /> that implements <see cref="WUX.Markup.IXamlMetadataProvider" />. The
/// metadata provider implemented on the application is known as the 'root metadata provider'. This provider
/// has the responsibility of loading all other metadata for custom UWP XAML types. In this implementation,
/// reflection is used at runtime to probe for metadata providers in the working directory, allowing any
/// type that includes metadata (compiled in to a .NET framework assembly) to be used without explicit
/// metadata handling by the developer.
/// </summary>
partial class XamlApplication : IDisposable
{
private readonly WUX.Hosting.WindowsXamlManager _windowsXamlManager;
/// <summary>
/// Gets a value indicating whether the instance has already been disposed
/// </summary>
public bool IsDisposed { get; private set; }
/// <summary>
/// Disposes the instance
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Called when the instance is getting finalized or disposed.
/// </summary>
/// <param name="disposing">True when disposing</param>
protected virtual void Dispose(bool disposing)
{
if (this.IsDisposed)
{
return;
}
if (disposing)
{
this._windowsXamlManager.Dispose();
}
this.IsDisposed = true;
}
/// <summary>
/// Gets the instance of the <seealso cref="WUX.Hosting.WindowsXamlManager"/>
/// </summary>
public WUX.Hosting.WindowsXamlManager WindowsXamlManager
{
get
{
return this._windowsXamlManager;
}
}
}
}

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

@ -0,0 +1,71 @@
// 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.Collections.Generic;
using WUX = Windows.UI.Xaml;
namespace Microsoft.Toolkit.Win32.UI.XamlHost
{
/// <summary>
/// XamlApplication is a custom <see cref="WUX.Application" /> that implements <see cref="WUX.Markup.IXamlMetadataProvider" />. The
/// metadata provider implemented on the application is known as the 'root metadata provider'. This provider
/// has the responsibility of loading all other metadata for custom UWP XAML types. In this implementation,
/// reflection is used at runtime to probe for metadata providers in the working directory, allowing any
/// type that includes metadata (compiled in to a .NET framework assembly) to be used without explicit
/// metadata handling by the developer.
/// </summary>
partial class XamlApplication : IXamlMetadataContainer
{
private static IXamlMetadataContainer _metadataContainer;
// Metadata provider identified by the root metadata provider
private readonly List<WUX.Markup.IXamlMetadataProvider> _metadataProviders;
/// <summary>
/// Gets the registered set of <seealso cref="WUX.Markup.IXamlMetadataProvider"/>
/// </summary>
public List<WUX.Markup.IXamlMetadataProvider> MetadataProviders
{
get
{
return this._metadataProviders;
}
}
/// <summary>
/// Gets and returns the current UWP XAML Application instance in a reference parameter.
/// If the current XAML Application instance has not been created for the process (is null),
/// a new <see cref="Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication" /> instance is created and returned.
/// </summary>
/// <returns>The instance of <seealso cref="XamlApplication"/></returns>
public static IXamlMetadataContainer GetOrCreateXamlMetadataContainer()
{
// Instantiation of the application object must occur before creating the DesktopWindowXamlSource instance.
// DesktopWindowXamlSource will create a generic Application object unable to load custom UWP XAML metadata.
if (_metadataContainer == null)
{
// Create a custom UWP XAML Application object that implements reflection-based XAML metadata probing.
try
{
var app = new XamlApplication();
app.MetadataProviders.AddRange(MetadataProviderDiscovery.DiscoverMetadataProviders());
return app;
}
catch
{
_metadataContainer = WUX.Application.Current as IXamlMetadataContainer;
}
}
var xamlApplication = _metadataContainer as XamlApplication;
if (xamlApplication != null && xamlApplication.IsDisposed)
{
throw new ObjectDisposedException(typeof(XamlApplication).FullName);
}
return _metadataContainer;
}
}
}

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

@ -0,0 +1,10 @@
// 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.
namespace Microsoft.Toolkit.Win32.UI.XamlHost
{
public partial class XamlApplication
{
}
}

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

@ -4,39 +4,49 @@
using System;
using System.Collections.Generic;
using windows = Windows;
using WUX = Windows.UI.Xaml;
namespace Microsoft.Toolkit.Win32.UI.XamlHost
{
/// <summary>
/// XamlApplication is a custom <see cref="windows.UI.Xaml.Application" /> that implements <see cref="windows.UI.Xaml.Markup.IXamlMetadataProvider" />. The
/// XamlApplication is a custom <see cref="WUX.Application" /> that implements <see cref="WUX.Markup.IXamlMetadataProvider" />. The
/// metadata provider implemented on the application is known as the 'root metadata provider'. This provider
/// has the responsibility of loading all other metadata for custom UWP XAML types. In this implementation,
/// reflection is used at runtime to probe for metadata providers in the working directory, allowing any
/// type that includes metadata (compiled in to a .NET framework assembly) to be used without explicit
/// metadata handling by the developer.
/// </summary>
internal class XamlApplication : windows.UI.Xaml.Application, windows.UI.Xaml.Markup.IXamlMetadataProvider
partial class XamlApplication : WUX.Application, WUX.Markup.IXamlMetadataProvider
{
private static readonly List<Type> FilteredTypes = new List<Type>
/// <summary>
/// Initializes a new instance of the <see cref="XamlApplication"/> class.
/// </summary>
public XamlApplication()
{
typeof(XamlApplication),
typeof(windows.UI.Xaml.Markup.IXamlMetadataProvider)
};
if (_metadataContainer != null)
{
throw new InvalidOperationException("Instance already exist");
}
// Metadata provider identified by the root metadata provider
private List<windows.UI.Xaml.Markup.IXamlMetadataProvider> _metadataProviders = null;
_metadataContainer = this;
this._metadataProviders = new List<WUX.Markup.IXamlMetadataProvider>();
// Create an instance of the WindowsXamlManager. This initializes and holds a
// reference on the UWP XAML DXamlCore and must be explicitly created before
// any UWP XAML types are programmatically created. If WindowsXamlManager has
// not been created before creating DesktopWindowXamlSource, DesktopWindowXaml source
// will create an instance of WindowsXamlManager here when creating XamlApplication.
this._windowsXamlManager = WUX.Hosting.WindowsXamlManager.InitializeForCurrentThread();
}
/// <summary>
/// Gets XAML <see cref="windows.UI.Xaml.Markup.IXamlType"/> interface from all cached metadata providers for the <paramref name="type"/>.
/// Gets XAML <see cref="WUX.Markup.IXamlType"/> interface from all cached metadata providers for the <paramref name="type"/>.
/// </summary>
/// <param name="type">Type of requested type</param>
/// <returns>IXamlType interface or null if type is not found</returns>
public windows.UI.Xaml.Markup.IXamlType GetXamlType(Type type)
public WUX.Markup.IXamlType GetXamlType(Type type)
{
EnsureMetadataProviders();
foreach (var provider in _metadataProviders)
foreach (var provider in this.MetadataProviders)
{
var result = provider.GetXamlType(type);
if (result != null)
@ -52,12 +62,10 @@ namespace Microsoft.Toolkit.Win32.UI.XamlHost
/// Gets XAML IXamlType interface from all cached metadata providers by full type name
/// </summary>
/// <param name="fullName">Full name of requested type</param>
/// <returns><see cref="windows.UI.Xaml.Markup.IXamlType"/> if found; otherwise, null.</returns>
public windows.UI.Xaml.Markup.IXamlType GetXamlType(string fullName)
/// <returns><see cref="WUX.Markup.IXamlType"/> if found; otherwise, null.</returns>
public WUX.Markup.IXamlType GetXamlType(string fullName)
{
EnsureMetadataProviders();
foreach (var provider in _metadataProviders)
foreach (var provider in this.MetadataProviders)
{
var result = provider.GetXamlType(fullName);
if (result != null)
@ -73,53 +81,15 @@ namespace Microsoft.Toolkit.Win32.UI.XamlHost
/// Gets all XAML namespace definitions from metadata providers
/// </summary>
/// <returns>Array of namespace definitions</returns>
public windows.UI.Xaml.Markup.XmlnsDefinition[] GetXmlnsDefinitions()
public WUX.Markup.XmlnsDefinition[] GetXmlnsDefinitions()
{
EnsureMetadataProviders();
var definitions = new List<windows.UI.Xaml.Markup.XmlnsDefinition>();
foreach (var provider in _metadataProviders)
var definitions = new List<WUX.Markup.XmlnsDefinition>();
foreach (var provider in this.MetadataProviders)
{
definitions.AddRange(provider.GetXmlnsDefinitions());
}
return definitions.ToArray();
}
/// <summary>
/// Probes file system for UWP XAML metadata providers
/// </summary>
private void EnsureMetadataProviders()
{
if (_metadataProviders == null)
{
_metadataProviders = MetadataProviderDiscovery.DiscoverMetadataProviders(FilteredTypes);
}
}
/// <summary>
/// Gets and returns the current UWP XAML Application instance in a reference parameter.
/// If the current XAML Application instance has not been created for the process (is null),
/// a new <see cref="Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication" /> instance is created and returned.
/// </summary>
internal static void GetOrCreateXamlApplicationInstance(ref windows.UI.Xaml.Application application)
{
// Instantiation of the application object must occur before creating the DesktopWindowXamlSource instance.
// DesktopWindowXamlSource will create a generic Application object unable to load custom UWP XAML metadata.
if (application == null)
{
try
{
// windows.UI.Xaml.Application.Current may throw if DXamlCore has not been initialized.
// Treat the exception as an uninitialized windows.UI.Xaml.Application condition.
application = windows.UI.Xaml.Application.Current;
}
catch
{
// Create a custom UWP XAML Application object that implements reflection-based XAML metadata probing.
application = new XamlApplication();
}
}
}
}
}

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

@ -43,8 +43,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
ProjectSection(SolutionItems) = preProject
Directory.Build.props = Directory.Build.props
Directory.Build.targets = Directory.Build.targets
version.json = version.json
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Toolkit.Win32.UI.XamlHost", "Microsoft.Toolkit.Win32.UI.XamlHost\Microsoft.Toolkit.Win32.UI.XamlHost.csproj", "{F87EDD34-AF48-45C7-9342-49023B882DA1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -75,12 +78,15 @@ Global
{D103E448-64B1-407C-B09E-7C61AF9F2740}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D103E448-64B1-407C-B09E-7C61AF9F2740}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D103E448-64B1-407C-B09E-7C61AF9F2740}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D103E448-64B1-407C-B09E-7C61AF9F2740}.Release|Any CPU.Build.0 = Release|Any CPU
{2FE9AA6A-BD27-438F-9941-221033E4A1DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2FE9AA6A-BD27-438F-9941-221033E4A1DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2FE9AA6A-BD27-438F-9941-221033E4A1DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2FE9AA6A-BD27-438F-9941-221033E4A1DD}.Release|Any CPU.Build.0 = Release|Any CPU
{45524ED2-8B5A-42E8-97A2-DCA44ECC83AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{45524ED2-8B5A-42E8-97A2-DCA44ECC83AA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{45524ED2-8B5A-42E8-97A2-DCA44ECC83AA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{45524ED2-8B5A-42E8-97A2-DCA44ECC83AA}.Release|Any CPU.Build.0 = Release|Any CPU
{B131E361-78CE-489B-B2C4-130C5FEB70F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B131E361-78CE-489B-B2C4-130C5FEB70F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B131E361-78CE-489B-B2C4-130C5FEB70F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -96,6 +102,11 @@ Global
{9C49A885-D39B-4CA0-9DEB-204A6EA7D453}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9C49A885-D39B-4CA0-9DEB-204A6EA7D453}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9C49A885-D39B-4CA0-9DEB-204A6EA7D453}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9C49A885-D39B-4CA0-9DEB-204A6EA7D453}.Release|Any CPU.Build.0 = Release|Any CPU
{F87EDD34-AF48-45C7-9342-49023B882DA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F87EDD34-AF48-45C7-9342-49023B882DA1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F87EDD34-AF48-45C7-9342-49023B882DA1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F87EDD34-AF48-45C7-9342-49023B882DA1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -115,6 +126,7 @@ Global
{A6F9DAE8-8CDC-4693-83E7-C9C59D1477FE} = {C0C8A97B-5921-465A-880C-3D5098872295}
{F8393C4E-4501-4CC2-8767-ABFE3AD1C0FB} = {C0C8A97B-5921-465A-880C-3D5098872295}
{9C49A885-D39B-4CA0-9DEB-204A6EA7D453} = {78966152-2550-4FA3-BDAC-CBEB078E739F}
{F87EDD34-AF48-45C7-9342-49023B882DA1} = {E3B3FB12-67C0-404C-BA3F-08E65BCC682C}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {AFDF3CA9-FBAD-4C80-A08A-7B69D21D561E}

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

@ -0,0 +1,19 @@
// 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.
// This file is used by Code Analysis to maintain SuppressMessage
// attributes that are applied to this project.
// Project-level suppressions either have no target or are given
// a specific target and scoped to a namespace, type, member, etc.
//
// To add a suppression to this file, right-click the message in the
// Code Analysis results, point to "Suppress Message", and click
// "In Suppression File".
// You do not need to add suppressions to this file manually.
#pragma warning disable SA1404 // Code analysis suppression must have justification
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1205:Partial elements must declare access", Scope = "type", Target = "~T:Microsoft.Toolkit.Wpf.UI.XamlHost.WindowsXamlHostBase")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1601:Partial elements must be documented", Scope = "type", Target = "~T:Microsoft.Toolkit.Wpf.UI.XamlHost.WindowsXamlHostBase")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1205:Partial elements must declare access", Scope = "type", Target = "~T:Microsoft.Toolkit.Wpf.UI.XamlHost.WindowsXamlHost")]
#pragma warning restore SA1404 // Code analysis suppression must have justification

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

@ -0,0 +1,43 @@
// 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.Runtime.InteropServices;
using WUX = Windows.UI.Xaml;
namespace Microsoft.Toolkit.Win32.UI.XamlHost
{
/// <summary>
/// Enables access to native methods on DesktopWindowXamlSourceNative version 2 for RS5
/// </summary>
/// <remarks>
/// Includes the method used to set the window handle of the <see cref="WUX.Hosting.DesktopWindowXamlSource" /> instance.
/// </remarks>
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("e3dcd8c7-3057-4692-99c3-7b7720afda31")]
internal partial interface IDesktopWindowXamlSourceNative2
{
/// <summary>
/// Attaches the <see cref="WUX.Hosting.DesktopWindowXamlSource" /> to a window using a window handle.
/// </summary>
/// <param name="parentWnd">pointer to parent Wnd</param>
/// <remarks>
/// The associated window will be used to parent UWP XAML visuals, appearing
/// as UWP XAML's logical render target.
/// </remarks>
void AttachToWindow(IntPtr parentWnd);
/// <summary>
/// Gets the handle associated with the <see cref="WUX.Hosting.DesktopWindowXamlSource" /> instance.
/// </summary>
IntPtr WindowHandle { get; }
/// <summary>
/// Sends the <paramref name="message"/> to the internal <see cref="WUX.Hosting.DesktopWindowXamlSource" /> window handle.
/// </summary>
/// <returns>True if the <paramref name="message"/> was handled</returns>
bool PreTranslateMessage(ref System.Windows.Interop.MSG message);
}
}

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

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<TargetFrameworks>net462;netcoreapp3.0</TargetFrameworks>
<TargetFrameworks>netcoreapp3.0;net462</TargetFrameworks>
<RootNamespace>Microsoft.Toolkit.Wpf.UI.XamlHost</RootNamespace>
<AssemblyName>Microsoft.Toolkit.Wpf.UI.XamlHost</AssemblyName>
@ -15,10 +15,6 @@
<UseWPF>true</UseWPF>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\Microsoft.Toolkit.Win32.UI.XamlHost\**\*.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net462'">
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
@ -62,4 +58,8 @@
<None Include="VisualStudioToolsManifest.xml" Pack="true" PackagePath="tools" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Microsoft.Toolkit.Win32.UI.XamlHost\Microsoft.Toolkit.Win32.UI.XamlHost.csproj" />
</ItemGroup>
</Project>

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

@ -1,49 +1,49 @@
// 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 windows = Windows;
namespace Microsoft.Toolkit.Wpf.UI.XamlHost
{
/// <summary>
/// Extensions for use with UWP UIElement objects wrapped by the WindowsXamlHostBaseExt
/// </summary>
public static class UwpUIElementExtensions
{
private static bool IsDesktopWindowsXamlSourcePresent() => windows.Foundation.Metadata.ApiInformation.IsApiContractPresent("Windows.UI.Xaml.Hosting.HostingContract", 3);
private static windows.UI.Xaml.DependencyProperty WrapperProperty
{
get
{
if (IsDesktopWindowsXamlSourcePresent())
{
var result = windows.UI.Xaml.DependencyProperty.RegisterAttached("Wrapper", typeof(System.Windows.UIElement), typeof(UwpUIElementExtensions), new windows.UI.Xaml.PropertyMetadata(null));
return result;
}
throw new NotImplementedException();
}
}
public static WindowsXamlHostBase GetWrapper(this windows.UI.Xaml.UIElement element)
{
if (IsDesktopWindowsXamlSourcePresent())
{
return (WindowsXamlHostBase)element.GetValue(WrapperProperty);
}
return null;
}
public static void SetWrapper(this windows.UI.Xaml.UIElement element, WindowsXamlHostBase wrapper)
{
if (IsDesktopWindowsXamlSourcePresent())
{
element.SetValue(WrapperProperty, wrapper);
}
}
}
}
// 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 windows = Windows;
namespace Microsoft.Toolkit.Wpf.UI.XamlHost
{
/// <summary>
/// Extensions for use with UWP UIElement objects wrapped by the WindowsXamlHostBaseExt
/// </summary>
public static class UwpUIElementExtensions
{
private static bool IsDesktopWindowsXamlSourcePresent() => windows.Foundation.Metadata.ApiInformation.IsApiContractPresent("Windows.UI.Xaml.Hosting.HostingContract", 3);
private static windows.UI.Xaml.DependencyProperty WrapperProperty
{
get
{
if (IsDesktopWindowsXamlSourcePresent())
{
var result = windows.UI.Xaml.DependencyProperty.RegisterAttached("Wrapper", typeof(System.Windows.UIElement), typeof(UwpUIElementExtensions), new windows.UI.Xaml.PropertyMetadata(null));
return result;
}
throw new NotImplementedException();
}
}
public static WindowsXamlHostBase GetWrapper(this windows.UI.Xaml.UIElement element)
{
if (IsDesktopWindowsXamlSourcePresent())
{
return (WindowsXamlHostBase)element.GetValue(WrapperProperty);
}
return null;
}
public static void SetWrapper(this windows.UI.Xaml.UIElement element, WindowsXamlHostBase wrapper)
{
if (IsDesktopWindowsXamlSourcePresent())
{
element.SetValue(WrapperProperty, wrapper);
}
}
}
}

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

@ -0,0 +1,79 @@
// 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.ComponentModel;
using System.Runtime.InteropServices;
using System.Windows;
using Microsoft.Toolkit.Win32.UI.XamlHost;
using WUX = Windows.UI.Xaml;
namespace Microsoft.Toolkit.Wpf.UI.XamlHost
{
/// <summary>
/// WindowsXamlHost control hosts UWP XAML content inside the Windows Presentation Foundation
/// </summary>
partial class WindowsXamlHost : WindowsXamlHostBase
{
/// <summary>
/// Gets XAML Content by type name
/// </summary>
public static DependencyProperty InitialTypeNameProperty { get; } = DependencyProperty.Register("InitialTypeName", typeof(string), typeof(WindowsXamlHost));
/// <summary>
/// Gets or sets XAML Content by type name
/// </summary>
/// <example><code>XamlClassLibrary.MyUserControl</code></example>
/// <remarks>
/// Content creation is deferred until after the parent hwnd has been created.
/// </remarks>
[Browsable(true)]
[Category("XAML")]
public string InitialTypeName
{
get => (string)GetValue(InitialTypeNameProperty);
set => SetValue(InitialTypeNameProperty, value);
}
/// <summary>
/// Creates <see cref="WUX.Application" /> object, wrapped <see cref="WUX.Hosting.DesktopWindowXamlSource" /> instance; creates and
/// sets root UWP XAML element on DesktopWindowXamlSource.
/// </summary>
/// <param name="hwndParent">Parent window handle</param>
/// <returns>Handle to XAML window</returns>
protected override HandleRef BuildWindowCore(HandleRef hwndParent)
{
// Create and set initial root UWP XAML content
if (!string.IsNullOrEmpty(InitialTypeName) && Child == null)
{
Child = UWPTypeFactory.CreateXamlContentByType(InitialTypeName);
var frameworkElement = Child as WUX.FrameworkElement;
// Default to stretch : UWP XAML content will conform to the size of WindowsXamlHost
if (frameworkElement != null)
{
frameworkElement.HorizontalAlignment = WUX.HorizontalAlignment.Stretch;
frameworkElement.VerticalAlignment = WUX.VerticalAlignment.Stretch;
}
}
return base.BuildWindowCore(hwndParent);
}
/// <summary>
/// Set data context on <seealso cref="Child"/> when it has changed.
/// </summary>
protected override void OnChildChanged()
{
base.OnChildChanged();
var frameworkElement = ChildInternal as WUX.FrameworkElement;
if (frameworkElement != null)
{
// WindowsXamlHost DataContext should flow through to UWP XAML content
frameworkElement.DataContext = DataContext;
}
}
}
}

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

@ -0,0 +1,13 @@
// 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.
namespace Microsoft.Toolkit.Wpf.UI.XamlHost
{
/// <summary>
/// Defines assembly visibility for <seealso cref="WindowsXamlHost"/>
/// </summary>
public partial class WindowsXamlHost
{
}
}

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

@ -6,103 +6,25 @@ using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Windows;
using Microsoft.Toolkit.Win32.UI.XamlHost;
using windows = Windows;
using WUX = Windows.UI.Xaml;
namespace Microsoft.Toolkit.Wpf.UI.XamlHost
{
/// <summary>
/// WindowsXamlHost control hosts UWP XAML content inside the Windows Presentation Foundation
/// </summary>
public class WindowsXamlHost : WindowsXamlHostBase
partial class WindowsXamlHost : WindowsXamlHostBase
{
/// <summary>
/// Gets XAML Content by type name
/// </summary>
public static DependencyProperty InitialTypeNameProperty { get; } = DependencyProperty.Register("InitialTypeName", typeof(string), typeof(WindowsXamlHost));
/// <summary>
/// Gets or sets XAML Content by type name
/// </summary>
/// <example><code>XamlClassLibrary.MyUserControl</code></example>
/// <remarks>
/// Content creation is deferred until after the parent hwnd has been created.
/// </remarks>
[Browsable(true)]
[Category("XAML")]
public string InitialTypeName
{
get => (string)GetValue(InitialTypeNameProperty);
set => SetValue(InitialTypeNameProperty, value);
}
/// <summary>
/// Gets or sets the root UWP XAML element displayed in the WPF control instance.
/// </summary>
/// <remarks>This UWP XAML element is the root element of the wrapped DesktopWindowXamlSource.</remarks>
[Browsable(true)]
public windows.UI.Xaml.UIElement Child
public WUX.UIElement Child
{
get => ChildInternal;
set => ChildInternal = value;
}
/// <summary>
/// Creates <see cref="windows.UI.Xaml.Application" /> object, wrapped <see cref="windows.UI.Xaml.Hosting.DesktopWindowXamlSource" /> instance; creates and
/// sets root UWP XAML element on DesktopWindowXamlSource.
/// </summary>
/// <param name="hwndParent">Parent window handle</param>
/// <returns>Handle to XAML window</returns>
protected override HandleRef BuildWindowCore(HandleRef hwndParent)
{
// Create and set initial root UWP XAML content
if (!string.IsNullOrEmpty(InitialTypeName) && Child == null)
{
Child = UWPTypeFactory.CreateXamlContentByType(InitialTypeName);
var frameworkElement = Child as windows.UI.Xaml.FrameworkElement;
// Default to stretch : UWP XAML content will conform to the size of WindowsXamlHost
if (frameworkElement != null)
{
frameworkElement.HorizontalAlignment = windows.UI.Xaml.HorizontalAlignment.Stretch;
frameworkElement.VerticalAlignment = windows.UI.Xaml.VerticalAlignment.Stretch;
}
}
return base.BuildWindowCore(hwndParent);
}
/// <inheritdoc />
protected override void Dispose(bool disposing)
{
if (disposing && !IsDisposed)
{
if (Child is windows.UI.Xaml.FrameworkElement frameworkElement)
{
frameworkElement.SizeChanged -= XamlContentSizeChanged;
}
base.Dispose(disposing);
}
}
protected override System.IntPtr WndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled)
{
const int WM_GETOBJECT = 0x003D;
switch (msg)
{
// We don't want HwndHost to handle the WM_GETOBJECT.
// Instead we want to let the HwndIslandSite's WndProc get it
// So return handled = false and don't let the base class do
// anything on that message.
case WM_GETOBJECT:
handled = false;
return System.IntPtr.Zero;
}
return base.WndProc(hwnd, msg, wParam, lParam, ref handled);
}
}
}

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

@ -5,45 +5,47 @@
using System;
using System.Collections.Generic;
using System.Windows;
using windows = Windows;
using Microsoft.Toolkit.Win32.UI.XamlHost;
using WF = Windows.Foundation;
using WUX = Windows.UI.Xaml;
namespace Microsoft.Toolkit.Wpf.UI.XamlHost
{
/// <summary>
/// Focus and Keyboard handling for Focus integration with UWP XAML
/// </summary>
public partial class WindowsXamlHostBase
partial class WindowsXamlHostBase
{
/// <summary>
/// Dictionary that maps WPF (host framework) FocusNavigationDirection to UWP XAML XxamlSourceFocusNavigationReason
/// </summary>
private static readonly Dictionary<System.Windows.Input.FocusNavigationDirection, windows.UI.Xaml.Hosting.XamlSourceFocusNavigationReason>
private static readonly Dictionary<System.Windows.Input.FocusNavigationDirection, WUX.Hosting.XamlSourceFocusNavigationReason>
MapDirectionToReason =
new Dictionary<System.Windows.Input.FocusNavigationDirection, windows.UI.Xaml.Hosting.XamlSourceFocusNavigationReason>
new Dictionary<System.Windows.Input.FocusNavigationDirection, WUX.Hosting.XamlSourceFocusNavigationReason>
{
{ System.Windows.Input.FocusNavigationDirection.Next, windows.UI.Xaml.Hosting.XamlSourceFocusNavigationReason.First },
{ System.Windows.Input.FocusNavigationDirection.First, windows.UI.Xaml.Hosting.XamlSourceFocusNavigationReason.First },
{ System.Windows.Input.FocusNavigationDirection.Previous, windows.UI.Xaml.Hosting.XamlSourceFocusNavigationReason.Last },
{ System.Windows.Input.FocusNavigationDirection.Last, windows.UI.Xaml.Hosting.XamlSourceFocusNavigationReason.Last },
{ System.Windows.Input.FocusNavigationDirection.Up, windows.UI.Xaml.Hosting.XamlSourceFocusNavigationReason.Up },
{ System.Windows.Input.FocusNavigationDirection.Down, windows.UI.Xaml.Hosting.XamlSourceFocusNavigationReason.Down },
{ System.Windows.Input.FocusNavigationDirection.Left, windows.UI.Xaml.Hosting.XamlSourceFocusNavigationReason.Left },
{ System.Windows.Input.FocusNavigationDirection.Right, windows.UI.Xaml.Hosting.XamlSourceFocusNavigationReason.Right },
{ System.Windows.Input.FocusNavigationDirection.Next, WUX.Hosting.XamlSourceFocusNavigationReason.First },
{ System.Windows.Input.FocusNavigationDirection.First, WUX.Hosting.XamlSourceFocusNavigationReason.First },
{ System.Windows.Input.FocusNavigationDirection.Previous, WUX.Hosting.XamlSourceFocusNavigationReason.Last },
{ System.Windows.Input.FocusNavigationDirection.Last, WUX.Hosting.XamlSourceFocusNavigationReason.Last },
{ System.Windows.Input.FocusNavigationDirection.Up, WUX.Hosting.XamlSourceFocusNavigationReason.Up },
{ System.Windows.Input.FocusNavigationDirection.Down, WUX.Hosting.XamlSourceFocusNavigationReason.Down },
{ System.Windows.Input.FocusNavigationDirection.Left, WUX.Hosting.XamlSourceFocusNavigationReason.Left },
{ System.Windows.Input.FocusNavigationDirection.Right, WUX.Hosting.XamlSourceFocusNavigationReason.Right },
};
/// <summary>
/// Dictionary that maps UWP XAML XamlSourceFocusNavigationReason to WPF (host framework) FocusNavigationDirection
/// </summary>
private static readonly Dictionary<windows.UI.Xaml.Hosting.XamlSourceFocusNavigationReason, System.Windows.Input.FocusNavigationDirection>
private static readonly Dictionary<WUX.Hosting.XamlSourceFocusNavigationReason, System.Windows.Input.FocusNavigationDirection>
MapReasonToDirection =
new Dictionary<windows.UI.Xaml.Hosting.XamlSourceFocusNavigationReason, System.Windows.Input.FocusNavigationDirection>()
new Dictionary<WUX.Hosting.XamlSourceFocusNavigationReason, System.Windows.Input.FocusNavigationDirection>()
{
{ windows.UI.Xaml.Hosting.XamlSourceFocusNavigationReason.First, System.Windows.Input.FocusNavigationDirection.Next },
{ windows.UI.Xaml.Hosting.XamlSourceFocusNavigationReason.Last, System.Windows.Input.FocusNavigationDirection.Previous },
{ windows.UI.Xaml.Hosting.XamlSourceFocusNavigationReason.Up, System.Windows.Input.FocusNavigationDirection.Up },
{ windows.UI.Xaml.Hosting.XamlSourceFocusNavigationReason.Down, System.Windows.Input.FocusNavigationDirection.Down },
{ windows.UI.Xaml.Hosting.XamlSourceFocusNavigationReason.Left, System.Windows.Input.FocusNavigationDirection.Left },
{ windows.UI.Xaml.Hosting.XamlSourceFocusNavigationReason.Right, System.Windows.Input.FocusNavigationDirection.Right },
{ WUX.Hosting.XamlSourceFocusNavigationReason.First, System.Windows.Input.FocusNavigationDirection.Next },
{ WUX.Hosting.XamlSourceFocusNavigationReason.Last, System.Windows.Input.FocusNavigationDirection.Previous },
{ WUX.Hosting.XamlSourceFocusNavigationReason.Up, System.Windows.Input.FocusNavigationDirection.Up },
{ WUX.Hosting.XamlSourceFocusNavigationReason.Down, System.Windows.Input.FocusNavigationDirection.Down },
{ WUX.Hosting.XamlSourceFocusNavigationReason.Left, System.Windows.Input.FocusNavigationDirection.Left },
{ WUX.Hosting.XamlSourceFocusNavigationReason.Right, System.Windows.Input.FocusNavigationDirection.Right },
};
/// <summary>
@ -62,8 +64,8 @@ namespace Microsoft.Toolkit.Wpf.UI.XamlHost
if (!_xamlSource.HasFocus)
{
_xamlSource.NavigateFocus(
new windows.UI.Xaml.Hosting.XamlSourceFocusNavigationRequest(
windows.UI.Xaml.Hosting.XamlSourceFocusNavigationReason.Programmatic));
new WUX.Hosting.XamlSourceFocusNavigationRequest(
WUX.Hosting.XamlSourceFocusNavigationReason.Programmatic));
}
}
@ -74,6 +76,11 @@ namespace Microsoft.Toolkit.Wpf.UI.XamlHost
/// <returns>Did handle tab</returns>
protected override bool TabIntoCore(System.Windows.Input.TraversalRequest request)
{
if (_xamlSource.HasFocus && !_onTakeFocusRequested)
{
return false; // If we have focus already, then we dont need to NavigateFocus
}
// Bug 17544829: Focus is wrong if the previous element is in a different FocusScope than the WindowsXamlHost element.
var focusedElement = System.Windows.Input.FocusManager.GetFocusedElement(
System.Windows.Input.FocusManager.GetFocusScope(this)) as FrameworkElement;
@ -85,7 +92,7 @@ namespace Microsoft.Toolkit.Wpf.UI.XamlHost
_lastFocusRequest = Guid.NewGuid();
}
var sourceFocusNavigationRequest = new windows.UI.Xaml.Hosting.XamlSourceFocusNavigationRequest(reason, origin, _lastFocusRequest);
var sourceFocusNavigationRequest = new WUX.Hosting.XamlSourceFocusNavigationRequest(reason, origin, _lastFocusRequest);
try
{
var result = _xamlSource.NavigateFocus(sourceFocusNavigationRequest);
@ -106,9 +113,9 @@ namespace Microsoft.Toolkit.Wpf.UI.XamlHost
/// <param name="sibling1">base rectangle</param>
/// <param name="sibling2">second of pair to transform</param>
/// <returns>result of transformed rectangle</returns>
private static windows.Foundation.Rect BoundsRelativeTo(FrameworkElement sibling1, System.Windows.Media.Visual sibling2)
private static WF.Rect BoundsRelativeTo(FrameworkElement sibling1, System.Windows.Media.Visual sibling2)
{
windows.Foundation.Rect origin = default(windows.Foundation.Rect);
WF.Rect origin = default(WF.Rect);
if (sibling1 != null)
{
@ -131,30 +138,59 @@ namespace Microsoft.Toolkit.Wpf.UI.XamlHost
return origin;
}
private bool _onTakeFocusRequested = false;
/// <summary>
/// Handles the <see cref="windows.UI.Xaml.Hosting.DesktopWindowXamlSource.TakeFocusRequested" /> event.
/// Handles the <see cref="WUX.Hosting.DesktopWindowXamlSource.TakeFocusRequested" /> event.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="windows.UI.Xaml.Hosting.DesktopWindowXamlSourceTakeFocusRequestedEventArgs"/> instance containing the event data.</param>
private void OnTakeFocusRequested(object sender, windows.UI.Xaml.Hosting.DesktopWindowXamlSourceTakeFocusRequestedEventArgs e)
/// <param name="e">The <see cref="WUX.Hosting.DesktopWindowXamlSourceTakeFocusRequestedEventArgs"/> instance containing the event data.</param>
private void OnTakeFocusRequested(object sender, WUX.Hosting.DesktopWindowXamlSourceTakeFocusRequestedEventArgs e)
{
if (_lastFocusRequest == e.Request.CorrelationId)
{
// If we've arrived at this point, then focus is being move back to us
// therefore, we should complete the operation to avoid an infinite recursion
// by "Restoring" the focus back to us under a new correctationId
var newRequest = new windows.UI.Xaml.Hosting.XamlSourceFocusNavigationRequest(
windows.UI.Xaml.Hosting.XamlSourceFocusNavigationReason.Restore);
var newRequest = new WUX.Hosting.XamlSourceFocusNavigationRequest(
WUX.Hosting.XamlSourceFocusNavigationReason.Restore);
_xamlSource.NavigateFocus(newRequest);
}
else
{
// Last focus request is not initiated by us, so continue
_lastFocusRequest = e.Request.CorrelationId;
var direction = MapReasonToDirection[e.Request.Reason];
var request = new System.Windows.Input.TraversalRequest(direction);
MoveFocus(request);
_onTakeFocusRequested = true;
try
{
// Last focus request is not initiated by us, so continue
_lastFocusRequest = e.Request.CorrelationId;
var direction = MapReasonToDirection[e.Request.Reason];
var request = new System.Windows.Input.TraversalRequest(direction);
MoveFocus(request);
}
finally
{
_onTakeFocusRequested = false;
}
}
}
private void OnThreadFilterMessage(ref System.Windows.Interop.MSG msg, ref bool handled)
{
if (handled)
{
return;
}
var desktopWindowXamlSourceNative = _xamlSource.GetInterop<IDesktopWindowXamlSourceNative2>();
if (desktopWindowXamlSourceNative != null)
{
handled = desktopWindowXamlSourceNative.PreTranslateMessage(msg);
}
}
protected override bool HasFocusWithinCore()
{
return _xamlSource.HasFocus;
}
}
}

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

@ -5,13 +5,14 @@
using System;
using System.Windows;
using windows = Windows;
using WUX = Windows.UI.Xaml;
namespace Microsoft.Toolkit.Wpf.UI.XamlHost
{
/// <summary>
/// Integrates UWP XAML in to WPF's layout system
/// </summary>
public partial class WindowsXamlHostBase
partial class WindowsXamlHostBase
{
/// <summary>
/// Measures wrapped UWP XAML content using passed in size constraint
@ -22,7 +23,7 @@ namespace Microsoft.Toolkit.Wpf.UI.XamlHost
{
var desiredSize = new Size(0, 0);
if (_xamlSource.Content != null)
if (IsXamlContentLoaded())
{
_xamlSource.Content.Measure(new windows.Foundation.Size(constraint.Width, constraint.Height));
desiredSize.Width = _xamlSource.Content.DesiredSize.Width;
@ -42,7 +43,7 @@ namespace Microsoft.Toolkit.Wpf.UI.XamlHost
/// <returns>Size</returns>
protected override Size ArrangeOverride(Size finalSize)
{
if (_xamlSource.Content != null)
if (IsXamlContentLoaded())
{
// Arrange is required to support HorizontalAlignment and VerticalAlignment properties
// set to 'Stretch'. The UWP XAML content will be 0 in the stretch alignment direction
@ -54,12 +55,33 @@ namespace Microsoft.Toolkit.Wpf.UI.XamlHost
return base.ArrangeOverride(finalSize);
}
/// <summary>
/// Is the Xaml Content loaded and live?
/// </summary>
/// <returns>True if the Xaml content is properly loaded</returns>
private bool IsXamlContentLoaded()
{
if (_xamlSource.Content == null)
{
return false;
}
if (WUX.Media.VisualTreeHelper.GetParent(_xamlSource.Content) == null)
{
// If there's no parent to this content, it's not "live" or "loaded" in the tree yet.
// Performing a measure or arrange in this state may cause unexpected results.
return false;
}
return true;
}
/// <summary>
/// UWP XAML content size changed
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="windows.UI.Xaml.SizeChangedEventArgs"/> instance containing the event data.</param>
protected void XamlContentSizeChanged(object sender, windows.UI.Xaml.SizeChangedEventArgs e)
private void XamlContentSizeChanged(object sender, windows.UI.Xaml.SizeChangedEventArgs e)
{
InvalidateMeasure();
}

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

@ -0,0 +1,13 @@
// 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.
namespace Microsoft.Toolkit.Wpf.UI.XamlHost
{
/// <summary>
/// Defines assembly visibility for <seealso cref="WindowsXamlHostBase"/>
/// </summary>
public partial class WindowsXamlHostBase
{
}
}

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

@ -6,55 +6,44 @@ using System;
using System.Runtime.InteropServices;
using System.Windows.Interop;
using Microsoft.Toolkit.Win32.UI.XamlHost;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media;
using windows = Windows;
using WUX = Windows.UI.Xaml;
namespace Microsoft.Toolkit.Wpf.UI.XamlHost
{
/// <summary>
/// WindowsXamlHost control hosts UWP XAML content inside the Windows Presentation Foundation
/// </summary>
public abstract partial class WindowsXamlHostBase : HwndHost
abstract partial class WindowsXamlHostBase : HwndHost
{
/// <summary>
/// UWP XAML Application instance and root UWP XamlMetadataProvider. Custom implementation required to
/// probe at runtime for custom UWP XAML type information. This must be created before
/// creating any DesktopWindowXamlSource instances if custom UWP XAML types are required.
/// An instance of <seealso cref="IXamlMetadataContainer"/>. Required to
/// probe at runtime for custom UWP XAML type information.
/// This must be implemented by the instance of <seealso cref="WUX.Application"/>
/// </summary>
private readonly windows.UI.Xaml.Application _application;
/// <remarks>
/// <seealso cref="WUX.Application"/> object is required for loading custom control metadata. If a custom
/// Application object is not provided by the application, the host control will create an instance of <seealso cref="XamlApplication"/>.
/// Instantiation of the application object must occur before creating the DesktopWindowXamlSource instance.
/// If no Application object is created before DesktopWindowXamlSource is created, DestkopWindowXamlSource
/// will create an instance of <seealso cref="XamlApplication"/> that implements <seealso cref="IXamlMetadataContainer"/>.
/// </remarks>
private static readonly IXamlMetadataContainer _metadataContainer = XamlApplication.GetOrCreateXamlMetadataContainer();
/// <summary>
/// UWP XAML DesktopWindowXamlSource instance that hosts XAML content in a win32 application
/// </summary>
private readonly windows.UI.Xaml.Hosting.DesktopWindowXamlSource _xamlSource;
/// <summary>
/// A reference count on the UWP XAML framework is tied to WindowsXamlManager's
/// lifetime. UWP XAML is spun up on the first WindowsXamlManager creation and
/// deinitialized when the last instance of WindowsXamlManager is destroyed.
/// </summary>
private readonly windows.UI.Xaml.Hosting.WindowsXamlManager _windowsXamlManager;
private readonly WUX.Hosting.DesktopWindowXamlSource _xamlSource;
/// <summary>
/// Private field that backs ChildInternal property.
/// </summary>
private UIElement _childInternal;
private WUX.UIElement _childInternal;
/// <summary>
/// Fired when WindowsXamlHost root UWP XAML content has been updated
/// </summary>
public event EventHandler ChildChanged;
/// <summary>
/// When a window containing Xaml content moves, Xaml closes all open popups. We need the same behavior for Xaml
/// content in the DesktopWindowXamlSource. Since the DesktopWindowXamlSource itself is not notified when the WPF
/// Window moves, we attach handlers to the WPF Window's SizeChanged and LocationChanged events and use the Xaml
/// VisualTreeHelper API to close all open popups in an event handler. The WPF Window is not reachable until after
/// this control is created. This field tracks the WPF Window so we can detach the event handlers during cleanup.
/// </summary>
private System.Windows.Window _window;
/// <summary>
/// Initializes a new instance of the <see cref="WindowsXamlHostBase"/> class.
/// </summary>
@ -64,28 +53,11 @@ namespace Microsoft.Toolkit.Wpf.UI.XamlHost
/// </remarks>
public WindowsXamlHostBase()
{
// Windows.UI.Xaml.Application object is required for loading custom control metadata. If a custom
// Application object is not provided by the application, the host control will create one (XamlApplication).
// Instantiation of the application object must occur before creating the DesktopWindowXamlSource instance.
// If no Application object is created before DesktopWindowXamlSource is created, DesktopWindowXamlSource
// will create a generic Application object unable to load custom UWP XAML metadata.
Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication.GetOrCreateXamlApplicationInstance(ref _application);
// Create an instance of the WindowsXamlManager. This initializes and holds a
// reference on the UWP XAML DXamlCore and must be explicitly created before
// any UWP XAML types are programmatically created. If WindowsXamlManager has
// not been created before creating DesktopWindowXamlSource, DesktopWindowXaml source
// will create an instance of WindowsXamlManager internally. (Creation is explicit
// here to illustrate how to initialize UWP XAML before initializing the DesktopWindowXamlSource.)
_windowsXamlManager = windows.UI.Xaml.Hosting.WindowsXamlManager.InitializeForCurrentThread();
// Create DesktopWindowXamlSource, host for UWP XAML content
_xamlSource = new windows.UI.Xaml.Hosting.DesktopWindowXamlSource();
_xamlSource = new WUX.Hosting.DesktopWindowXamlSource();
// Hook DesktopWindowXamlSource OnTakeFocus event for Focus processing
_xamlSource.TakeFocusRequested += OnTakeFocusRequested;
Loaded += WindowsXamlHostBase_Loaded;
}
/// <summary>
@ -104,44 +76,13 @@ namespace Microsoft.Toolkit.Wpf.UI.XamlHost
}
/// <summary>
/// Attaches event handlers to Window.SizeChanged and Window.LocationChanged to close all popups opened by the
/// Xaml content inside the DesktopWindowXamlSource.
/// Gets the current instance of <seealso cref="XamlApplication"/>
/// </summary>
private void WindowsXamlHostBase_Loaded(object sender, System.Windows.RoutedEventArgs e)
protected static IXamlMetadataContainer MetadataContainer
{
if (_window == null)
get
{
_window = System.Windows.Window.GetWindow(this);
_window.LocationChanged += OnWindowLocationChanged;
}
}
/// <summary>
/// Close all popups opened by the Xaml content inside the DesktopWindowXamlSource.
/// </summary>
private void OnWindowLocationChanged(object sender, EventArgs e)
{
#pragma warning disable 8305 // Experimental API
XamlRoot xamlRoot = _childInternal.XamlRoot;
var openPopups = VisualTreeHelper.GetOpenPopupsForXamlRoot(xamlRoot);
foreach (windows.UI.Xaml.Controls.Primitives.Popup popup in openPopups)
{
// Toggle the CompositeMode property, which will force all windowed Popups
// to reposition themselves relative to the new position of the host window.
var compositeMode = popup.CompositeMode;
// Set CompositeMode to some value it currently isn't set to.
if (compositeMode == ElementCompositeMode.SourceOver)
{
popup.CompositeMode = ElementCompositeMode.MinBlend;
}
else
{
popup.CompositeMode = ElementCompositeMode.SourceOver;
}
// Restore CompositeMode to whatever it was originally set to.
popup.CompositeMode = compositeMode;
return _metadataContainer;
}
}
@ -154,17 +95,17 @@ namespace Microsoft.Toolkit.Wpf.UI.XamlHost
/// <param name="uwpProperty">the related DependencyProperty of the UWP control</param>
/// <param name="converter">a converter, if one's needed</param>
/// <param name="direction">indicates that the binding should be one or two directional. If one way, the Uwp control is only updated from the wrapper.</param>
public void Bind(string propertyName, System.Windows.DependencyProperty wpfProperty, windows.UI.Xaml.DependencyProperty uwpProperty, object converter = null, System.ComponentModel.BindingDirection direction = System.ComponentModel.BindingDirection.TwoWay)
public void Bind(string propertyName, System.Windows.DependencyProperty wpfProperty, WUX.DependencyProperty uwpProperty, object converter = null, System.ComponentModel.BindingDirection direction = System.ComponentModel.BindingDirection.TwoWay)
{
if (direction == System.ComponentModel.BindingDirection.TwoWay)
{
var binder = new windows.UI.Xaml.Data.Binding()
var binder = new WUX.Data.Binding()
{
Source = this,
Path = new windows.UI.Xaml.PropertyPath(propertyName),
Converter = (windows.UI.Xaml.Data.IValueConverter)converter
Path = new WUX.PropertyPath(propertyName),
Converter = (WUX.Data.IValueConverter)converter
};
windows.UI.Xaml.Data.BindingOperations.SetBinding(ChildInternal, uwpProperty, binder);
WUX.Data.BindingOperations.SetBinding(ChildInternal, uwpProperty, binder);
}
var rebinder = new System.Windows.Data.Binding()
@ -190,9 +131,9 @@ namespace Microsoft.Toolkit.Wpf.UI.XamlHost
/// <summary>
/// Gets or sets the root UWP XAML element displayed in the WPF control instance.
/// </summary>
/// <value>The <see cref="windows.UI.Xaml.UIElement"/> child.</value>
/// <remarks>This UWP XAML element is the root element of the wrapped <see cref="windows.UI.Xaml.Hosting.DesktopWindowXamlSource" />.</remarks>
protected windows.UI.Xaml.UIElement ChildInternal
/// <value>The <see cref="WUX.UIElement"/> child.</value>
/// <remarks>This UWP XAML element is the root element of the wrapped <see cref="WUX.Hosting.DesktopWindowXamlSource" />.</remarks>
protected WUX.UIElement ChildInternal
{
get
{
@ -206,7 +147,7 @@ namespace Microsoft.Toolkit.Wpf.UI.XamlHost
return;
}
var currentRoot = (windows.UI.Xaml.FrameworkElement)ChildInternal;
var currentRoot = (WUX.FrameworkElement)ChildInternal;
if (currentRoot != null)
{
currentRoot.SizeChanged -= XamlContentSizeChanged;
@ -215,22 +156,28 @@ namespace Microsoft.Toolkit.Wpf.UI.XamlHost
_childInternal = value;
SetContent();
var frameworkElement = ChildInternal as windows.UI.Xaml.FrameworkElement;
var frameworkElement = ChildInternal as WUX.FrameworkElement;
if (frameworkElement != null)
{
// If XAML content has changed, check XAML size
// to determine if WindowsXamlHost needs to re-run layout.
frameworkElement.SizeChanged += XamlContentSizeChanged;
// WindowsXamlHost DataContext should flow through to UWP XAML content
frameworkElement.DataContext = DataContext;
}
OnChildChanged();
// Fire updated event
ChildChanged?.Invoke(this, new EventArgs());
}
}
/// <summary>
/// Called when the property <seealso cref="ChildInternal"/> has changed.
/// </summary>
protected virtual void OnChildChanged()
{
}
/// <summary>
/// Exposes ChildInternal without exposing its actual Type.
/// </summary>
@ -241,23 +188,25 @@ namespace Microsoft.Toolkit.Wpf.UI.XamlHost
}
/// <summary>
/// Gets or sets a value indicating whether this wrapper control instance been disposed
/// Gets a value indicating whether this wrapper control instance been disposed
/// </summary>
protected bool IsDisposed { get; set; }
public bool IsDisposed { get; private set; }
/// <summary>
/// Creates <see cref="windows.UI.Xaml.Application" /> object, wrapped <see cref="windows.UI.Xaml.Hosting.DesktopWindowXamlSource" /> instance; creates and
/// sets root UWP XAML element on <see cref="windows.UI.Xaml.Hosting.DesktopWindowXamlSource" />.
/// Creates <see cref="WUX.Application" /> object, wrapped <see cref="WUX.Hosting.DesktopWindowXamlSource" /> instance; creates and
/// sets root UWP XAML element on <see cref="WUX.Hosting.DesktopWindowXamlSource" />.
/// </summary>
/// <param name="hwndParent">Parent window handle</param>
/// <returns>Handle to XAML window</returns>
protected override HandleRef BuildWindowCore(HandleRef hwndParent)
{
ComponentDispatcher.ThreadFilterMessage += this.OnThreadFilterMessage;
// 'EnableMouseInPointer' is called by the WindowsXamlManager during initialization. No need
// to call it directly here.
// Create DesktopWindowXamlSource instance
var desktopWindowXamlSourceNative = _xamlSource.GetInterop();
var desktopWindowXamlSourceNative = _xamlSource.GetInterop<IDesktopWindowXamlSourceNative>();
// Associate the window where UWP XAML will display content
desktopWindowXamlSourceNative.AttachToWindow(hwndParent.Handle);
@ -296,27 +245,52 @@ namespace Microsoft.Toolkit.Wpf.UI.XamlHost
/// <param name="disposing">Is disposing?</param>
protected override void Dispose(bool disposing)
{
if (disposing)
if (disposing && !this.IsDisposed)
{
ChildInternal = null;
if (_window != null)
var currentRoot = (WUX.FrameworkElement)ChildInternal;
if (currentRoot != null)
{
_window.LocationChanged -= OnWindowLocationChanged;
_window = null;
currentRoot.SizeChanged -= XamlContentSizeChanged;
}
// Required by CA2213: _xamlSource?.Dispose() is insufficient.
// Free any other managed objects here.
ComponentDispatcher.ThreadFilterMessage -= this.OnThreadFilterMessage;
ChildInternal = null;
if (_xamlSource != null)
{
_xamlSource.TakeFocusRequested -= OnTakeFocusRequested;
_xamlSource.Dispose();
}
}
// Free any unmanaged objects here.
if (_xamlSource != null && !this.IsDisposed)
{
_xamlSource.Dispose();
}
// BUGBUG: CoreInputSink cleanup is failing when explicitly disposing
// WindowsXamlManager. Add dispose call back when that bug is fixed in 19h1.
this.IsDisposed = true;
// Call base class implementation.
base.Dispose(disposing);
}
protected override System.IntPtr WndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled)
{
const int WM_GETOBJECT = 0x003D;
switch (msg)
{
// We don't want HwndHost to handle the WM_GETOBJECT.
// Instead we want to let the HwndIslandSite's WndProc get it
// So return handled = false and don't let the base class do
// anything on that message.
case WM_GETOBJECT:
handled = false;
return System.IntPtr.Zero;
}
return base.WndProc(hwnd, msg, wParam, lParam, ref handled);
}
}
}

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

@ -1,7 +1,7 @@
// 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.
// 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.
// Based on https://github.com/saikrishnav/testfxSTAext/blob/master/LICENSE
#if NETCOREAPP

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

@ -1,7 +1,7 @@
// 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.
// 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.
// This file is used by Code Analysis to maintain SuppressMessage
// attributes that are applied to this project.
// Project-level suppressions either have no target or are given

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

@ -1,8 +1,8 @@
$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
$globalJsonPath = Join-Path -Path $PSScriptRoot -ChildPath ..\global.json
$globalJson = Get-Content $globalJsonPath | ConvertFrom-Json
$dotnetinstall = Join-Path -Path $PSScriptRoot dotnet-install.ps1
Invoke-WebRequest 'https://dot.net/v1/dotnet-install.ps1' -OutFile $dotnetinstall;
$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
$globalJsonPath = Join-Path -Path $PSScriptRoot -ChildPath ..\global.json
$globalJson = Get-Content $globalJsonPath | ConvertFrom-Json
$dotnetinstall = Join-Path -Path $PSScriptRoot dotnet-install.ps1
Invoke-WebRequest 'https://dot.net/v1/dotnet-install.ps1' -OutFile $dotnetinstall;
& $dotnetinstall -Version $globalJson.sdk.version;

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

@ -5,7 +5,7 @@
"^refs/heads/dev$", // we release out of dev
"^refs/heads/rel/\\d+\\.\\d+\\.\\d+" // we also release branches starting with rel/N.N.N
],
"nugetPackageVersion":{
"nugetPackageVersion": {
"semVer": 2
},
"cloudBuild": {