开发者

WindowsFormsHost ZOrder

It appears Windo开发者_JS百科wsFormsHost 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?


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.


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>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜