Средство выбора папок .NET MAUI

Я хотел бы сделать приложение-загрузчик, которое сохраняет изображения в папку. Приложение должно работать на Windows и MacOS, а позже может появиться на Android и iOS.

Я не нашел способ выбрать целевую папку. Любая идея о том, как этого можно достичь с помощью приложения blazor или xaml .NET MAUI?

2 ответа

Я начал реализовывать это для Windows и macOS. Вы можете просмотреть код здесь: https://github.com/jfversluis/MauiFolderPickerSample , а также написать небольшую запись в блоге об этом здесь: https://blog.verslu.is/maui/folder-picker-with-dotnet- Мауи/

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

  • Определить интерфейс
  • Реализовать интерфейс на каждой поддерживаемой платформе
  • Потребляйте функциональность

Для этого я создал очень простой, но эффективный интерфейс

      public interface IFolderPicker
{
    Task<string> PickFolder();
}

Затем мы создаем реализацию для Windows, добавляя новый файл FilePicker.csк Platforms\Windows\папка. Это делает его специфичным для Windows и позволяет нам писать специфичный для Windows код. Файл содержит этот код:

      using WindowsFolderPicker = Windows.Storage.Pickers.FolderPicker;

namespace MauiFolderPickerSample.Platforms.Windows
{
    public class FolderPicker : IFolderPicker
    {
        public async Task<string> PickFolder()
        {
            var folderPicker = new WindowsFolderPicker();

            // Get the current window's HWND by passing in the Window object
            var hwnd = ((MauiWinUIWindow)App.Current.Windows[0].Handler.NativeView).WindowHandle;

            // Associate the HWND with the file picker
            WinRT.Interop.InitializeWithWindow.Initialize(folderPicker, hwnd);

            var result = await folderPicker.PickSingleFolderAsync();

            return result.Path;
        }
    }
}

Поскольку я выбрал здесь имя для своего собственного объекта, возникает конфликт имен с именем Windows. FolderPickerвот почему вверху есть такое странное использование. Если вы идете на MyFolderPickerкак имя вашего объекта, которое не понадобится.

Теперь мы регистрируем этот интерфейс и реализацию в универсальном хост-билдере в нашем MauiProgram.cs:

      public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            .ConfigureFonts(fonts =>
            {
                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
            });

// Note: this part was added

#if WINDOWS
        builder.Services.AddTransient<IFolderPicker, Platforms.Windows.FolderPicker>();
#elif MACCATALYST
        builder.Services.AddTransient<IFolderPicker, Platforms.MacCatalyst.FolderPicker>();
#endif
        builder.Services.AddTransient<MainPage>();
        builder.Services.AddTransient<App>();
// Note: end added part

        return builder.Build();
    }
}

Обратите внимание, что я также добавил MainPageа также Appздесь, чтобы наша инъекция конструктора работала (посмотрите на MainPage.xaml.csв связанном репозитории).

Теперь мы можем использовать нашу функциональность следующим образом:

      namespace MauiFolderPickerSample;

public partial class MainPage : ContentPage
{
    private readonly IFolderPicker _folderPicker;

    public MainPage(IFolderPicker folderPicker)
    {
        InitializeComponent();
        _folderPicker = folderPicker;
    }

    private async void OnPickFolderClicked(object sender, EventArgs e)
    {
        var pickedFolder = await _folderPicker.PickFolder();

        FolderLabel.Text = pickedFolder;

        SemanticScreenReader.Announce(FolderLabel.Text);
    }
}

Внедрение других платформ потребует от вас реализовать интерфейс для платформы, которую вы хотите поддерживать, и зарегистрировать ее в универсальном компоновщике хостов. Это должно помочь вам начать работу с Windows и macOS.

На самом деле вызов этого не должен отличаться между .NET MAUI (обычный) или .NET MAUI Blazor.

Хорошие новости: в .NET Maui теперь есть плагин выбора папок. Хорошо, пакет NuGet делает больше, чем просто выбирает папки, но это уже другой вопрос.

https://learn.microsoft.com/en-us/dotnet/communitytoolkit/maui/essentials/folder-picker?tabs=android

Набор инструментов сообщества .NET MAUI (CommunityToolkit.Maui в NuGet) предоставляет вам средство выбора папок, которое довольно легко использовать и настраивать.

iOS и Windows не требуют никаких разрешений, но Android нуждается, если у вас еще нет этой настройки. Откройте файл Platforms/Android/AndroidManifest.xml и добавьте в узел манифеста следующее:

      <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

Затем включите следующий код везде, где он вам нужен:

      async Task PickFolder(CancellationToken cancellationToken)
{
    var result = await FolderPicker.Default.PickAsync(cancellationToken);
    if (result.IsSuccessful)
    {
        await Toast.Make($"The folder was picked: Name - {result.Folder.Name}, Path - {result.Folder.Path}", ToastDuration.Long).Show(cancellationToken);
    }
    else
    {
        await Toast.Make($"The folder was not picked with error: {result.Exception.Message}").Show(cancellationToken);
    }
}

Или вы можете превратить это в событие нажатия кнопки, как я сделал:

      private async void PickFolder_Clicked(object sender, EventArgs e)
{
    CancellationTokenSource source = new();
    CancellationToken token = source.Token;
    var result = await FolderPicker.Default.PickAsync(token);
    
    if (result.IsSuccessful)
    {
        SaveLocation.Text = result.Folder.Path; // SaveLocation is a textbox in my XAML file
    }
}

Просто обязательно используйтеCommunityToolkitпакет дляFolderPicker, вместоWindowsбиблиотека VS 2022 заполняется автоматически.

      using CommunityToolkit.Maui.Storage;

Вам также потребуется добавить CommunityToolkit в свой стартовый класс.

      builder
    ...
    .UseMauiCommunityToolkit()

Пока что на Android он работает нормально, но ни на чем другом я его не проверял. ЮММВ.

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