ICommand是否可以在PropertyChanged之后不触发? [英] ICommand CanExecute not triggering after PropertyChanged?

查看:99
本文介绍了ICommand是否可以在PropertyChanged之后不触发?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 WPF应用程序,该应用程序显示了绑定到如下命令的按钮:

I got a WPF application that shows a button bound to a command like that:

<Button Command="{Binding Path=TestrunStartCommand}" Content="GO!">

该命令的定义如下:

public ICommand TestrunStartCommand
{
    get { return new RelayCommand(TestrunStartExecute, () => !IsTestrunInProgress); }
}

public bool IsTestrunInProgress
{
    get{
        return _isTestrunInProgress;
    }
    set{
        _isTestrunInProgress = value;
        RaisePropertyChanged(IsTestrunInProgressPropertyName);
    }
}   

问题是,将IsTestrunInProgress设置为false后,不会立即启用该按钮,而仅在我在应用程序窗口中单击后才会启用该按钮.

The problem is, the button won't be enabled immediately after I set IsTestrunInProgress to false, but only after I click inside the application window.

您能帮助我理解此行为并向我展示如何解决此问题吗?

Could you help me understand this behaviour and show me how to fix this?

进一步阅读: wpf命令模式-什么时候查询可以执行

推荐答案

ICommand界面公开事件

The ICommand interface exposes an event ICommand.CanExecuteChanged which is used to inform the UI when to re-determine the IsEnabled state of command driven UI components.

根据您使用的RelayCommand的实现,可能需要引发此事件;许多实现公开了诸如RelayCommand.RaiseCanExecuteChanged()之类的方法,您可以调用该方法来强制UI刷新.

Depending upon the implementation of the RelayCommand you are using, you may need to raise this event; Many implementations expose a method such as RelayCommand.RaiseCanExecuteChanged() which you can invoke to force the UI to refresh.

RelayCommand的某些实现使用 CommandManager.RequerySuggested ,在这种情况下,您需要致电 CommandManager.InvalidateRequerySuggested() 强制刷新界面.

Some implementations of the RelayCommand make use of CommandManager.RequerySuggested, in which case you will need to call CommandManager.InvalidateRequerySuggested() to force the UI to refresh.

长话短说,您需要从属性设置器中调用这些方法之一.

Long story short, you will need to call one of these methods from your property setter.

更新

由于在更改活动焦点时正在确定按钮的状态,因此我相信正在使用CommandManager.因此,在属性的设置器中,分配后备字段后,调用 CommandManager.InvalidateRequerySuggested() .

As the state of the button is being determined when the active focus is changing, I believe the CommandManager is being used. So in the setter of your property, after assigning the backing field, invoke CommandManager.InvalidateRequerySuggested().

更新2

RelayCommand实现来自MVVM light工具箱.从WPF/.NET使用时,该实现将包装CommandManager中公开的方法和事件.这意味着这些命令在大多数情况下都会自动运行(更改UI或更改聚焦元素).但是在某些情况下(例如这种情况),您将需要手动强制命令重新查询.使用此库执行此操作的正确方法是在RelayCommand上调用RaiseCanExecuteChanged()方法.

The RelayCommand implementation is from the MVVM light toolkit. When consumed from WPF/.NET, the implementation wraps the methods and events exposed from the CommandManager. This will mean that these commands work automagically in the majority of situations (where the UI is altered, or the focused element is changed). But in a few cases, such as this one, you will need to manually force the command to re-query. The proper way to do this using this library would be to call the RaiseCanExecuteChanged() method on the RelayCommand.

这篇关于ICommand是否可以在PropertyChanged之后不触发?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆