CommunityToolkit.Mvvm是微软官方推出的轻量级MVVM框架,相比传统的MVVM框架,它没有复杂的依赖,体积小且易用,非常适合WPF、WinUI、MAUI等C#客户端项目的开发。它提供了属性通知、命令、依赖注入等核心功能,能够大幅减少重复代码的编写。

一、基础使用方式
1. 安装框架
首先需要通过NuGet安装CommunityToolkit.Mvvm包,在Visual Studio的包管理器控制台执行以下命令即可:
Install-Package CommunityToolkit.Mvvm
2. 实现属性通知
传统实现INotifyPropertyChanged接口需要手动编写属性变更通知代码,使用CommunityToolkit.Mvvm可以通过特性快速实现。首先定义ViewModel基类,继承ObservableObject:
using CommunityToolkit.Mvvm.ComponentModel;
// 继承ObservableObject获得属性通知能力
public partial class MainViewModel : ObservableObject
{
// 使用ObservableProperty特性标记字段,会自动生成对应的可通知属性
[ObservableProperty]
private string _userName;
[ObservableProperty]
private int _age;
}
上述代码会自动生成UserName和Age两个公共属性,当属性值变更时会自动触发PropertyChanged事件,不需要手动编写OnPropertyChanged相关代码。
3. 定义命令
框架提供了RelayCommand和AsyncRelayCommand用于定义命令,同样通过特性即可快速实现:
using CommunityToolkit.Mvvm.Input;
public partial class MainViewModel : ObservableObject
{
[ObservableProperty]
private string _userName;
// 定义同步命令
[RelayCommand]
private void SaveUser()
{
// 保存用户逻辑
Console.WriteLine($"保存用户:{UserName}");
}
// 定义异步命令
[RelayCommand]
private async Task LoadUserDataAsync()
{
await Task.Delay(1000); // 模拟异步加载
UserName = "测试用户";
}
}
生成后的命令名称会在方法名后加Command,比如SaveUser方法会生成SaveUserCommand,LoadUserDataAsync方法会生成LoadUserDataAsyncCommand,可以直接在XAML中绑定使用。
二、最佳实践
1. ViewModel分层设计
不要将所有业务逻辑都堆在一个ViewModel中,应该按照功能模块拆分ViewModel,比如用户模块对应UserViewModel,订单模块对应OrderViewModel,每个ViewModel只负责对应模块的逻辑,提升代码的可维护性。
2. 合理使用依赖注入
CommunityToolkit.Mvvm支持依赖注入,建议将服务通过构造函数注入到ViewModel中,而不是在ViewModel内部直接实例化服务,这样方便后续做单元测试和模块替换。
using CommunityToolkit.Mvvm.ComponentModel;
using Microsoft.Extensions.DependencyInjection;
// 定义用户服务接口
public interface IUserService
{
string GetUserName();
}
// 用户服务实现
public class UserService : IUserService
{
public string GetUserName()
{
return "默认用户";
}
}
// 带依赖注入的ViewModel
public partial class MainViewModel : ObservableObject
{
private readonly IUserService _userService;
// 通过构造函数注入服务
public MainViewModel(IUserService userService)
{
_userService = userService;
UserName = _userService.GetUserName();
}
[ObservableProperty]
private string _userName;
}
// 服务注册示例
var services = new ServiceCollection();
services.AddTransient<IUserService, UserService>();
services.AddTransient<MainViewModel>();
var serviceProvider = services.BuildServiceProvider();
var viewModel = serviceProvider.GetRequiredService<MainViewModel>();
3. 命令参数绑定规范
如果命令需要接收参数,直接在方法上定义参数即可,框架会自动匹配绑定时的参数:
public partial class MainViewModel : ObservableObject
{
[RelayCommand]
private void DeleteUser(int userId)
{
Console.WriteLine($"删除用户ID:{userId}");
}
}
XAML中绑定命令参数时,可以直接使用Binding传递对应的值:
<Button Content="删除" Command="{Binding DeleteUserCommand}" CommandParameter="1001" />
三、常见坑点及规避方案
1. 字段命名不符合规范导致属性生成失败
使用ObservableProperty特性时,字段必须以_开头,且采用驼峰命名法,否则不会自动生成公共属性。比如以下写法是错误的:
// 错误写法:字段没有以_开头 [ObservableProperty] private string userName; // 错误写法:字段不符合驼峰命名规范 [ObservableProperty] private string _UserName;
正确的写法必须是_userName这种形式,才会生成UserName公共属性。
2. 命令方法访问修饰符错误
被RelayCommand特性标记的方法必须是私有的,不能是公共的,否则会生成失败。以下写法是错误的:
// 错误写法:方法是公共的
[RelayCommand]
public void SaveUser()
{
// 逻辑代码
}
需要改为私有方法:
// 正确写法:私有方法
[RelayCommand]
private void SaveUser()
{
// 逻辑代码
}
3. 异步命令中未正确处理异常
AsyncRelayCommand中的异步方法如果抛出异常,默认不会捕获,会导致程序崩溃。建议在异步命令方法中主动添加异常处理逻辑:
[RelayCommand]
private async Task LoadDataAsync()
{
try
{
await Task.Delay(1000);
// 模拟可能出错的代码
throw new Exception("加载失败");
}
catch (Exception ex)
{
Console.WriteLine($"加载数据出错:{ex.Message}");
}
}
4. 属性通知未触发的问题
如果手动修改了自动生成的属性值,没有触发通知,需要检查是否直接修改了字段而不是属性。比如以下写法不会触发通知:
// 错误写法:直接修改字段,不会触发属性通知 _userName = "新用户"; // 正确写法:修改属性,会触发通知 UserName = "新用户";
如果需要修改字段后手动触发通知,可以调用OnPropertyChanged方法:
_userName = "新用户"; OnPropertyChanged(nameof(UserName));
四、总结
CommunityToolkit.Mvvm是一个上手简单、功能实用的MVVM框架,能够大幅减少开发中的重复代码。使用时只要注意字段命名规范、命令方法修饰符、异常处理等常见问题,结合分层设计和依赖注入的最佳实践,就能高效完成C#客户端项目的开发。
C#_CommunityToolkit_MvvmMVVM模式依赖注入命令绑定属性通知修改时间:2026-07-04 13:39:18