CommunityToolkit.Mvvm 库

CommunityToolkit.Mvvm(原名 Microsoft.Toolkit.Mvvm)是一个由 .NET 社区维护的现代化、轻量级 MVVM 框架,专为 WPF、UWP、Xamarin 和 .NET MAUI 等 XAML 平台设计。

一、核心特点

  1. 轻量高效:仅包含必要的 MVVM 组件,无额外依赖

  2. 平台中立:适用于所有 XAML 平台(WPF/UWP/Xamarin/MAUI)

  3. 源码生成:利用 Roslyn 编译器生成高性能代码

  4. 现代化 API:使用 C# 最新特性(如记录类型、模式匹配等)

  5. 官方支持:微软 .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.MvvmPrismMVVM 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>

五、最佳实践

  1. 使用分部类:将生成的代码与自定义逻辑分离

public partial class UserViewModel
{
    // 自定义逻辑
}

利用源码生成:减少样板代码

[ObservableProperty]
private string _name; // 自动生成属性+通知

弱引用消息:避免内存泄漏

WeakReferenceMessenger.Default.Register<MyMessage>(this, (r, m) => { });

异步命令:正确处理异步操作

[RelayCommand]
private async Task LoadDataAsync()
{
    // 异步操作
}

CommunityToolkit.Mvvm 是现代 .NET MVVM 应用的理想选择,特别适合需要轻量级、高性能且跨平台的场景。它的源码生成特性可以显著减少样板代码,同时保持代码的可读性和可维护性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值