如何基于多个AsyncRelayCommand的IsRunning属性实现统一IsLoading通知
最优实现方案
你可以通过合并两个AsyncRelayCommand的IsRunning状态计算IsLoading,同时监听两个命令的PropertyChanged事件,当任意一个命令的IsRunning变化时触发IsLoading的属性变更通知,以下是基于CommunityToolkit.Mvvm的示例代码:
// ViewModel需要继承ObservableObject public partial class MyViewModel : ObservableObject { // 两个异步命令实例 public AsyncRelayCommand Loading1Command { get; } public AsyncRelayCommand Loading2Command { get; } // 统一暴露的IsLoading属性,任意命令运行中就返回true public bool IsLoading => Loading1Command.IsRunning || Loading2Command.IsRunning; public MyViewModel() { Loading1Command = new AsyncRelayCommand(Load1Async); Loading2Command = new AsyncRelayCommand(Load2Async); // 监听两个命令的属性变更事件 Loading1Command.PropertyChanged += (s, e) => { if (e.PropertyName == nameof(AsyncRelayCommand.IsRunning)) { OnPropertyChanged(nameof(IsLoading)); } }; Loading2Command.PropertyChanged += (s, e) => { if (e.PropertyName == nameof(AsyncRelayCommand.IsRunning)) { OnPropertyChanged(nameof(IsLoading)); } }; } private async Task Load1Async() { // 加载逻辑1 } private async Task Load2Async() { // 加载逻辑2 } }
如果有多个命令需要监听,可以封装通用的辅助方法批量处理,减少重复代码。
疑问解答
1. 是否可以为AsyncRelayCommand.PropertyChanged添加针对IsRunningChangedEventArgs的事件处理程序实现该需求?
可以,这就是上述方案的核心实现逻辑。注意AsyncRelayCommand的IsRunning变更触发的是标准PropertyChanged事件,事件参数携带的属性名是nameof(AsyncRelayCommand.IsRunning),只要在事件处理中判断属性名匹配后,手动触发IsLoading的变更通知即可。
2. 是否存在类似[AlsoNotify...]的特性可直接实现该能力?
目前CommunityToolkit.Mvvm的[ICommand]源生成器没有内置你示例中的[AlsoNotifyIsRunningFor]特性。有一个接近的内置特性[NotifyCanExecuteChangedFor],但它仅用于通知命令的可执行状态变更,不支持联动通知其他自定义属性的状态。
如果不想手动写事件监听代码,可以自行实现对应源生成器扩展,或者使用第三方Mvvm框架的对应能力,原生CommunityToolkit.Mvvm暂时不支持直接通过特性实现该需求。
内容的提问来源于stack exchange,提问作者user17280926
相关产品推荐
相关产品推荐

