CommunityToolkit.Mvvm提供了强大的异步编程支持,通过IAsyncRelayCommand和AsyncRelayCommand等类型,使得在MVVM架构中处理异步操作变得简单而优雅。本文将详细介绍如何在WinForm应用中使用这些特性。
IAsyncRelayCommand - 异步命令接口AsyncRelayCommand - 基础异步命令实现AsyncRelayCommand<T> - 带参数的异步命令实现首先创建一个WinForm项目,添加必要的NuGet包:
XML<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />

C#using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
namespace App13
{
// ObservableObject 是 CommunityToolkit.Mvvm 提供的基础 ViewModel 类
public partial class MainViewModel : ObservableObject
{
// 使用 ObservableProperty 特性自动实现属性通知
[ObservableProperty]
private string status = "就绪";
[ObservableProperty]
private bool isLoading;
// 异步命令 - 基础示例
private readonly IAsyncRelayCommand loadDataCommand;
public IAsyncRelayCommand LoadDataCommand => loadDataCommand;
public MainViewModel()
{
// 初始化异步命令
loadDataCommand = new AsyncRelayCommand(LoadDataAsync);
}
// 模拟异步数据加载
private async Task LoadDataAsync()
{
try
{
IsLoading = true;
Status = "正在加载数据...";
// 模拟耗时操作
await Task.Delay(2000);
Status = "数据加载完成!";
}
catch (Exception ex)
{
MessageBox.Show($"发生错误:{ex.Message}");
Status = "加载失败";
}
finally
{
IsLoading = false;
}
}
}
}
C#using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
namespace App13
{
public partial class AdvancedViewModel : ObservableObject
{
[ObservableProperty]
private string progressStatus = "就绪";
[ObservableProperty]
private int progressValue;
// 使用 CancellationTokenSource 支持取消操作
private CancellationTokenSource? cts;
// 声明异步命令
private readonly IAsyncRelayCommand startProcessCommand;
private readonly IRelayCommand cancelCommand;
public IAsyncRelayCommand StartProcessCommand => startProcessCommand;
public IRelayCommand CancelCommand => cancelCommand;
public AdvancedViewModel()
{
startProcessCommand = new AsyncRelayCommand(
ExecuteLongProcessAsync,
// 通过判断 cts 是否为 null 来确定命令是否可执行
() => cts == null
);
cancelCommand = new RelayCommand(
// 取消操作的实现
() =>
{
cts?.Cancel();
cts = null;
},
// 只有在进程运行时才能取消
() => cts != null
);
}
private async Task ExecuteLongProcessAsync()
{
try
{
// 创建新的 CancellationTokenSource
cts = new CancellationTokenSource();
ProgressStatus = "处理中...";
ProgressValue = 0;
// 模拟长时间运行的任务
for (int i = 0; i <= 100; i += 10)
{
// 检查是否请求取消
cts.Token.ThrowIfCancellationRequested();
ProgressValue = i;
await Task.Delay(500, cts.Token);
}
ProgressStatus = "处理完成!";
ProgressValue = 100;
}
catch (OperationCanceledException)
{
ProgressStatus = "操作已取消";
}
catch (Exception ex)
{
MessageBox.Show($"发生错误:{ex.Message}");
ProgressStatus = "处理失败";
}
finally
{
cts = null;
// 通知命令可用性变化
(StartProcessCommand as AsyncRelayCommand)?.NotifyCanExecuteChanged();
(CancelCommand as RelayCommand)?.NotifyCanExecuteChanged();
}
}
}
}
C#namespace App13
{
public partial class Form1 : Form
{
private readonly MainViewModel viewModel;
private readonly AdvancedViewModel advancedViewModel;
public Form1()
{
InitializeComponent();
// 初始化ViewModel
viewModel = new MainViewModel();
advancedViewModel = new AdvancedViewModel();
// 设置数据绑定
SetupDataBindings();
}
private void SetupDataBindings()
{
// 基础示例绑定
btnLoad.Click += async (s, e) => await viewModel.LoadDataCommand.ExecuteAsync(null);
// 使用BindingSource实现属性绑定
var bindingSource = new BindingSource();
bindingSource.DataSource = viewModel;
lblStatus.DataBindings.Add("Text", bindingSource, nameof(viewModel.Status));
// 高级示例绑定
btnStart.Click += async (s, e) => await advancedViewModel.StartProcessCommand.ExecuteAsync(null);
btnCancel.Click += (s, e) => advancedViewModel.CancelCommand.Execute(null);
var advancedBindingSource = new BindingSource();
advancedBindingSource.DataSource = advancedViewModel;
progressBar.DataBindings.Add("Value", advancedBindingSource, nameof(advancedViewModel.ProgressValue));
lblProgressStatus.DataBindings.Add("Text", advancedBindingSource, nameof(advancedViewModel.ProgressStatus));
}
}
}

CommunityToolkit.Mvvm提供的异步支持极大地简化了WinForm应用中的异步操作处理。通过AsyncRelayCommand和相关组件,我们可以:
合理使用这些特性,可以显著提高应用程序的响应性和用户体验。
本文作者:技术老小子
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!