如何从 WPF 用户控件获取托管 WinForm 的实例?

How to get an instance of hosting WinForm from a WPF user control?

我有一个 WPF UserControl 托管在 WPF window 或 Windows 表单 Form 中。当用户按下"X"按钮关闭托管window/form时,我想抓取这个关闭事件,做一些操作。

为此,我订阅了 UserControl 的加载事件以获取托管 windows/form 实例并订阅其关闭事件。

它在 WPF window 上运行良好,但当我尝试对 Form 执行相同操作时,出现错误,无法继续。

WPFUsercontrol.xaml.cs

private void WpfUsercontrol_OnLoaded(object sender, RoutedEventArgs e)
{
    Window window = Window.GetWindow(this);
    if (window != null)
        window.Closing += window_closing;

    Form form = this.Parent as Form;    
    //Error: Cannot convert from System.Windows.DependencyObject to System.Windows.Forms.Form    
}

如何实现关闭 Form 的相同功能,就像我使用 WPF Window 一样?

您不能仅将 WPF UserControl 的父级转换为 System.Windows.Forms.Form,即使该控件托管在 Windows 表单 Form 中,因为托管不是那是微不足道的,需要额外的 "black magic".

相反,您必须先获取 HwndSource 并获取其 ElementHost 实例。这样,您就可以访问 TopLevelControl,这将是您正在寻找的 Form

var hwndSource = (HwndSource)PresentationSource.FromDependencyObject(this);
var host = (ElementHost)Control.FromChildHandle(hwndSource.Handle);
Form form = (Form)host.TopLevelControl;