2011-06-08 27 views
3

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

如何检测何时/如果HwndSource可用?我打算使用如下代码获取参考:

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

回答

3

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

从MSDN网站:

“屏幕上的所有WPF元素由HWND最终支持当你创建一个WPF窗口,WPF创建一个顶级HWND,并使用HwndSource放窗口及其WPF内容在HWND中,应用程序中剩余的WPF内容共享单独的HWND,除了菜单,组合框下拉菜单和其他弹出窗口,这些元素创建了自己的顶级窗口,这就是为什么一个WPF菜单可能会经过包含它的窗口HWND的边缘。当你使用HwndHost在WPF中放置一个HWND时,WPF会通知Win32如何将新的子HWND相对于WPF窗口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(); 

在VB

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

我希望这有助于拉动。

+0

这是真实的,但在某些时候我的控制将被放置在由HWND支持屏幕的元素中,这就是我想检测。 – anthony 2011-06-09 00:13:02

+0

嗨。我希望上面的文字中的额外信息回答你的问题。祝你好运! – Rendition 2011-06-09 07:44:15

2

我一直使用Window.SourceInitialized事件来确定HWND(即HwndSource)何时可以使用。就你而言,你可能需要为OnVisualParentChanged方法添加覆盖。在您的覆盖中,搜索相关窗口的可视化树(或使用Window.GetWindow)。

如果窗口有一个有效的HWND,那么你可以直接使用它。如果没有,那么你必须订阅SourceInitialized事件。您可以从处理程序中的SourceInitialized中解除绑定,以确保只调用一次。

如果您的控件托管在Popup内,则这不起作用。在这种情况下,您必须获取相关Popup的引用并观察Opened事件。