Не могу использовать средство выбора файлов WinUI 3

Я пытаюсь показать средство выбора файлов в своем приложении Windows App SDK (WinUI 3). Я делаю это на С#.

Вот моя функция, чтобы показать средство выбора файлов:

        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;
            }
        }

И вот как я вызываю функцию:

            StorageFile pickedFile = await PickFileAsync();

На всякий случай, если это имеет значение, я вызываю функцию из другой функции, которая определяется как private, async и void.

Кстати, я поместил метод PickFileAsync() в код .cs для одной из страниц моего приложения, так как страница содержит меню, которое запускает действие.

Есть очень мало статей, показывающих это, поэтому я не мог провести много исследований.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
64
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вам нужно использовать метод GetWindowHandle, чтобы получить дескриптор окна. 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();

Это работает и для Page? Только что обновил свой вопрос.

Ben 09.06.2023 01:50

Когда я запускаю предоставленный вами код, Visual Studio выдает ошибку System.InvalidCastException: 'Specified cast is not valid.' и указывает на строку, определяющую переменную hwnd.

Ben 09.06.2023 01:52

Вам нужно пройти от Window до GetWindowHandle(). Вы можете сделать свой MainWindow доступным из App.xaml.cs следующим образом: public static Window? Window { get; private set; }.

Andrew KeepCoding 09.06.2023 02:44

@AndrewKeepCoding Как бы я тогда поместил это в качестве аргумента для вызова GetWindowHandle()? Я пробовал var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(Window);, но это не сработало.

Ben 09.06.2023 03:30

В App.xaml.cs задайте свойство Window при создании MainWindow. Поскольку Window является статическим свойством, вы можете получить MainWindow на своей странице следующим образом: nint windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(App.Window);

Andrew KeepCoding 09.06.2023 04:33

@AndrewKeepCoding Теперь я получаю эту ошибку: System.NullReferenceException: 'Object reference not set to an instance of an object.' из-за вызова GetWindowHandle().

Ben 09.06.2023 17:06

@AndrewKeepCoding Я пытался показать содержимое App.Window в уведомлении Toast, теперь оно выдает мне эту полезную ошибку: TexType_V2.App.Window.get returned null.. Итак, App.Window равно нулю?

Ben 09.06.2023 17:18

Вы установили Window в App.xaml.cs? Window = new MainWindow()

Andrew KeepCoding 10.06.2023 06:29

@AndrewKeepCoding Куда бы я поместил этот код?

Ben the Coder 10.06.2023 18:05

Опубликовал ответ. Надеюсь, поможет. Дайте мне знать, если у вас есть дополнительные вопросы.

Andrew KeepCoding 11.06.2023 04:49
Ответ принят как подходящий

Вот пример, если вы хотите открыть средство выбора файлов на Page.

Во-первых, сделайте свой MainWindow доступным со своей страницы. Один из способов сделать это — сделать это 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();
    }
}

и на вашей странице:

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.
        }
    }
}

Спасибо большое! Это работает отлично.

Ben 11.06.2023 17:41

Другие вопросы по теме