Wpf: получение содержащего HwndSource пользовательского элемента управления - PullRequest
3 голосов
/ 09 июня 2011

Я пишу пользовательский элемент управления Wpf, и мне нужно как можно раньше получить ссылку на HwndSource содержащего окна.Это будет 1) в конструкторе моего элемента управления, если это возможно, или 2) в момент добавления элемента управления в иерархию отображения.

Как я могу определить, когда / если HwndSource доступен?Я планирую приобрести ссылку, используя следующий код:

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

Ответы [ 3 ]

4 голосов
/ 10 июня 2011

Вы можете использовать метод AddSourceChangedHandler PresentationSource для прослушивания изменений PS (HwndSource является производным PS).

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

3 голосов
/ 09 июня 2011

Насколько я понимаю, элементы управления WPF не являются окнами.Только окно в приложении wpf имеет hwnd.

С сайта msdn:

"Все элементы WPF на экране в конечном итоге поддерживаются HWND. При создании WPFWindow, WPF создает HWND верхнего уровня и использует HwndSource для помещения окна и его содержимого WPF в HWND. Остальная часть содержимого WPF в приложении разделяет этот HWND. Исключением являются меню, раскрывающиеся списки со списком,и другие всплывающие окна. Эти элементы создают свое собственное окно верхнего уровня, поэтому меню WPF потенциально может пройти за край окна HWND, в котором оно находится. Когда вы используете HwndHost для помещения HWND в WPF, WPF сообщает Win32как расположить новый дочерний HWND относительно окна WPF HWND. "

Для взаимодействия Win32 см. следующую ссылку:

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

Редактировать: КомуРасширьте ответ, ответив на комментарий ниже:

Чтобы получить дескриптор окна, которому принадлежит hwnd, вы можете использовать класс WindowInteropHelper.

Tего пример также взят из документации MSDN

в c #

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

в vb

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

Надеюсь, это поможет.

2 голосов
/ 09 июня 2011

Я всегда использовал событие Window.SourceInitialized , чтобы определить, когда HWND (то есть HwndSource) готов к использованию.В вашем случае вам, вероятно, потребуется добавить переопределение для метода OnVisualParentChanged .В вашем переопределении ищите визуальное дерево для связанного Окна (или используйте Window.GetWindow ).

Если Окно имеет допустимый HWND, то вы можете просто использовать его как есть,Если нет, то вам придется подписаться на событие SourceInitialized.Вы можете отсоединиться от SourceInitialized в вашем обработчике, чтобы убедиться, что он вызывается только один раз.

Это не будет работать, если ваш элемент управления находится внутри Popup .В этом случае вам нужно получить ссылку на соответствующее всплывающее окно и посмотреть событие Opened .

...