wpf RelayCommand的CanExecute 没有触发的原因

问题描述

使用MVVM RelayCommand CanExecute 进行按钮禁用控制,偶尔会出现CanExecute 一直不触发。

如图CanExecute 一直没触发,导致按钮本应该可用,这里一直不可用。在这里插入图片描述
而且出现这个问题后,只要鼠标或键盘点击任意一处地方(可以是电脑屏幕的任何一个图标)就能马上触发CanExecute事件,真神奇。

问题定位

通过测试发现,页面Load事件数据量大时,不会出现这个问题。只会在数据少页面响应很快时,就会出现这个问题。
顺着排查,发现再Load事件内使用了await Task.Delay(20) 使用await Task.Delay异步线程睡眠,CPU会被调度到其它地方。可能会导致这个页面焦点被改变,焦点改变CanExecute就触发不了了。

问题修改

把页面Load事件内的await Task.Delay 修改为 Thread.Sleep 问题解决!

Task.Factory.StartNew(async () =>
                          {
                             var resobj= await this.service.StartCheck(this.IsRequest, this.isGetCurWeekAfterData);
                              int count = 0;
                              Load(classObject);
                              count += classObject.RequestTree?.Count()?? 0;
                              Thread.Sleep(20);
                              //await Task.Delay(20); 会导致mvvm Command CanExecute 不触发,数据量少的时候可以必现此问题 Lv
                             //...
                          });
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
A:WPF中的ICommand是一个接口,用于封装在MVVM(Model-View-ViewModel)架构中的命令行为。ICommand包含三个方法:Execute,CanExecute和CanExecuteChanged事件。Execute方法表示命令的执行操作,CanExecute方法用于检查命令是否可以执行,CanExecuteChanged事件在CanExecute方法的返回值发生变化时发生。 以下是一个示例命令类,实现了ICommand接口: ```C# public class RelayCommand : ICommand { private readonly Action<object> execute; private readonly Predicate<object> canExecute; public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } public RelayCommand(Action<object> execute, Predicate<object> canExecute = null) { this.execute = execute ?? throw new ArgumentNullException(nameof(execute)); this.canExecute = canExecute; } public bool CanExecute(object parameter) { return canExecute == null || canExecute(parameter); } public void Execute(object parameter) { execute(parameter); } } ``` 使用此命令类,你可以在ViewModel中声明命令,并在View中绑定到命令上: ```C# public class MyViewModel { public ICommand MyCommand { get; } public MyViewModel() { MyCommand = new RelayCommand(DoSomething, CanDoSomething); } private bool CanDoSomething(object parameter) { // Return true or false to indicate if the command can be executed return true; } private void DoSomething(object parameter) { // Do something here when the command is executed } } ``` 在View中,你可以使用以下代码将命令绑定到Button的Click事件上: ```XAML <Button Command="{Binding MyCommand}" Content="Execute Command" /> ``` 当用户单击按钮时,将触发MyCommandExecute方法。可以使用CanExecute方法来控制按钮是否应该启用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值