CommunityToolkit.Mvvm(原名 Microsoft.Toolkit.Mvvm)是一个由 .NET 社区维护的现代化、轻量级 MVVM 框架,专为 WPF、UWP、Xamarin 和 .NET MAUI 等 XAML 平台设计。
一、核心特点
-
轻量高效:仅包含必要的 MVVM 组件,无额外依赖
-
平台中立:适用于所有 XAML 平台(WPF/UWP/Xamarin/MAUI)
-
源码生成:利用 Roslyn 编译器生成高性能代码
-
现代化 API:使用 C# 最新特性(如记录类型、模式匹配等)
-
官方支持:微软 .NET 团队维护,质量有保障
二、主要组件
1. ObservableObject (替代 INotifyPropertyChanged)
using CommunityToolkit.Mvvm.ComponentModel;
public partial class UserViewModel : ObservableObject
{
[ObservableProperty]
private string _name; // 自动生成 public string Name { get; set; }
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(FullName))] // 当Name变化时通知FullName
private string _lastName;
public string FullName => $"{Name} {LastName}";
}
2. RelayCommand (ICommand 实现)
using CommunityToolkit.Mvvm.Input;
public partial class UserViewModel
{
[RelayCommand]
private void Submit() // 自动生成 SubmitCommand
{
// 提交逻辑
}
[RelayCommand(CanExecute = nameof(CanDelete))]
private void Delete(User user)
{
// 删除逻辑
}
private bool CanDelete(User user) => user != null;
}
3. 依赖注入支持
using CommunityToolkit.Mvvm.DependencyInjection;
// 配置服务
Ioc.Default.ConfigureServices(
new ServiceCollection()
.AddSingleton<IDataService, DataService>()
.BuildServiceProvider());
// 使用服务
var dataService = Ioc.Default.GetRequiredService<IDataService>();
4. 消息传递
using CommunityToolkit.Mvvm.Messaging;
// 发送消息
WeakReferenceMessenger.Default.Send(new UserLoggedInMessage(user));
// 接收消息
WeakReferenceMessenger.Default.Register<UserLoggedInMessage>(this, (r, m) =>
{
// 处理消息
});
三、与 Prism/MVVM Light 对比
特性 | CommunityToolkit.Mvvm | Prism | MVVM Light |
---|---|---|---|
大小 | 极轻量 (~100KB) | 较大 | 中等 |
学习曲线 | 简单 | 较陡峭 | 中等 |
依赖注入 | 基础支持 | 强大 | 无 |
导航 | 无 | 强大 | 无 |
平台支持 | 全平台 | 主要WPF | 全平台 |
源码生成 | 是 | 否 | 否 |
维护状态 | 活跃 | 活跃 | 维护中 |
四、实际应用示例
1. 安装
dotnet add package CommunityToolkit.Mvvm
2. 完整 ViewModel 示例
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
public partial class UserViewModel : ObservableObject
{
private readonly IUserService _userService;
[ObservableProperty]
private User _selectedUser;
[ObservableProperty]
private bool _isLoading;
public UserViewModel(IUserService userService)
{
_userService = userService;
LoadUsersCommand.ExecuteAsync(null);
}
[RelayCommand]
private async Task LoadUsers()
{
IsLoading = true;
try
{
Users = await _userService.GetAllAsync();
WeakReferenceMessenger.Default.Send(new UsersLoadedMessage(Users.Count));
}
finally
{
IsLoading = false;
}
}
[RelayCommand(CanExecute = nameof(CanDeleteUser))]
private void DeleteUser(User user)
{
_userService.Delete(user.Id);
}
private bool CanDeleteUser(User user) => user != null && !IsLoading;
}
public record UsersLoadedMessage(int Count);
3. 在 WPF 中使用
<Window x:Class="MyApp.Views.UserView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyApp.ViewModels"
Title="用户管理" Height="450" Width="800">
<Window.DataContext>
<local:UserViewModel/>
</Window.DataContext>
<Grid>
<Button Content="加载用户" Command="{Binding LoadUsersCommand}"/>
<ListView ItemsSource="{Binding Users}" SelectedItem="{Binding SelectedUser}">
<ListView.ContextMenu>
<ContextMenu>
<MenuItem Header="删除" Command="{Binding DeleteUserCommand}"
CommandParameter="{Binding SelectedItem, RelativeSource={RelativeSource AncestorType=ListView}}"/>
</ContextMenu>
</ListView.ContextMenu>
</ListView>
<ProgressBar IsIndeterminate="True" Visibility="{Binding IsLoading, Converter={StaticResource BooleanToVisibilityConverter}}"/>
</Grid>
</Window>
五、最佳实践
-
使用分部类:将生成的代码与自定义逻辑分离
public partial class UserViewModel
{
// 自定义逻辑
}
利用源码生成:减少样板代码
[ObservableProperty]
private string _name; // 自动生成属性+通知
弱引用消息:避免内存泄漏
WeakReferenceMessenger.Default.Register<MyMessage>(this, (r, m) => { });
异步命令:正确处理异步操作
[RelayCommand]
private async Task LoadDataAsync()
{
// 异步操作
}
CommunityToolkit.Mvvm 是现代 .NET MVVM 应用的理想选择,特别适合需要轻量级、高性能且跨平台的场景。它的源码生成特性可以显著减少样板代码,同时保持代码的可读性和可维护性。