1.概要
最近在迁移 GeneralUpdate.Tool的时候需要用到文件夹选择,在MAUI中可以使用FolderPicker进行选择。注意,和上篇文章的文件选择不一样。因为在.NET MAUI中目前还没有傻瓜式直接可用的FolderPicker供开发者使用所以需要自己动手做一些修改。
完整示例代码:https://gitee.com/Juster-zhu/GeneralUpdate/tree/master/src/c%23/GeneralUpdate.PacketTool
2.详细内容
实现步骤如下:
- 定义接口
public interface IFolderPickerService | |
{ | |
Task<string> PickFolderTaskAsync(); | |
} |
2.在每个受支持的平台上实现接口
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;
不可以删除因为加入了环境的判断会导致在编码时认为是无效应用,实际运行时会使用到该命名空间。
mauiAppBuilder.Services.AddTransient<IFolderPickerService, Platforms.Windows.FolderPicker>(); | |
mauiAppBuilder.Services.AddTransient<IFolderPickerService, Platforms.MacCatalyst.FolderPicker>(); | |
实际代码如下。
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) | |
{ | |
mauiAppBuilder.Services.AddTransient<IFolderPickerService, Platforms.Windows.FolderPicker>(); | |
mauiAppBuilder.Services.AddTransient<IFolderPickerService, Platforms.MacCatalyst.FolderPicker>(); | |
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; | |
} | |
} |
- 运行效果如下