user21603351
user21603351

Reputation:

Can't use WinUI 3 File Picker

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

Answers (2)

Andrew KeepCoding
Andrew KeepCoding

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

emoacht
emoacht

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

Related Questions