MD 状态:stable 更新:2026/5/12

.NET MAUI

一句话定位:用 C# 和 XAML 从单一代码库构建 Android、iOS、macOS、Windows 原生应用的微软官方跨平台框架,是 Xamarin.Forms 的正统继承者。

核心概念

应用入口与生命周期

MauiProgram.cs 是应用启动入口,使用 MauiAppBuilder 注册服务、配置字体、Handler 映射等:

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

Shell — 导航容器

Shell 是 MAUI 推荐的顶层导航结构,提供飞出菜单(Flyout)、底部 Tab、URI 路由导航:

<!-- AppShell.xaml -->
<Shell>
    <TabBar>
        <ShellContent Title="首页" ContentTemplate="{DataTemplate local:HomePage}" Route="home" />
        <ShellContent Title="设置" ContentTemplate="{DataTemplate local:SettingsPage}" Route="settings" />
    </TabBar>
</Shell>

路由导航:await Shell.Current.GoToAsync("//details?id=42")

ContentPage — 页面单元

每个页面继承自 ContentPage,XAML 定义 UI,code-behind 或 ViewModel 处理逻辑。

Handler 架构

MAUI 用 Handler 替代了 Xamarin 的 Renderer。每个跨平台控件(如 Button)对应一个 Handler,Handler 内部映射到各平台原生控件。可自定义 Handler 修改原生行为,无需继承整个控件:

// 移除 Android Entry 下划线
Microsoft.Maui.Handlers.EntryHandler.Mapper.AppendToMapping("NoUnderline", (handler, view) =>
{
    handler.PlatformView.BackgroundTintList =
        Android.Content.Res.ColorStateList.ValueOf(Android.Graphics.Color.Transparent);
});

MVVM + 数据绑定

MAUI 内置 INotifyPropertyChanged 绑定系统,推荐配合 CommunityToolkit.Mvvm 减少样板代码:

// ViewModel
public partial class CounterViewModel : ObservableObject
{
    [ObservableProperty]
    private int count;

    [RelayCommand]
    private void Increment() => Count++;
}
<!-- View 绑定 -->
<Label Text="{Binding Count}" />
<Button Text="点击" Command="{Binding IncrementCommand}" />

依赖注入

MAUI 原生支持 Microsoft.Extensions.DependencyInjection,在 MauiProgram.cs 中注册,页面/ViewModel 通过构造函数注入。


快速上手

环境要求

  • Windows:Visual Studio 2022/2026,安装 .NET Multi-Platform App UI 工作负载
  • macOS:Visual Studio Code + .NET MAUI 扩展 + Xcode

创建项目

dotnet new maui -n MyApp
cd MyApp
dotnet run -f net10.0-windows10.0.19041.0   # Windows
dotnet run -f net10.0-android               # Android(需模拟器)

完整示例:计数器页面

CounterViewModel.cs

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

public partial class CounterViewModel : ObservableObject
{
    [ObservableProperty]
    private int count;

    [ObservableProperty]
    private string statusMessage = "尚未点击";

    [RelayCommand]
    private void Increment()
    {
        Count++;
        StatusMessage = $"已点击 {Count} 次";
    }
}

CounterPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:vm="clr-namespace:MyApp"
             x:Class="MyApp.CounterPage"
             Title="计数器">
    <ContentPage.BindingContext>
        <vm:CounterViewModel />
    </ContentPage.BindingContext>

    <VerticalStackLayout Spacing="16" Padding="32" VerticalOptions="Center">
        <Label Text="{Binding StatusMessage}" FontSize="18" HorizontalOptions="Center" />
        <Label Text="{Binding Count}" FontSize="48" FontAttributes="Bold" HorizontalOptions="Center" />
        <Button Text="点击我" Command="{Binding IncrementCommand}" HorizontalOptions="Center" />
    </VerticalStackLayout>
</ContentPage>

典型使用场景

场景说明
企业内部移动应用与 Azure AD、Microsoft 365 深度集成,适合企业 LOB 应用
Xamarin 迁移官方迁移路径,大量 API 兼容,迁移成本低
移动 + 桌面同构一套代码同时发布 Android/iOS/Windows/macOS
Blazor Hybrid嵌入 WebView 运行 Blazor 组件,复用 Web 前端代码
.NET 全栈团队后端 ASP.NET Core + 前端 MAUI,共享模型层和业务逻辑

框架对比

维度.NET MAUIXamarin.FormsFlutterAvalonia UI
语言C#C#DartC#
UI 渲染原生控件(Handler)原生控件(Renderer)自绘引擎(Skia/Impeller)自绘引擎(Skia)
平台支持Android/iOS/macOS/WindowsAndroid/iOS/macOS/WindowsAndroid/iOS/macOS/Windows/WebAndroid/iOS/macOS/Windows/Linux
桌面支持良好(WinUI3/Mac Catalyst)有限良好极佳(桌面优先)
UI 一致性各平台原生外观各平台原生外观跨平台完全一致跨平台完全一致
生态.NET 生态 + NuGet.NET 生态 + NuGetpub.dev(庞大)NuGet(较小)
学习曲线低(.NET 开发者)中(需学 Dart)低(.NET 开发者)
社区活跃度中(微软主导)维护模式高(Google 主导)中(社区主导)
适合场景企业/移动+桌面遗留项目UI 精细/动画丰富桌面优先

[!tip] 选型建议

  • 团队已有 .NET 背景 → 优先 MAUI
  • 需要高度自定义 UI 和流畅动画 → 考虑 Flutter
  • 纯桌面应用(Windows/Linux/macOS)→ 考虑 Avalonia UI
  • 从 Xamarin 迁移 → MAUI 是官方路径,无需犹豫

优缺点

优点

  • 单一代码库:一套 C# + XAML 覆盖 5 个平台(含 Tizen)
  • .NET 生态复用:直接使用 NuGet 包、Entity Framework、HttpClient 等
  • 原生性能:Handler 架构直接映射原生控件,无额外渲染层
  • 微软官方支持:长期维护承诺,与 Azure/Visual Studio 深度集成
  • 依赖注入内置:现代化应用架构开箱即用
  • Hot Reload:支持 XAML 和 C# 热重载,开发体验良好

缺点与已知坑

[!warning] CollectionView 性能问题 大数据集(数千条)下 CollectionView 性能较差,虚拟化不完善。企业级列表场景需谨慎评估,或使用第三方控件(如 Syncfusion)。

[!warning] Windows 桌面体验不完整

  • 无法自定义标题栏(需绕过到 WinUI3 原生 API)
  • 窗口管理 API 有限,获取当前激活窗口需用 Win32 API
  • MAUI Blazor 在 Windows 上使用 WebView2,语言/区域设置有坑

[!warning] 启动时间 冷启动比原生应用慢,.NET 运行时加载有开销,低端 Android 设备上尤为明显。

[!warning] 第三方控件生态较弱 相比 Flutter 的 pub.dev,MAUI 专用控件库较少,复杂 UI 需依赖 Syncfusion、Telerik 等商业库。

[!warning] macOS 支持依赖 Mac Catalyst macOS 版本通过 Mac Catalyst 实现,并非真正的 AppKit 应用,部分 macOS 原生体验缺失。

其他已知问题:

  • 调试 iOS 需要 Mac 机器(或 Mac Build Host)
  • 热重载在复杂状态场景下偶尔失效
  • 早期版本(.NET 6/7)bug 较多,建议使用 .NET 9/10

适合什么人 / 项目

适合:

  • .NET / C# 开发团队,希望复用现有技能和代码
  • 从 Xamarin.Forms 迁移的项目
  • 企业内部应用(ERP、CRM、审批流),需要与 Azure/AD 集成
  • 需要同时发布移动端 + Windows 桌面的应用
  • 全栈 .NET 团队(后端 ASP.NET Core + 前端 MAUI 共享模型)

不适合:

  • 需要极致 UI 动画和高度自定义视觉效果(考虑 Flutter)
  • 纯桌面应用且需要 Linux 支持(考虑 Avalonia UI
  • 团队无 .NET 背景,学习成本不合算
  • 对包体积极度敏感的应用(Flutter 包更小)

相关链接

相关笔记