WinUI3子页面创建FilePicker抛出异常及解决过程
问题:WinUI3子页面中获取窗口句柄导致文件选择器异常
从WinUI3 Gallery复制的文件选择器代码在MainWindow中运行正常,但在子页面执行相同操作时抛出异常。已知问题出在获取窗口句柄(HWND)上,但不知道如何解决。本人刚接触C#和WinUI3,几周前才完成第一个Hello World程序。
按钮点击事件代码
private async void PickAFileButton_Click(object sender, RoutedEventArgs e) { // 清除之前返回的文件名(如果存在) OutputTextBlock.Text = ""; // 创建文件选择器 var openPicker = new Windows.Storage.Pickers.FileOpenPicker(); // 获取当前WinUI 3窗口的句柄(HWND) var window = WindowHelper.GetWindowForElement(this); var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(window); // 使用窗口句柄初始化文件选择器 WinRT.Interop.InitializeWithWindow.Initialize(openPicker, hWnd); // 设置文件选择器选项 openPicker.ViewMode = PickerViewMode.Thumbnail; openPicker.FileTypeFilter.Add("*"); // 打开选择器让用户选择文件 var file = await openPicker.PickSingleFileAsync(); if (file != null) { PickAFileOutputTextBlock.Text = "选中文件: " + file.Name; } else { PickAFileOutputTextBlock.Text = "操作已取消。"; } }
WindowHelper.cs代码
//********************************************************* // // Copyright (c) Microsoft. All rights reserved. // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. // //********************************************************* using Microsoft.UI; using Microsoft.UI.Windowing; using Microsoft.UI.Xaml; using System; using System.Collections.Generic; using WinRT.Interop; namespace AppUIBasics.Helper { // 辅助类,用于查找包含任意UIElement的窗口(GetWindowForElement)。 // 为此,我们需要跟踪所有活动窗口。应用代码必须调用WindowHelper.CreateWindow // 而不是直接"new Window",这样我们才能跟踪所有相关窗口。未来平台API可能会原生支持此功能。 public class WindowHelper { static public Window CreateWindow() { Window newWindow = new Window(); TrackWindow(newWindow); return newWindow; } static public void TrackWindow(Window window) { window.Closed += (sender, args) => { _activeWindows.Remove(window); }; _activeWindows.Add(window); } static public AppWindow GetAppWindow(Window window) { IntPtr hWnd = WindowNative.GetWindowHandle(window); WindowId wndId = Win32Interop.GetWindowIdFromWindow(hWnd); return AppWindow.GetFromWindowId(wndId); } static public Window GetWindowForElement(UIElement element) { if (element.XamlRoot != null) { foreach (Window window in _activeWindows) { if (element.XamlRoot == window.Content.XamlRoot) { return window; } } } return null; } static public UIElement FindElementByName(UIElement element, string name) { if (element.XamlRoot != null && element.XamlRoot.Content != null) { var ele = (element.XamlRoot.Content as FrameworkElement).FindName(name); if (ele != null) { return ele as UIElement; } } return null; } static public List<Window> ActiveWindows { get { return _activeWindows; }} static private List<Window> _activeWindows = new List<Window>(); } }
更新
曾出现新错误,最终通过重建项目解决了该问题。
内容的提问来源于stack exchange,提问作者unsealed1051
相关产品推荐
相关产品推荐

