Wpf:获取自定义控件的包含HwndSource

时间:2011-06-08 23:59:38

标签: .net wpf hwnd

我正在编写一个自定义的Wpf控件,我需要尽早获取对包含窗口的HwndSource的引用。如果可能的话,这将是1)在我的控制的构造函数中;或2)在控件添加到显示层次结构时。

如何检测HwndSource何时/是否可用?我计划使用以下代码获取引用:

var source = HwndSource.FromVisual(this) as HwndSource;

3 个答案:

答案 0 :(得分:4)

您可以使用PresentationSource的AddSourceChangedHandler方法监听PS何时更改(HwndSource是派生PS)。

http://msdn.microsoft.com/en-us/library/system.windows.presentationsource.addsourcechangedhandler.aspx

答案 1 :(得分:3)

据我所知,WPF控件不是windows。只有wpf应用程序中的窗口才有hwnd。

来自msdn网站:

“屏幕上的所有WPF元素最终都由HWND支持。当您创建WPF窗口时,WPF创建顶级HWND,并使用HwndSource将Window及其WPF内容放入HWND中应用程序中其余的WPF内容共享单个HWND。例外是菜单,组合框下拉菜单和其他弹出窗口。这些元素创建自己的顶级窗口,这就是为什么WPF菜单可能会去的原因超过包含它的窗口HWND的边缘。当你使用HwndHost在HWF中放置HWND时,WPF通知Win32如何相对于WPF窗口HWND定位新的子HWND。“

对于Win32互操作性,请参阅以下链接:

http://msdn.microsoft.com/en-us/library/ms742522.aspx

编辑:要增强答案以解决以下评论:

为了获得拥有hwnd的窗口的句柄,可以使用WindowInteropHelper类。

此示例也来自MSDN文档

在c#

WindowInteropHelper wih = new WindowInteropHelper(myDialog);
wih.Owner = ownerHwnd;
myDialog.ShowDialog();

in vb

Dim wih As New WindowInteropHelper(myDialog)
wih.Owner = ownerHwnd
myDialog.ShowDialog()

我希望这会有所帮助。

答案 2 :(得分:2)

我总是使用Window.SourceInitialized事件来确定HWND(即HwndSource)何时可以使用。在您的情况下,您可能需要为OnVisualParentChanged方法添加覆盖。在覆盖中,向上搜索关联窗口的可视树(或使用Window.GetWindow)。

如果Window具有有效的HWND,那么您可以按原样使用它。如果没有,那么您必须订阅SourceInitialized事件。您可以从处理程序中的SourceInitialized中取消挂钩,以确保只调用一次。

如果您的控件托管在Popup内,则无效。在这种情况下,您必须获得对相关Popup的引用并观察Opened事件。