Void
Void

Reputation: 109

WindowsFormsHost ZOrder

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?

Upvotes: 6

Views: 3295

Answers (2)

ds1709
ds1709

Reputation: 199

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>

Upvotes: 0

Martin Harris
Martin Harris

Reputation: 28617

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.

Upvotes: 8

Related Questions