mcpField
D
dotnet-maui-development

dotnet-maui-development

github.com/wshaddix开发8690 次安装35 周前更新
代码仓库

关于 dotnet-maui-development

为使用 C# 和 XAML 构建跨平台应用的开发者提供 .NET MAUI 开发指导,涵盖项目结构、MVVM、平台服务、Hot Reload、迁移选择及 .NET 11 变化。

主要功能

  1. 01单项目多目标结构
  2. 02结合 MVVM 的 XAML 数据绑定
  3. 03Shell 导航与依赖注入
  4. 04平台专属服务模式
  5. 05Hot Reload 指导与注意事项
  6. 06迁移选择及 .NET 11 说明

适用场景

  1. 01规划多平台 MAUI 项目结构
  2. 02使用 XAML 和 ViewModel 实现共享界面
  3. 03为 MAUI 应用添加平台专属服务
  4. 04评估 MAUI 的适用性和迁移方案

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/wshaddix/dotnet-skills --skill dotnet-maui-development

安装后在 Claude Code 中输入/dotnet-maui-development确认已加载。

详细介绍

dotnet-maui-development

.NET MAUI 跨平台开发:采用平台文件夹的单项目结构、使用 MVVM(CommunityToolkit.Mvvm)的 XAML 数据绑定、Shell 导航、通过分部类和条件编译实现的平台服务、依赖注入、各平台上的 Hot Reload,以及 .NET 11 改进(XAML 源生成、Android 上的 CoreCLR、dotnet run 设备选择)。包含客观的当前状态评估和迁移选项。

**版本假设:**以 .NET 8.0+ 为基准(MAUI 随 .NET 8+ 一起提供)。明确标注 .NET 11 Preview 1 的内容。示例使用最新的稳定 API。

**范围界定:**此技能涵盖 MAUI 项目结构、XAML/MVVM 模式、平台服务、当前状态评估、迁移选项和 .NET 11 改进。iOS/Mac Catalyst 上的 MAUI Native AOT 由 [skill:dotnet-maui-aot] 负责。

**不在范围内:**MAUI 测试(Appium、XHarness、平台特定测试)——请参阅 [skill:dotnet-maui-testing]。通用 Native AOT 模式——请参阅 [skill:dotnet-native-aot]。UI 框架选择决策树——请参阅 [skill:dotnet-ui-chooser]。

交叉引用:[skill:dotnet-maui-aot](iOS/Mac Catalyst 上的 Native AOT)、[skill:dotnet-maui-testing](测试模式)、[skill:dotnet-version-detection](TFM 检测)、[skill:dotnet-native-aot](通用 AOT 模式)、[skill:dotnet-ui-chooser](框架选择)、[skill:dotnet-accessibility](无障碍模式,如 SemanticProperties、屏幕阅读器)。


项目结构

MAUI 使用单项目架构。一个 .csproj 通过多目标设定面向所有平台,平台特定代码则放在平台文件夹中。


<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>net8.0-android;net8.0-ios;net8.0-maccatalyst</TargetFrameworks>
    <TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">
      $(TargetFrameworks);net8.0-windows10.0.19041.0
    </TargetFrameworks>
    <OutputType>Exe</OutputType>
    <UseMaui>true</UseMaui>
    <SingleProject>true</SingleProject>
    <RootNamespace>MyApp</RootNamespace>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="CommunityToolkit.Mvvm" Version="8.*" />
    <PackageReference Include="CommunityToolkit.Maui" Version="9.*" />
  </ItemGroup>
</Project>
项目布局
MyApp/
  MyApp/
    App.xaml / App.xaml.cs            # Application entry, resource dictionaries
    AppShell.xaml / AppShell.xaml.cs  # Shell navigation definition
    MauiProgram.cs                   # Host builder, DI, service registration
    MainPage.xaml / MainPage.xaml.cs  # Initial page
    ViewModels/                      # MVVM ViewModels
    Views/                           # XAML pages
    Models/                          # Data models
    Services/                        # Service interfaces and implementations
    Resources/
      Fonts/                         # Custom fonts (.ttf/.otf)
      Images/                        # SVG/PNG images (auto-resized per platform)
      Styles/                        # Shared styles, colors, resource dictionaries
      Raw/                           # Raw assets (JSON, etc.)
      Splash/                        # Splash screen image
    Platforms/
      Android/                       # AndroidManifest.xml, MainActivity.cs
      iOS/                           # Info.plist, AppDelegate.cs
      MacCatalyst/                   # Info.plist, AppDelegate.cs
      Windows/                       # Package.appxmanifest, App.xaml
    Properties/
      launchSettings.json
  MyApp.Tests/                       # Unit tests
资源管理

MAUI 以声明式方式处理资源文件。图像会根据单一源文件自动调整大小,以适配各个平台:


<ItemGroup>
  
  <MauiImage Include="Resources\Images\*" />

  
  <MauiFont Include="Resources\Fonts\*" />

  
  <MauiSplashScreen Include="Resources\Splash\splash.svg"
                    Color="#512BD4" BaseSize="128,128" />

  
  <MauiIcon Include="Resources\AppIcon\appicon.svg"
            ForegroundFile="Resources\AppIcon\appiconfg.svg"
            Color="#512BD4" />
</ItemGroup>

XAML 模式

数据绑定基础

MAUI XAML 数据绑定将 UI 元素连接到 ViewModel 属性。使用 {Binding} 并正确设置 BindingContext。

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:vm="clr-namespace:MyApp.ViewModels"
             x:Class="MyApp.Views.ProductListPage"
             x:DataType="vm:ProductListViewModel">

    <VerticalStackLayout Padding="16" Spacing="12">
        <SearchBar Text="{Binding SearchTerm}"
                   SearchCommand="{Binding SearchCommand}" />

        <CollectionView ItemsSource="{Binding Products}"
                        SelectionMode="Single"
                        SelectionChangedCommand="{Binding SelectProductCommand}"
                        SelectionChangedCommandParameter="{Binding SelectedItem,
                            Source={RelativeSource Self}}">
            <CollectionView.ItemTemplate>
                <DataTemplate x:DataType="model:Product">
                    <Frame Padding="12" Margin="0,4">
                        <HorizontalStackLayout Spacing="12">
                            <Image Source="{Binding ImageUrl}"
                                   HeightRequest="60" WidthRequest="60" />
                            <VerticalStackLayout>
                                <Label Text="{Binding Name}"
                                       FontAttributes="Bold" />
                                <Label Text="{Binding Price, StringFormat='{0:C}'}"
                                       TextColor="Gray" />
                            </VerticalStackLayout>
                        </HorizontalStackLayout>
                    </Frame>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </VerticalStackLayout>
</ContentPage>

**编译绑定:**在页面和数据模板上使用 x:DataType 启用编译绑定。编译绑定会在构建时进行类型检查,且运行速度比基于反射的绑定更快。

使用 CommunityToolkit.Mvvm 实现 MVVM

CommunityToolkit.Mvvm(Microsoft MVVM Toolkit)是 MAUI 推荐使用的 MVVM 框架。它使用源生成器来消除样板代码。

// ViewModels/ProductListViewModel.cs
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

public partial class ProductListViewModel : ObservableObject
{
    private readonly IProductService _productService;
    private readonly INavigationService _navigationService;

    public ProductListViewModel(
        IProductService productService,
        INavigationService navigationService)
    {
        _productService = productService;
        _navigationService = navigationService;
    }

    [ObservableProperty]
    [NotifyCanExecuteChangedFor(nameof(SearchCommand))]
    private string _searchTerm = "";

    [ObservableProperty]
    private ObservableCollection<Product> _products = [];

    [ObservableProperty]
    private bool _isLoading;

    [RelayCommand]
    private async Task LoadProductsAsync(CancellationToken ct)
    {
        IsLoading = true;
        try
        {
            var items = await _productService.GetProductsAsync(ct);
            Products = new ObservableCollection<Product>(items);
        }
        finally
        {
            IsLoading = false;
        }
    }

    [RelayCommand(CanExecute = nameof(CanSearch))]
    private async Task SearchAsync(CancellationToken ct)
    {
        var results = await _productService.SearchAsync(SearchTerm, ct);
        Products = new ObservableCollection<Product>(results);
    }

    private bool CanSearch() => !string.IsNullOrWhiteSpace(SearchTerm);

    [RelayCommand]
    private async Task SelectProductAsync(Product? product)
    {
        if (product is null) return;
        await _navigationService.GoToAsync(
            nameof(ProductDetailPage),
            new Dictionary<string, object> { ["Product"] = product });
    }
}

主要源生成器特性:

  • [ObservableProperty] —— 根据支持字段生成带有 INotifyPropertyChanged 的属性
  • [RelayCommand] —— 根据方法生成 ICommand(支持异步、取消和 CanExecute)
  • [NotifyPropertyChangedFor] —— 为依赖属性引发 PropertyChanged
  • [NotifyCanExecuteChangedFor] —— 属性更改时重新评估命令的 CanExecute
Shell 导航

Shell 定义视觉层次结构和导航结构。它支持飞出菜单、选项卡和基于 URI 的导航。


<Shell xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       xmlns:views="clr-namespace:MyApp.Views"
       x:Class="MyApp.AppShell">

    
    <TabBar>
        <ShellContent Title="Products"
                      Icon="products.png"
                      ContentTemplate="{DataTemplate views:ProductListPage}" />

        <ShellContent Title="Cart"
                      Icon="cart.png"
                      ContentTemplate="{DataTemplate views:CartPage}" />

        <ShellContent Title="Profile"
                      Icon="profile.png"
                      ContentTemplate="{DataTemplate views:ProfilePage}" />
    </TabBar>
</Shell>
// Register routes for pages not in the Shell visual hierarchy
// (pushed onto the navigation stack, not direct Shell tabs)
public partial class AppShell : Shell
{
    public AppShell()
    {
        InitializeComponent();
        Routing.RegisterRoute(nameof(ProductDetailPage), typeof(ProductDetailPage));
        Routing.RegisterRoute(nameof(CheckoutPage), typeof(CheckoutPage));
    }
}
// Navigate with parameters
await Shell.Current.GoToAsync(nameof(ProductDetailPage),
    new Dictionary<string, object>
    {
        ["Product"] = selectedProduct
    });

// Receive parameters via QueryProperty
[QueryProperty(nameof(Product), "Product")]
public partial class ProductDetailViewModel : ObservableObject
{
    [ObservableProperty]
    private Product _product = null!;
}
ContentPage 生命周期
public partial class ProductListPage : ContentPage
{
    private readonly ProductListViewModel _viewModel;

    public ProductListPage(ProductListViewModel viewModel)
    {
        InitializeComponent();
        _viewModel = viewModel;
        BindingContext = viewModel;
    }

    protected override async void OnAppearing()
    {
        base.OnAppearing();
        // Load data when page appears (not in constructor)
        await _viewModel.LoadProductsCommand.ExecuteAsync(null);
    }

    protected override void OnDisappearing()
    {
        base.OnDisappearing();
        // Cancel pending operations, unsubscribe events
    }
}

平台服务

用于平台特定代码的分部类

使用分部类,并在 Platforms 文件夹中提供平台特定实现。构建系统会为每个目标编译相应的实现。

// Services/IDeviceService.cs (shared interface)
public interface IDeviceService
{
    string GetDeviceIdentifier();
    Task<bool> HasBiometricAsync();
}

// Services/DeviceService.cs (shared partial class)
public partial class DeviceService : IDeviceService
{
    public partial string GetDeviceIdentifier();
    public partial Task<bool> HasBiometricAsync();
}
// Platforms/Android/Services/DeviceService.cs
public partial class DeviceService
{
    public partial string GetDeviceIdentifier()
    {
        return Android.Provider.Settings.Secure.GetString(
            Android.App.Application.Context.ContentResolver,
            Android.Provider.Settings.Secure.AndroidId) ?? "unknown";
    }

    public partial Task<bool> HasBiometricAsync()
    {
        var manager = BiometricManager.From(Android.App.Application.Context);
        var result = manager.CanAuthenticate(
            BiometricManager.Authenticators.BiometricStrong);
        return Task.FromResult(
            result == BiometricManager.BiometricSuccess);
    }
}
// Platforms/iOS/Services/DeviceService.cs
public partial class DeviceService
{
    public partial string GetDeviceIdentifier()
    {
        return UIKit.UIDevice.CurrentDevice.IdentifierForVendor?.ToString()
            ?? "unknown";
    }

    public partial Task<bool> HasBiometricAsync()
    {
        var context = new LocalAuthentication.LAContext();
        return Task.FromResult(context.CanEvaluatePolicy(
            LocalAuthentication.LAPolicy.DeviceOwnerAuthenticationWithBiometrics,
            out _));
    }
}
条件编译

对于较小的平台差异,可使用 #if 指令,而非分部类:

public void ConfigurePlatformDefaults()
{
#if ANDROID
    // Android-specific: request permissions
    Platform.CurrentActivity?.RequestPermissions(
        [Android.Manifest.Permission.Camera]);
#elif IOS || MACCATALYST
    // iOS/Mac Catalyst: no runtime permission request needed for camera
    // (handled via Info.plist NSCameraUsageDescription)
#elif WINDOWS
    // Windows: WinUI-specific configuration
#endif
}

两种方式的适用场景:

  • **分部类:**大型平台实现、多个方法、复杂逻辑
  • **条件编译:**单行差异、轻微分支、常量
依赖注入

MAUI 使用 Microsoft.Extensions.DependencyInjection。在 MauiProgram.cs 中注册服务、ViewModel 和页面。

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

        // Services
        builder.Services.AddSingleton<IProductService, ProductService>();
        builder.Services.AddSingleton<INavigationService, NavigationService>();
        builder.Services.AddTransient<IDeviceService, DeviceService>();

        // HTTP client
        builder.Services.AddHttpClient("api", client =>
        {
            client.BaseAddress = new Uri("https://api.example.com");
        });

        // ViewModels (transient so each page gets a fresh instance)
        builder.Services.AddTransient<ProductListViewModel>();
        builder.Services.AddTransient<ProductDetailViewModel>();

        // Pages (transient, resolved with DI-injected ViewModels)
        builder.Services.AddTransient<ProductListPage>();
        builder.Services.AddTransient<ProductDetailPage>();

        // For DI patterns beyond MAUI-specific registration, see [skill:dotnet-csharp-dependency-injection]

#if DEBUG
        builder.Logging.AddDebug();
#endif

        return builder.Build();
    }
}

当前状态评估(2026 年 2 月)

最后验证时间:2026-02-13

生产就绪情况

.NET MAUI 已可用于生产环境,但存在一些注意事项。该框架在企业中应用广泛,社区也在积极投入,但开发者应了解已知的工具和平台缺口。

增长指标:

  • 用户同比增长 36%
  • 社区拉取请求增加 557%
  • 在业务线应用中得到广泛的企业采用
已知问题

Visual Studio 2026 工具问题:

  • IDE 更新后,Android 工具链偶尔会在首次构建时失败;清理并重新构建通常可以解决大多数问题
  • 在某些 Android 模拟器配置下,热重载偶尔无法连接
  • XAML IntelliSense 可能会对有效的已编译绑定显示误报;即使出现红色波浪线,构建仍会成功

iOS 平台缺口:

  • 兼容 iOS 26.x 需要使用最新的 MAUI 服务更新进行测试
  • 某些 iOS 专用控件(例如使用自定义格式的 DatePicker)存在渲染不一致的问题
  • Xcode 更新可能会导致构建工具链失效,直到 MAUI 发布服务更新
诚实评估

如果你需要使用单一的 C#/.NET 代码库,面向 Android、iOS、macOS (Catalyst) 和 Windows,并采用原生 UI 渲染,那么 MAUI 是合适的选择。它尤其适用于业务线应用、企业场景,以及拥有现有 .NET 专业经验的团队。

在以下情况下,MAUI 并非最佳选择:

  • 需要面向 Web 浏览器的目标平台(可考虑 Blazor 或 Uno Platform)
  • 需要 Linux 桌面支持(可考虑 Uno Platform 或 Avalonia)
  • 需要跨平台实现像素级精准的自定义渲染(可考虑游戏引擎或基于 Skia 的框架)
  • 团队没有 .NET 经验(可评估原生或 React Native 替代方案)

迁移选项

如果 MAUI 并非最佳选择,可考虑以下 .NET 替代方案:

WinUI 3(仅限 Windows)

如果你的应用仅面向 Windows,WinUI 3 无需跨平台抽象层,即可提供更丰富的 Windows 原生体验。


<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
    <UseWinUI>true</UseWinUI>
  </PropertyGroup>
</Project>

适合选择 WinUI 而非 MAUI 的情况:

  • 仅限 Windows 的应用,无移动端或 macOS 需求
  • 需要深度集成 Windows(任务栏、通知、小组件)
  • 需要 MAUI 未提供的 WinAppSDK 功能
  • 从 UWP 迁移
Uno Platform(Web + Linux + 所有平台)

如果你除了移动端和 Windows,还需要支持 Web (WASM) 或 Linux 桌面,Uno Platform 可提供更广泛的目标平台覆盖,并支持兼容 WinUI 的 API 表面。

适合选择 Uno 而非 MAUI 的情况:

  • 需要部署到 Web 浏览器(WASM)
  • 需要 Linux 桌面支持(GTK/Framebuffer)
  • 需要嵌入式设备目标平台
  • 团队偏好使用 MVUX 响应式模式的 WinUI API 表面
  • 需要 Figma 到 XAML 的设计工作流

有关 Uno Platform 开发模式,请参阅 [skill:dotnet-uno-platform];有关各目标平台的部署,请参阅 [skill:dotnet-uno-targets]。

决策摘要
需求MAUIWinUI 3Uno Platform
Android + iOS是否是
Windows 桌面是是(最佳)是
macOS (Catalyst)是否是
Web (WASM)否否是
Linux 桌面否否是
原生 UI 渲染是是Skia + 原生
MVVM Toolkit是是是
MVUX 响应式否否是

完整的框架决策树请参阅 [skill:dotnet-ui-chooser]。


.NET 11 改进

最后验证时间:2026-02-13

XAML 源代码生成(.NET 11 Preview 1 中的默认模式)

.NET 11 Preview 1 将 XAML 源代码生成为默认的 XAML 编译模式,取代传统的 XAMLC(XamlCompilationAttribute)方式。源代码生成的 XAML 兼容 AOT,可提供更好的诊断信息,并加快启动速度。



<PropertyGroup>
  <MauiXamlInflator>XamlC</MauiXamlInflator>
</PropertyGroup>

**变更内容:**XAML 页面会在生成时转换为 C# 源代码,而不是通过 XamlCompilationAttribute 编译为 IL。这会生成类型安全的初始化代码,并支持 Native AOT。

**何时回退:**如果自定义标记扩展遇到源代码生成问题、依赖运行时 XAML 加载的第三方控件出现问题,或使用旧版 LoadFromXaml,请回退到 XamlC。

Android 使用 CoreCLR(.NET 11 Preview 1 中的默认模式)

.NET 11 Preview 1 将 Android Release 构建的默认运行时从 Mono 换为 CoreCLR。CoreCLR 性能更佳、诊断能力更强,并与服务器和桌面运行时保持一致。



<PropertyGroup>
  <UseMonoRuntime>true</UseMonoRuntime>
</PropertyGroup>

**变更内容:**Release 构建使用 CoreCLR(与 ASP.NET Core 和桌面应用使用相同的运行时),而不是 Mono。Debug 构建继续使用 Mono,以支持 Hot Reload。

**何时选择退出:**如果依赖 Mono 特有的行为、在较旧的 Android 设备(API < 26)上遇到 CoreCLR 兼容性问题,或使用专门针对 Mono 内部实现的库,请选择退出。

dotnet run 设备选择

.NET 11 Preview 1 为 MAUI 项目的 dotnet run 添加了交互式目标框架和设备选择功能。

# .NET 11: interactive device selection
dotnet run --project MyApp/MyApp.csproj
# Prompts: Select target framework:
#   1. net11.0-android
#   2. net11.0-ios
#   3. net11.0-maccatalyst
# Then: Select device:
#   1. Pixel 7 API 34 (emulator)
#   2. Samsung Galaxy S24 (physical)

# Skip interactive selection with explicit TFM
dotnet run --project MyApp/MyApp.csproj -f net11.0-android

这样就无需手动指定精确的 TFM 字符串 -f,并简化了开发者的内循环。


Hot Reload

MAUI 支持 XAML Hot Reload 和 C# Hot Reload,但具体功能因平台而异。

支持矩阵
更改类型AndroidiOSmacOSWindows
XAML 布局/样式是是是是
C# 方法体是是是是
新增实例方法(非泛型类)部分支持(.NET 9+)部分支持(.NET 9+)部分支持(.NET 9+)部分支持(.NET 9+)
新增静态方法/泛型类型成员重新生成重新生成重新生成重新生成
资源字典是是是是
新增 XAML 页面重新生成重新生成重新生成重新生成
CSS 更改是是是是
启用 Hot Reload
# CLI: Hot Reload is enabled automatically in Debug configuration
dotnet run --project MyApp/MyApp.csproj -f net8.0-android

# Visual Studio: Hot Reload is on by default (fire icon in toolbar)
# VS Code: Use MAUI extension with Hot Reload enabled

注意事项:

  • Hot Reload 需要 Debug 构建配置;Release 构建不支持
  • XAML Hot Reload 对自定义渲染器或处理程序的更改可能要等到重新生成后才会生效
  • 在 Android 上,Hot Reload 使用 MetadataUpdateHandler 机制;对静态字段或构造函数的更改需要重启
  • 在 iOS 模拟器上,Hot Reload 可以正常工作,但物理设备上的 Hot Reload 需要稳定的 USB/WiFi 连接

Agent 注意事项

  1. 不要创建单独的平台项目。 MAUI 采用单项目结构。平台专属代码应放在同一项目中的 Platforms/ 文件夹内,而不是放在单独的 Android/iOS 项目中(Xamarin.Forms 才是这种结构)。
  2. 不要混用 MVVM Toolkit 特性和手动实现的 INotifyPropertyChanged。 请始终使用 [ObservableProperty]。混用源代码生成和手写的属性更改实现会导致难以察觉的绑定错误。
  3. 不要在构造函数中调用异步方法。 使用 OnAppearing() 或已加载的命令触发数据加载。在构造函数中调用异步方法会导致未观察到的异常,以及与绑定上下文初始化相关的竞态条件。
  4. 不要使用 Device.BeginInvokeOnMainThread。 它已弃用。请改用 Microsoft.Maui.ApplicationModel 中的 MainThread.BeginInvokeOnMainThread() 或 MainThread.InvokeOnMainThreadAsync()。
  5. 不要使用 RuntimeInformation 硬编码平台检查。 请使用 DeviceInfo.Platform 比较(DevicePlatform.Android、DevicePlatform.iOS),这是 MAUI 用于平台检测的跨平台抽象。
  6. 不要在没有 x:DataType 的情况下使用 {Binding}。 始终在页面和数据模板上设置 x:DataType,以启用编译绑定。基于反射的绑定速度较慢,且无法在构建时检测到错误。
  7. 页面通常应设为 Transient,而非 Singleton。 Singleton 页面会因保留的绑定导致数据过时和内存泄漏。如果需要保留状态(例如,选项卡式页面),请使用 Singleton ViewModel 和 Transient 页面。
  8. 不要忘记为非选项卡页面注册 Shell 路由。 推入导航堆栈的页面(通过 GoToAsync)必须在 AppShell 构造函数中使用 Routing.RegisterRoute 注册,否则导航会抛出 RouteNotFoundException。

先决条件

  • .NET 8.0+(.NET MAUI 随 .NET 8+ 一同提供)
  • MAUI 工作负载:dotnet workload install maui
  • 平台 SDK:Android SDK(API 21+)、Xcode(仅限 macOS,用于 iOS/Mac Catalyst)、Windows App SDK(用于 Windows)
  • 安装了 MAUI 工作负载的 Visual Studio 2022+、安装了 .NET MAUI 扩展的 VS Code,或 JetBrains Rider 2024.2+

参考资料

评论

支持 Markdown