Scenario
I have the following scenario (I've stripped it down to a sample application):
- A WPF application with a window (MainWindow) hosting a WinForms UserControl (UserControl1).
- The control is added dynamically in the code behind to a
WindowsFormsHost
- The control is added dynamically in the code behind to a
- UserControl1 has a button which opens a form (Form1)
- It uses
form1.Show(this)
.
- It uses
Problem is:
- Form1's
.Owner
property is null.- In the real application, some work is done involving the
.Owner
property which means I can't just ignore this problem. Ideally, of course, there wouldn't be any dependancy here. - In the real application, I don't have control over the WinForms side of this code. Our WPF application is hosting another team's WinForms control.
- Notes:
- When I use a WinForms host instead, the
.Owner
property is set correctly. - UserControl1 is hosted fine in all other ways -- in the real application everything else works fine, it's just that the form opened by the user control doesn't have a proper owner.
- When I use a WinForms host instead, the
- In the real application, some work is done involving the
I can understand why there's a problem here, but I'm hoping the answer to my next question might be 'yes'!
Is there anything I can do to get this to work by making changes on the WPF side of the equation?
Failing that, could anything be done on the WinForms side? (it's not beyond the realms of possibility that I could get some changes implemented there...)
Sample Code
Here's the code in my sample app. First the WPF side:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:my="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="700">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Button Name="btnAdd" Click="btnAdd_Click" Content="Add Winform"/>
<WindowsFormsHost Grid.Row="1" Name="host" ScrollViewer.CanContentScroll="False"/>
</Grid>
</Window>
public partial class MainWindow : Window
{
private WindowsFormsHost host;
public MainWindow()
{
InitializeComponent();
}
private void btnAdd_Click(object sender, RoutedEventArgs e)
{
UserControl1 uc1 = new UserControl1();
WindowsFormsHost.EnableWindowsFormsInterop();
this.host.Child = uc1;
}
}
And now the WinForms side...
UserControl1 is just a user control with a button and a label on it. Here's the code:
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form1 form1 = new Form1();
form1.Show(this);
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.label1.Text = "this: " + this + Environment.NewLine + "parent: " + this.Parent + Environment.NewLine + "toplevelcontrol: " + this.TopLevelControl;
}
}
Form1 is just an empty form.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
MessageBox.Show(" this: " + this + " owner: " + this.Owner);
}
}
The Owner
shown in the message box and the TopLevelControl
shown in the label are null
when hosted in WPF, but have a value when hosted in another WinForms application.
Further Investigation
I guess the problem here is that .Owner
is of type Form
and there's no instance of this type in the WPF application. It's hard to imagine what valid value that property could have in this scenario. It seems likely, therefore, that I need to get the code changed that's accessing the `.Owner' property in Form1.