简而言之:我想在我的 WPF 应用程序中使用 UWP 中的一些元素。我的问题是 UWP 元素始终出现在所有其他 WPF UI 元素(例如按钮、矩形...)之上。
我无法分享原始示例,但我目前正在尝试使其与以下示例一起使用:https://github.com/microsoft/Windows.UI.Composition-Win32-Samples/tree/master/dotnet/ WPF/HelloComposition
在此示例中,有“CompositionHostControl”。 只是为了证明我可以在它前面放置一个 WPF UI 控件,我添加了一个矩形:
<local:CompositionHostControl x:Name="CompositionHostControl1"
Grid.Row="1" Grid.Column="1"
VerticalAlignment="Top"
Width="600" Height="500"
BorderBrush="LightGray" BorderThickness="3" Panel.ZIndex="1"/>
<Rectangle Fill="Aqua" Width="200" Height="200" Grid.Row="1" Grid.Column="1" Panel.ZIndex="2" />
根据我对“Panel.ZIndex”的理解,矩形应该位于 CompositionHostControl 的前面(=最上面)。
但是,这是行不通的。矩形始终呈现在 CompositionHostControl 后面。
我还查看了“CompositionHostControl.xaml.cs”,但找不到任何将此控件设置为最顶层的内容。
在“CompositionHost.cs”中,我将第 119 行更改为
interop.CreateDesktopWindowTarget(hwndHost, true, out raw);
到
interop.CreateDesktopWindowTarget(hwndHost, false, out raw);
因为第二个参数的名称为“isTopmost”。然而,这也没有效果。
我查看了https://learn.microsoft.com/en-us/windows/uwp/composition/visual-layer,对我来说,看起来应该可以更改 Z 顺序,但我做到了不知道该怎么做。
我还查看了https://mtaulty.com/2015/12/17/m_15996/,其中或多或少清楚地表明“我也可以结合上面的部分或全部1-4,以便允许不同的技术来发挥各自的优势 - 例如,我可能有一些 Direct3D 游戏位于 XAML 层提供的一组游戏控件之下。”
最后但并非最不重要的一点是,我一般都知道空域问题:https://learn.microsoft.com/en-us/previous-versions/dotnet/netframework-3.0/aa970688(v=vs.85 )?重定向自=MSDN 然而,我的理解是情况并非如此,因为一切都是基于视觉层的。
这个问题仍然是空域的问题,这种限制来自于在窗口管理器级别混合不同的技术,而不是 WPF 实现决策。
CompositionHostControl 本质上是一个 Win32 子窗口,您无法在其上绘制 WPF 内容。
建议使用
SetWindowRgn
来限制某些区域的绘制。比如上面要添加一个WPF Rectangle,可以使用CombineRgn
来获取一个有矩形孔的区域,这样就可以显示WPF的内容了。
protected override HandleRef BuildWindowCore(HandleRef hwndParent)
{
// Create Window
hwndHost = IntPtr.Zero;
hwndHost = CreateWindowEx(0, "static", "Win32Window",
WS_CHILD | WS_VISIBLE ,
0, 0,
hostWidth, hostHeight,
hwndParent.Handle,
(IntPtr)HOST_ID,
IntPtr.Zero,
0);
// Create Dispatcher Queue
dispatcherQueue = InitializeCoreDispatcher();
// Build Composition Tree of content
InitComposition(hwndHost);
var hrgn = CreateRectRgn(0, 0, hostWidth, hostHeight);
var wpfRgn = CreateRectRgn(300, 300, 200, 200);
var region = CreateRectRgn(0, 0, 0, 0);
CombineRgn(region, hrgn, wpfRgn, RGN_DIFF); //RGN_DIFF=4
int regionType = SetWindowRgn(hwndHost, region, true);
return new HandleRef(this, hwndHost);
}