シナリオ
次のシナリオがあります (サンプル アプリケーションに落とし込みました)。
- WinForms UserControl ( UserControl1 ) をホストするウィンドウ ( MainWindow ) を持つ WPF アプリケーション。
- コントロールはコード ビハインドで動的に追加されます。
WindowsFormsHost
- コントロールはコード ビハインドで動的に追加されます。
- UserControl1には、フォームを開くボタンがあります ( Form1 )
- を使用しています
form1.Show(this)
。
- を使用しています
問題は次のとおりです。
- Form1の
.Owner
プロパティは null です。- 実際のアプリケーションでは、プロパティに関連するいくつかの作業が行われるため、
.Owner
この問題を無視することはできません。もちろん、理想的には、ここには依存関係がありません。 - 実際のアプリケーションでは、このコードの WinForms 側を制御することはできません。私たちの WPF アプリケーションは、別のチームの WinForms コントロールをホストしています。
- ノート:
- 代わりに WinForms ホストを使用すると、
.Owner
プロパティが正しく設定されます。 - UserControl1は、他のすべての方法で正常にホストされます。実際のアプリケーションでは、他のすべてが正常に機能します。ユーザー コントロールによって開かれたフォームに適切な所有者がいないだけです。
- 代わりに WinForms ホストを使用すると、
- 実際のアプリケーションでは、プロパティに関連するいくつかの作業が行われるため、
ここに問題がある理由は理解できますが、次の質問への答えが「はい」になることを願っています!
方程式の 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);
}
}
Owner
メッセージ ボックスに表示されるTopLevelControl
とラベルに表示される はnull
、WPF でホストされている場合ですが、別の WinForms アプリケーションでホストされている場合は値を持ちます。
さらなる調査
.Owner
ここでの問題は、それが型Form
であり、WPF アプリケーションにこの型のインスタンスがないことだと思います。このシナリオでそのプロパティが持つ有効な値を想像するのは困難です。したがって、 Form1の `.Owner' プロパティにアクセスしているコードを変更する必要があるようです。