我得到了一个 WPF 应用程序,它显示了一个按钮绑定(bind)到这样的命令:
<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 后,该按钮不会立即启用,而是只有在我在应用程序窗口内单击之后。
你能帮我理解这种行为并告诉我如何解决这个问题吗?
最佳答案
ICommand
接口(interface)公开了一个事件 ICommand.CanExecuteChanged
用于通知 UI 何时重新确定命令驱动的 UI 组件的 IsEnabled
状态。
根据您正在使用的 RelayCommand
的实现,您可能需要引发此事件;许多实现公开了一个方法,例如 RelayCommand.RaiseCanExecuteChanged()
,您可以调用该方法来强制刷新 UI。
RelayCommand
的一些实现使用了 CommandManager.RequerySuggested
,在这种情况下,您需要调用 CommandManager.InvalidateRequerySuggested()
强制刷新 UI。
长话短说,您需要从您的属性 setter 中调用这些方法之一。
更新
由于当事件焦点发生变化时正在确定按钮的状态,我相信正在使用 CommandManager
。因此,在您的属性的 setter 中,在分配支持字段后,调用 CommandManager.InvalidateRequerySuggested()
.
更新 2
RelayCommand
实现来自 MVVM light 工具包。当从 WPF/.NET 使用时,实现包装从 CommandManager
公开的方法和事件。这将意味着这些命令在大多数情况下自动运行(UI 更改或焦点元素更改)。但在少数情况下,例如本例,您将需要手动强制命令重新查询。使用此库执行此操作的正确方法是调用 RelayCommand
上的 RaiseCanExecuteChanged()
方法。
关于c# - PropertyChanged 后 ICommand CanExecute 不触发?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14479303/