从创建一个WinForms控件的窗体中承载WPF - 业主未设置 [英] Creating a form from a WinForms Control hosted within WPF -- Owner is not set

查看:133
本文介绍了从创建一个WinForms控件的窗体中承载WPF - 业主未设置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

场景



我有以下的情况下(我已经剥离下来到一个示例应用程序):




  • 一个WPF应用程序与窗口(主窗口)托管的WinForms用户控件(的UserControl1 )。

    • 控制动态代码添加后面一个 WindowsFormsHost


  • 的UserControl1 有打开一个表格( Form1中

      按钮
    • 它使用 form1.Show(本)




但问题是:




  • Form1中。业主属性为null。

    • 在实际应用中,有些工作就完成了涉及 .Owner 属性,这意味着我不能忽略这问题。理想情况下,当然也就不会在这里的任何依赖关系。

    • 在实际应用中,我没有在这个代码的WinForms侧控制。我们的WPF应用程序托管另一支球队的的WinForms控制

    • 注释:

      • 当我使用一个WinForms主机相反, .Owner 属性设置正确

      • 的UserControl1 托管在其他方面优良 - 在实际应用中一切做工精细,它只是形式通过的用户控件没有正确的所有者打开的





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



有什么我可以做的就是这通过在方程的WPF侧更改工作?



如果做不到这一点,可以在任何的WinForms的一侧做什么? (这并非不可能的境界,我可以得到实现有一些变化......)



示例代码



下面是我的示例应用程序的代码。首先是WPF的一面:



<预类=郎咸平的XML prettyprint-覆盖> <窗口x:类=WpfApplication1.MainWindow
的xmlns =http://schemas.microsoft.com/winfx/2006/xaml/presentation
的xmlns:我=CLR的命名空间:System.Windows.Forms.Integration;装配WindowsFormsIntegration程序=
的xmlns:X =http://schemas.microsoft.com/winfx/2006/xaml
标题=主窗口HEIGHT =350WIDTH =700>
<网格和GT;
< Grid.RowDefinitions>
< RowDefinition高度=自动/>
< RowDefinition />
< /Grid.RowDefinitions>
<按钮名称=btnAdd点击=btnAdd_ClickCONTENT =Winform中添加/>

< WindowsFormsHost Grid.Row =1NAME =主机ScrollViewer.CanContentScroll =FALSE/>
< /网格和GT;
< /窗GT;



<预类=郎-CS prettyprint-覆盖> 公共部分类主窗口:窗口
{
私人WindowsFormsHost主机;

公共主窗口()
{
的InitializeComponent();
}

私人无效btnAdd_Click(对象发件人,RoutedEventArgs E)
{
的UserControl1 UC1 =新的UserControl1();
WindowsFormsHost.EnableWindowsFormsInterop();
this.host.Child = UC1;

}
}

和现在的WinForms方..



的UserControl1 只是一个按钮,就可以了标签的用户控件。下面的代码:



<预类=郎-CS prettyprint-覆盖> 公共部分类的UserControl1:用户控件
{
公众的UserControl1()
{
的InitializeComponent();
}

私人无效的button1_Click(对象发件人,EventArgs五)
{
Form1的Form1中=新Form1的();
form1.Show(本);
}

保护覆盖无效的OnLoad(EventArgs的发送)
{
base.OnLoad(E);

this.label1.Text =这样的:这+ + + Environment.NewLine父母:+ this.Parent + Environment.NewLine +toplevelcontrol:+ this.TopLevelControl;
}
}



Form1中只是一个。空的形式



<预类=郎-CS prettyprint-覆盖> 公共部分Form1类:表格
{
公Form1的()
{
的InitializeComponent();
}

保护覆盖无效的OnLoad(EventArgs的发送)
{
base.OnLoad(E);

MessageBox.Show(这样的:这+ +店主:+ this.Owner);
}
}



所有者在消息框中显示的 TopLevelControl 标签中显示的是时,在WPF托管,但在另一个WinForms应用程序托管时的值。



进一步调查



我想这里的问题是, .Owner 的类型表格的,有没有这种类型的WPF应用程序的实例。很难想象有什么有效的值,属性可能在这种情况下。这很可能的,因此,我需要得到的代码改变了这一切的访问`.Owner'属性的 Form1中


解决方案

 <窗口
的xmlns:我=CLR的命名空间:System.Windows.Forms.Integration;装配WindowsFormsIntegration程序=
>

<我:WindowsFormsHost NAME =MapHostScrollViewer.CanContentScroll =FALSE时,SizeChanged =MapHost_SizeChanged/>



地图控件继承了System.Windows.Forms.Control的

  MapHost.Child =地图控件; 


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
  • UserControl1 has a button which opens a form (Form1)
    • It uses form1.Show(this).

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.

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.

解决方案

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

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

MapControl inherits System.Windows.Forms.Control

MapHost.Child = MapControl;

这篇关于从创建一个WinForms控件的窗体中承载WPF - 业主未设置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆