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

3

我正在编写一个自定义的Wpf控件,需要尽早地获取包含窗口的HwndSource引用。如果可能的话,这应该在我的控件构造函数中完成;或者在控件添加到显示层次结构的时候完成。

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

var source = HwndSource.FromVisual(this) as HwndSource;
3个回答

4

3
据我所知,WPF控件不是窗口。只有wpf应用程序中的窗口具有hwnd。
从msdn网站上可以看到:
“屏幕上的所有WPF元素最终都由HWND支持。当您创建一个WPF窗口时,WPF会创建一个顶级HWND,并使用HwndSource将窗口及其WPF内容放置在HWND内。应用程序中的其他WPF内容共享该唯一的HWND。一个例外是菜单、组合框下拉列表和其他弹出窗口。这些元素会创建自己的顶级窗口,这就是为什么WPF菜单可能会超过包含它的窗口HWND边缘的原因。当您使用HwndHost将HWND放置在WPF内部时,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();

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

希望这能帮到你。


这是正确的,但在某些时候,我的控件将被放置在屏幕上由HWND支持的元素中,这就是我试图检测的内容。 - anthony
嗨。我希望上面的附加信息能回答你的问题。祝你好运! - Rendition

2
我一直使用Window.SourceInitialized事件来确定HWND(即HwndSource)何时准备好供使用。在您的情况下,您可能需要添加一个OnVisualParentChanged方法的重写。在您的重写中,向上搜索可视树以查找关联的窗口(或使用Window.GetWindow)。
如果窗口有有效的HWND,则可以直接使用它。如果没有,则必须订阅SourceInitialized事件。您可以在处理程序中取消对SourceInitialized的挂钩,以确保它只被调用一次。
如果你的控件托管在弹出窗口内,那么这种方法就行不通了。在这种情况下,你需要获取关联弹出窗口的引用并监听打开事件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接