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