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?
-
You may want to try embedding the usercontrols inside a "Popup." This is a little late, but I was having a similar issue. If you want details on how to code it up, [this answer](http://stackoverflow.com/a/11348291/865883) might be useful. Not sure if you're still working on your project after 2 years though.. – funseiki Jul 05 '12 at 17:17
2 Answers
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.

- 28,277
- 7
- 90
- 101
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 Button
s 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 Button
s is ElementHost
and WinForms
Button
s 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>

- 189
- 3
- 11