WinUI3使用FilePicker和FolderPicker
微软已经在2023年2月的社区电话会议上公布更新了WinUI 3 Gallery中的示例,如果你安装了WinUI 3 Gallery,可以点击FilePicker跳转。
但是微软示例的做法并不一定适合直接拿来用,尤其是在获取HWND这里,并没有解释存在的坑。如果官方示例不能成功运行可以参考我这篇博客,他们的原理是相同的。
桌面应用需要获取HWND
在基于桌面的应用程序(如WinUI3或WPF MSIX)中,FileOpenPicker
、FileSavePicker
和FolderPicker
API需要与它们关联的HWND,以便它们知道要在哪个窗口上显示。 这意味着,与UWP不同,您必须在使用FilePicker和FolderPicker之前添加几行额外的代码。
一般情况下,我们在UWP当中这样使用FileOpenPicker()
:
csharp
var filePicker = new FileOpenPicker();
filePicker.FileTypeFilter.Add("*");
var file = await filePicker.PickSingleFileAsync();
但是,对于桌面程序,必须添加两行以获取当前的HWND,并在Picker上设置HWND:
csharp
var filePicker = new FileOpenPicker();
// 通过传入Window对象获取当前窗口的HWND
var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
// 将HWND与文件选择器相关联
WinRT.Interop.InitializeWithWindow.Initialize(filePicker, hwnd);
// 像往常一样使用Picker
filePicker.FileTypeFilter.Add("*");
var file = await filePicker.PickSingleFileAsync();
如何在Page中使用Picker
获取一个HWND并设置给Picker很简单,但是问题在于上面这些都只适用于在MainWindow上使用。
然而,大多数应用程序都是在Page中实现逻辑,MainWindows只是一个没有任何逻辑实现的容器。
如何解决也很简单,我们只需要将:
csharp
GetWindowHandle(this)
替换为:
csharp
GetWindowHandle(App.m_window)
这里面的App.m_window
是在App.xaml.cs中定义的。但如果你在一个空白的WinUI3中这么用,VS会提示你App.m_window
有一定的保护级别,这是因为m_window
默认定义为:
csharp
private Window m_window;
我们需要将其修改为:
csharp
public static Window m_window;
static
是HWND调用所需。
参考资料
2、【WinUI 3】获取MainWindow、AppWindow、WindowHandle、WindowID实例_获取app.window的classname_XiaoLi8848的博客-CSDN博客