.NET MAUI实战 FolderPicker

1.概要

最近在迁移 GeneralUpdate.Tool的时候需要用到文件夹选择,在MAUI中可以使用FolderPicker进行选择。注意,和上篇文章的文件选择不一样。因为在.NET MAUI中目前还没有傻瓜式直接可用的FolderPicker供开发者使用所以需要自己动手做一些修改。

完整示例代码:https://gitee.com/Juster-zhu/GeneralUpdate/tree/master/src/c%23/GeneralUpdate.PacketTool.

2.详细内容

实现步骤如下:

  1. 定义接口

.NET MAUI实战 FolderPicker

   public interface IFolderPickerService
  {
       Task<string> PickFolderTaskAsync();
  }

2.在每个受支持的平台上实现接口

.NET MAUI实战 FolderPicker

using GeneralUpdate.Infrastructure.DataServices.Pick;
using WindowsFolderPicker = Windows.Storage.Pickers.FolderPicker;
namespace GeneralUpdate.PacketTool.Platforms.Windows
{
   public class FolderPicker : IFolderPickerService
  {
       public async Task<string> PickFolderTaskAsync()
      {
           var folderPicker = new WindowsFolderPicker();
           // Might be needed to make it work on Windows 10
           folderPicker.FileTypeFilter.Add("*");

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

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

           var result = await folderPicker.PickSingleFolderAsync();

           return result?.Path;
      }
  }
}

3.向.NET MAUI框架容器中注入FolderPicker注册实现

一定需要记住下面代码中的这个using引用。

using GeneralUpdate.Infrastructure.DataServices.Pick;

不可以删除因为加入了环境的判断会导致在编码时认为是无效应用,实际运行时会使用到该命名空间。

#if WINDOWS
mauiAppBuilder.Services.AddTransient<IFolderPickerService, Platforms.Windows.FolderPicker>();
#elif MACCATALYST
mauiAppBuilder.Services.AddTransient<IFolderPickerService, Platforms.MacCatalyst.FolderPicker>();
#endif

实际代码如下。

using GeneralUpdate.Infrastructure.DataServices.Pick;
using GeneralUpdate.PacketTool.ViewModels;
namespace GeneralUpdate.PacketTool
{
   public static class MauiProgram
  {
       public static MauiApp CreateMauiApp()
      {
           var builder = MauiApp.CreateBuilder();
           builder
              .UseMauiApp<App>()
              .RegisterViewModels()
              .RegisterView()
              .RegisterAppServices()
              .RegisterOther()
              .ConfigureFonts(fonts =>
              {
                   fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                   fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
              });
           return builder.Build();
      }

       public static MauiAppBuilder RegisterOther(this MauiAppBuilder mauiAppBuilder)
      {
           mauiAppBuilder.Services.AddTransient<App>();
           return mauiAppBuilder;
      }

       public static MauiAppBuilder RegisterView(this MauiAppBuilder mauiAppBuilder)
      {
           mauiAppBuilder.Services.AddTransient<MainPage>();
           return mauiAppBuilder;
      }

       public static MauiAppBuilder RegisterViewModels(this MauiAppBuilder mauiAppBuilder)
      {
           mauiAppBuilder.Services.AddTransient<MainViewModel>();
           return mauiAppBuilder;
      }

       public static MauiAppBuilder RegisterAppServices(this MauiAppBuilder mauiAppBuilder)
      {
#if WINDOWS
mauiAppBuilder.Services.AddTransient<IFolderPickerService, Platforms.Windows.FolderPicker>();
#elif MACCATALYST
mauiAppBuilder.Services.AddTransient<IFolderPickerService, Platforms.MacCatalyst.FolderPicker>();
#endif
           return mauiAppBuilder;
      }
  }
}

4.使用功能

  • 如何使用

将我们刚刚在容器中注入好的FolderPickerService取出来,并初始化ViewModel中的引用。

   public class MainViewModel : ViewModeBase
  {
       //code...

       public MainViewModel(IFolderPickerService folderPickerService)
      {
           _folderPickerService = folderPickerService;
      }

       //code...
    }

FolderPickerService调用。

       /// <summary>
       /// Choose a path
       /// </summary>
       /// <param name="value"></param>
       private async Task SelectFolderAction(string value)
      {
           var pickerResult = await _folderPickerService.PickFolderTaskAsync();
           if (pickerResult == null)
          {
               await Shell.Current.DisplayAlert("Pick options", "No results were selected !", "ok");
               return;
          }
           switch (value)
          {
               case "Source":
                   SourcePath = pickerResult;
                   break;
               case "Target":
                   TargetPath = pickerResult;
                   break;
               case "Patch":
                   PatchPath = pickerResult;
                   break;
          }
      }

 

  • 运行效果如下

.NET MAUI实战 FolderPicker