Я пытаюсь показать средство выбора файлов в своем приложении 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 для одной из страниц моего приложения, так как страница содержит меню, которое запускает действие.
Есть очень мало статей, показывающих это, поэтому я не мог провести много исследований.





Вам нужно использовать метод 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();
Когда я запускаю предоставленный вами код, Visual Studio выдает ошибку System.InvalidCastException: 'Specified cast is not valid.' и указывает на строку, определяющую переменную hwnd.
Вам нужно пройти от Window до GetWindowHandle(). Вы можете сделать свой MainWindow доступным из App.xaml.cs следующим образом: public static Window? Window { get; private set; }.
@AndrewKeepCoding Как бы я тогда поместил это в качестве аргумента для вызова GetWindowHandle()? Я пробовал var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(Window);, но это не сработало.
В App.xaml.cs задайте свойство Window при создании MainWindow. Поскольку Window является статическим свойством, вы можете получить MainWindow на своей странице следующим образом: nint windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(App.Window);
@AndrewKeepCoding Теперь я получаю эту ошибку: System.NullReferenceException: 'Object reference not set to an instance of an object.' из-за вызова GetWindowHandle().
@AndrewKeepCoding Я пытался показать содержимое App.Window в уведомлении Toast, теперь оно выдает мне эту полезную ошибку: TexType_V2.App.Window.get returned null.. Итак, App.Window равно нулю?
Вы установили Window в App.xaml.cs? Window = new MainWindow()
@AndrewKeepCoding Куда бы я поместил этот код?
Опубликовал ответ. Надеюсь, поможет. Дайте мне знать, если у вас есть дополнительные вопросы.
Вот пример, если вы хотите открыть средство выбора файлов на 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.
}
}
}
Спасибо большое! Это работает отлично.
Это работает и для
Page? Только что обновил свой вопрос.