异步编程的艺术:C# 中命令执行与Winform界面交互的完美融合
|
admin
2025年3月14日 9:44
本文热度 131
|
CommunityToolkit.Mvvm提供了强大的异步编程支持,通过IAsyncRelayCommand
和AsyncRelayCommand
等类型,使得在MVVM架构中处理异步操作变得简单而优雅。本文将详细介绍如何在WinForm应用中使用这些特性。
核心组件
主要异步命令类型
IAsyncRelayCommand
AsyncRelayCommand
AsyncRelayCommand
异步命令特性
实战示例
基础项目设置
首先创建一个WinForm项目,添加必要的NuGet包:
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
示例ViewModel
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
usingstatic System.Windows.Forms.VisualStyles.VisualStyleElement;
namespace App13
{
// ObservableObject 是 CommunityToolkit.Mvvm 提供的基础 ViewModel 类
public partial class MainViewModel : ObservableObject
{
// 使用 ObservableProperty 特性自动实现属性通知
[ObservableProperty]
privatestring status = "就绪";
[ObservableProperty]
privatebool 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;
}
}
}
}
带取消功能的高级示例
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]
privatestring progressStatus = "就绪";
[ObservableProperty]
privateint 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();
}
}
}
}
WinForm界面实现
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
和相关组件,我们可以:
- 优雅地处理异步操作
- 轻松实现取消功能
- 有效管理UI状态
- 提供良好的用户体验
合理使用这些特性,可以显著提高应用程序的响应性和用户体验。
该文章在 2025/3/14 9:44:27 编辑过