2011-06-08 26 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事件。