Reputation:
I'm trying to show a file picker in my Windows App SDK (WinUI 3) application. I'm making it in C#.
Here's my function to show the file picker:
private async Task<StorageFile> PickFileAsync()
{
var filePicker = new FileOpenPicker();
filePicker.ViewMode = PickerViewMode.Thumbnail;
filePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
filePicker.FileTypeFilter.Add(".jpg");
filePicker.FileTypeFilter.Add(".jpeg");
filePicker.FileTypeFilter.Add(".png");
var hwnd = this.XamlRoot.Content.XamlRoot.WindowId;
WinRT.Interop.InitializeWithWindow.Initialize(filePicker, hwnd);
StorageFile file = await filePicker.PickSingleFileAsync();
if (file != null)
{
// Application now has read/write access to the picked file
return file;
}
else
{
return null;
}
}
And this is how I call the function:
StorageFile pickedFile = await PickFileAsync();
Just in case it matters, I'm calling the function from another function which is defined as private
, async
, and void
.
By the way, I've put the PickFileAsync()
method in the .cs
code for one of my app's pages, since the page contains the menu which triggers the action.
There are very few articles showing this so I couldn't really do much research.
Upvotes: 3
Views: 2743
Reputation: 13666
Here's an example if you want to open the FileOpenPicker on a Page
.
First, make your MainWindow
accessible from your page. One way to do this is by make it public static
:
App.xaml.cs
using Microsoft.UI.Xaml;
namespace FilePickerExample;
public partial class App : Application
{
public App()
{
this.InitializeComponent();
}
public static Window? Window { get; private set; }
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
Window = new MainWindow();
Window.Activate();
}
}
and in your page:
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System;
using Windows.Storage;
using Windows.Storage.Pickers;
using WinRT.Interop;
namespace FilePickerExample;
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
FileOpenPicker fileOpenPicker = new()
{
ViewMode = PickerViewMode.Thumbnail,
FileTypeFilter = { ".jpg", ".jpeg", ".png", ".gif" },
};
nint windowHandle = WindowNative.GetWindowHandle(App.Window);
InitializeWithWindow.Initialize(fileOpenPicker, windowHandle);
StorageFile file = await fileOpenPicker.PickSingleFileAsync();
if (file != null)
{
// Do something with the file.
}
}
}
UPDATE
Note that the FileOpenPicker
DOES NOT WORK when the app is run as ADMINISTRATOR / ELEVATED. This is a known issue, and you can follow it in the GitHub repo here.
Upvotes: 4
Reputation: 3591
You need to use GetWindowHandle
method to get the window handle. https://learn.microsoft.com/en-us/windows/apps/develop/ui-input/retrieve-hwnd#winui-3-with-c
var filePicker = new FileOpenPicker();
...
var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
WinRT.Interop.InitializeWithWindow.Initialize(filePicker, hwnd);
StorageFile file = await filePicker.PickSingleFileAsync();
Upvotes: 2