从WPF中托管的WinForms控件创建表单 - 未设置所有者

时间:2012-12-11 17:30:47

标签: c# wpf winforms winforms-interop

方案

我有以下场景(我已将其剥离为示例应用程序):

  • 具有托管WinForms UserControl( UserControl1 )的窗口( MainWindow )的WPF应用程序。
    • 控件在后面的代码中动态添加到WindowsFormsHost
  • UserControl1 有一个打开表单的按钮( Form1
    • 它使用form1.Show(this)

问题是:

  • Form1 .Owner属性为null。
    • 在实际应用程序中,有些工作涉及.Owner属性,这意味着我不能忽略这个问题。当然,理想情况下,这里不会有任何依赖。
    • 在实际应用程序中,我无法控制此代码的WinForms端。我们的WPF应用程序正在托管另一个团队的WinForms控件。
    • 注意:
      • 当我使用WinForms主机时,.Owner属性设置正确。
      • UserControl1 以其他所有方式托管 - 在实际应用程序中,其他一切正常,只是由用户控件打开的表单没有一个合适的主人。

我可以理解为什么这里有问题,但我希望我的下一个问题的答案可能是'是'!

通过在等式的WPF方面进行更改,我能做些什么来实现这个目标吗?

如果失败了,可以在WinForms端完成任何事情吗? (这可能超出我可以在那里实施一些变更的可能性......)

示例代码

以下是我的示例应用中的代码。首先是WPF方面:

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

    }
}

现在是WinForms方......

UserControl1 只是一个用户控件,上面有一个按钮和一个标签。这是代码:

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 只是一个空表格。

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        MessageBox.Show(" this: " + this + " owner: " + this.Owner);
    }
}

在WPF中托管时,消息框中显示的Owner和标签中显示的TopLevelControlnull,但在另一个WinForms应用程序中托管时具有值。

进一步调查

我想这里的问题是.Owner的类型为Form,并且WPF应用程序中没有此类型的实例。很难想象财产在这种情况下可能具有的有效价值。因此,似乎我需要更改代码,以便访问 Form1 中的`.Owner'属性。

1 个答案:

答案 0 :(得分:1)

<Window
  xmlns:my="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration" 
>

<my:WindowsFormsHost  Name="MapHost" ScrollViewer.CanContentScroll="False"  SizeChanged="MapHost_SizeChanged" />

MapControl继承System.Windows.Forms.Control

MapHost.Child = MapControl;