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:
Коммит
1dbafae37f
|
@ -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": {
|
||||
|
|
Загрузка…
Ссылка в новой задаче