.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 MAUI | Xamarin.Forms | Flutter | Avalonia UI |
|---|---|---|---|---|
| 语言 | C# | C# | Dart | C# |
| UI 渲染 | 原生控件(Handler) | 原生控件(Renderer) | 自绘引擎(Skia/Impeller) | 自绘引擎(Skia) |
| 平台支持 | Android/iOS/macOS/Windows | Android/iOS/macOS/Windows | Android/iOS/macOS/Windows/Web | Android/iOS/macOS/Windows/Linux |
| 桌面支持 | 良好(WinUI3/Mac Catalyst) | 有限 | 良好 | 极佳(桌面优先) |
| UI 一致性 | 各平台原生外观 | 各平台原生外观 | 跨平台完全一致 | 跨平台完全一致 |
| 生态 | .NET 生态 + NuGet | .NET 生态 + NuGet | pub.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 包更小)
相关链接
- 官方文档
- GitHub 仓库
- .NET MAUI Blog
- CommunityToolkit.Mvvm
- .NET MAUI Community Toolkit
- Syncfusion Toolkit for MAUI(免费)