WindowsFormsHost ZOrder

发布于 2024-09-15 22:24:30 字数 98 浏览 9 评论 0原文

看起来 WindowsFormsHost 控件被设置为显示在顶部。有没有办法更改其 z 顺序,以允许同一窗口上的其他 WPF 控件在 WindowsFormsHost 控件之上可见?

It appears WindowsFormsHost control is set to display on top. Is there any way to change its z-order to allow other WPF controls on the same window to be visible on top of the WindowsFormsHost control?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

天荒地未老 2024-09-22 22:24:30

不幸的是,不能,由于 winformshost 合成到 WPF 窗口的方式,它必须出现在顶部。

请参阅此处中的 z 顺序段落。

在 WPF 用户界面中,您可以将元素的 z 顺序更改为
控制重叠行为。绘制托管 Windows 窗体控件
在单独的 HWND 中,因此它始终绘制在 WPF 元素之上。

托管的 Windows 窗体控件也绘制在任何 Adorner 之上
元素。

Unfortunately no, because of the way the winformshost is composited into a WPF window it must appear on top.

See the z-order paragraph from here.

In a WPF user interface, you can change the z-order of elements to
control overlapping behavior. A hosted Windows Forms control is drawn
in a separate HWND, so it is always drawn on top of WPF elements.

A hosted Windows Forms control is also drawn on top of any Adorner
elements.

°如果伤别离去 2024-09-22 22:24:30

你可以做一个小技巧。当您声明 WindowsFormsHost 时,它的父组件是第一个 HWND 组件。通常它是根窗口。因此,控件的剪辑区域是整个窗口。我将展示一个使用 WPF ScrollViewer 的示例。

<Window>
    <Grid>
        <ScrollViewer Margin="20,50">
            <ItemsControl ItemsSource="{StaticResource StringArray}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <WindowsFormsHost>
                            <wf:Button />
                        </WindowsFormsHost>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </ScrollViewer>
    </Grid>
</Window>

在这种情况下,Button 将超出 ScrollViewer 范围。但是有一种方法可以创建“中间”HWND 项来剪辑 ScrollViewer 上的 WinForms 区域。只需将另一个 WindowsFormsHostElementHost 一起放置,如下所示:

<Grid>
    <WindowsFormsHost Margin="20,50">
        <ElementHost x:Name="This is a clip container">
            <ScrollViewer>
                <ItemsControl ItemsSource="{StaticResource StringArray}">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <WindowsFormsHost>
                                <wf:Button />
                            </WindowsFormsHost>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </ScrollViewer>
        </ElementHost>
    </WindowsFormsHost>
</Grid>

现在 Button 的剪辑区域是 ElementHostWinForms 按钮在滚动时将被其剪切。您还可以为 ContentContol 创建 ControlTemplate 并在需要时重用它。

<ControlTemplate x:Key="ClipContainer" TargetType="{x:Type ContentControl}">
    <WindowsFormsHost>
        <ElementHost>
            <ContentPresenter />
        </ElementHost>
    </WindowsFormsHost>
</ControlTemplate>
<Grid>
    <ContentControl Template="{StaticResource ClipContainer}" Margin="20,50">
        <ScrollViewer>
            <ItemsControl ItemsSource="{StaticResource StringArray}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <WindowsFormsHost>
                            <wf:Button />
                        </WindowsFormsHost>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </ScrollViewer>
    </ContentControl>
</Grid>

You can do a little trick. When you declare an WindowsFormsHost, it's parent is first HWND component. Usually it's root window. So, clip area for controls is whole window. I'll show an example with WPF ScrollViewer.

<Window>
    <Grid>
        <ScrollViewer Margin="20,50">
            <ItemsControl ItemsSource="{StaticResource StringArray}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <WindowsFormsHost>
                            <wf:Button />
                        </WindowsFormsHost>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </ScrollViewer>
    </Grid>
</Window>

In this case Buttons will be out of ScrollViewer bounds. But there's a way to create "intermediate" HWND item to clip WinForms area over ScrollViewer. Just place another WindowsFormsHost with ElementHost like below:

<Grid>
    <WindowsFormsHost Margin="20,50">
        <ElementHost x:Name="This is a clip container">
            <ScrollViewer>
                <ItemsControl ItemsSource="{StaticResource StringArray}">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <WindowsFormsHost>
                                <wf:Button />
                            </WindowsFormsHost>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </ScrollViewer>
        </ElementHost>
    </WindowsFormsHost>
</Grid>

Now clip area for Buttons is ElementHost and WinForms Buttons will be clipped by it on scrolling. Also you can create ControlTemplate for ContentContol and reuse it where you need it.

<ControlTemplate x:Key="ClipContainer" TargetType="{x:Type ContentControl}">
    <WindowsFormsHost>
        <ElementHost>
            <ContentPresenter />
        </ElementHost>
    </WindowsFormsHost>
</ControlTemplate>
<Grid>
    <ContentControl Template="{StaticResource ClipContainer}" Margin="20,50">
        <ScrollViewer>
            <ItemsControl ItemsSource="{StaticResource StringArray}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <WindowsFormsHost>
                            <wf:Button />
                        </WindowsFormsHost>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </ScrollViewer>
    </ContentControl>
</Grid>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文