c# - 从 WindowsFormsHost 中的 Windows 窗体控件获取 WPF 窗口

标签 c# wpf gdi windowsformshost

我有一个托管在 WindowsFormsHost 中的 Windows 窗体控件。这是我用来完成此任务的 XAML:

<Window x:Class="Forms.Address.MyWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Forms.Address"
        xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"  
        mc:Ignorable="d"
        Title="New Window" Height="500" Width="720">
    <Grid>
        <WindowsFormsHost x:Name="host">
            <local:MyFormsControl x:Name="genericName"/>
        </WindowsFormsHost>
    </Grid>
</Window>

我想监听 WindowsFormsHost 所在窗口的事件。这在 Windows 窗体中很简单,因为我可以使用 FindForm 方法来获取控件所在的窗体。但是出于显而易见的原因,当控件位于 WindowsFormsHost 内部时,FindForm 不起作用。我的控件的父级是 System.Windows.Forms.Integration.WinFormsAdapter ,其父级为 null。

我的问题是:如何找到包含我的控件的窗口?

最佳答案

感谢 elgonzo,他建议我使用反射来获取 WinFormsAdapter 类中的字段。这是我找到窗口的方法:

public static Window findParentWindow(Control control) {
    WindowsFormsHost host = findWPFHost(control);
    return Window.GetWindow(host);
}//FindParentWindow

private static WindowsFormsHost findWPFHost(Control control) {
    if (control.Parent != null)
        return findWPFHost(control.Parent);
    else {
        string typeName = "System.Windows.Forms.Integration.WinFormsAdapter";
        if (control.GetType().FullName == typeName) {
            Assembly adapterAssembly = control.GetType().Assembly;
            Type winFormsAdapterType = adapterAssembly.GetType(typeName);
            return (WindowsFormsHost)winFormsAdapterType.InvokeMember("_host", BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance, null, control, new string[0], null);

        } else
            throw new Exception("The top parent of a control within a host should be a System.Windows.Forms.Integration.WinFormsAdapter, but that is not what was found.  Someone should propably check this out.");
    }//if
}//FindWPFHost

我所做的是首先递归地找到 WinFormsAdapter,然后使用反射从中提取 _host 字段。这是 WPF WindowsFormsHost 对象,因此可以使用 Window.GetWindow(host) 找到它的窗口。

需要注意的是,如果使用 ElementHost 将 WindowsFormsHost 放置在 Windows 窗体中,则 GetWindow 将返回 null,因为没有窗口。

关于c# - 从 WindowsFormsHost 中的 Windows 窗体控件获取 WPF 窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44055831/

相关文章:

c# - 当我在组合框中返回 SelectedItem 时返回 System.Data.DataRowView

c# - 填充 ComboBox DataColumn 项和值

c# - 如何设置 WPF 窗口的宽度等于其标题栏中的内容?

当 AllowsTransparency ="True"时 wpf WindowsFormsHost 不可见

c - 是否有某种方法可以使 win32 GDI 调用以不同的方式解释坐标?

c++ GDI位图不想加载

c# - 无法识别 List<InterfaceType> 的扩展方法

c# - 从 FrameworkElementFactory 获取绑定(bind)

c++ - DXGI 文本输出轨迹

c# Convert.To Base64(String) 没有脉冲