如何在WinUI 3的C++/WinRT中获取承载UIElement的Window实例
在WinUI 3 C++/WinRT中获取承载UIElement的Window实例
可以通过两种可靠方法实现需求:
方法一:结合视觉树遍历与Window内容匹配
WinUI 3的Window不属于视觉树节点,所以直接用VisualTreeHelper.GetParent无法直接找到它。但每个Window的Content是其视觉树的根元素,因此可以遍历目标UIElement的父节点,同时匹配所有已打开Window的Content,找到对应实例:
winrt::Microsoft::UI::Xaml::Window GetWindowForElement(winrt::Microsoft::UI::Xaml::UIElement const& element) { auto currentElement = element; while (currentElement) { // 遍历应用所有已打开的Window for (auto const& window : winrt::Microsoft::UI::Xaml::Window::All()) { if (window.Content() == currentElement) { return window; } } // 向上遍历父元素 currentElement = winrt::Microsoft::UI::Xaml::Media::VisualTreeHelper::GetParent(currentElement).try_as<winrt::Microsoft::UI::Xaml::UIElement>(); } return nullptr; }
方法二:利用XamlRoot属性简化匹配
WinUI 3的UIElement自带XamlRoot属性,其Content对应所属Window的根内容元素,结合Window.All()遍历即可快速匹配:
winrt::Microsoft::UI::Xaml::Window GetWindowForElement(winrt::Microsoft::UI::Xaml::UIElement const& element) { if (auto xamlRoot = element.XamlRoot()) { auto rootContent = xamlRoot.Content().try_as<winrt::Microsoft::UI::Xaml::UIElement>(); for (auto const& window : winrt::Microsoft::UI::Xaml::Window::All()) { if (window.Content() == rootContent) { return window; } } } return nullptr; }
注意事项
- 确保目标
UIElement已加载到视觉树中,此时XamlRoot才会有有效值; Window.All()会返回应用当前所有已打开的窗口,遍历匹配的效率在窗口数量较少时可以忽略。
内容的提问来源于stack exchange,提问作者ridilculous
相关产品推荐
相关产品推荐

