【发布时间】:2017-10-18 17:52:26
【问题描述】:
我有一个托管在 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。
我的问题是:如何找到包含我的控件的窗口?
【问题讨论】:
-
Process.GetCurrentProcess().MainWindowHandle会不会有帮助? (您已将窗口类命名为“MainWindow”,但我不完全确定它是否真的是应用程序的主窗口...)请注意,通过获取本机窗口句柄,您只能收听本机 Windows 事件消息,而不是WPF 特定事件... -
不,那是用词不当;它不是主窗口。不过好想。我将更改问题以删除该详细信息。
-
该死,你真的把它弄复杂了 ;-) 现在我只能自发地想到其他三种可能性。 (1) 在适当的位置执行
new WindowInteropHelper(wpfWindow).Handle并将获得的句柄以某种方式传递给您的WinForms 控件。 (2) WinFormsAdapter 似乎是一个内部/未记录的类。但也许它有一些包含窗口句柄(或其他有用数据)的字段,您可以通过反射提取。 (3)使用WinAPIEnumChildWindows枚举你的进程的所有窗口句柄,并找出一种方法来识别你所追求的窗口句柄...... -
我赞成方法(1)或(3)(如果可行的话)。使用反射的方法(2)有些脆弱。不属于框架库的此类类的字段/方法可能会因以后的框架更新而以无法预料的方式发生变化,这可能会破坏程序的功能。
标签: c# wpf gdi windowsformshost