c# - PropertyChanged 后 ICommand CanExecute 不触发?

标签 c# wpf mvvm-light

我得到了一个 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 后,该按钮不会立即启用,而是只有在我在应用程序窗口内单击之后

你能帮我理解这种行为并告诉我如何解决这个问题吗?

进一步阅读: wpf command pattern - when does it query canexecute

最佳答案

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/

相关文章:

c# - 垂直包装元素(固定长度和水平位置)

c# - DataTable 表达式无法解释标记 '!'

WPF TabControl - 当 TabItem 可见性更改时选择不同的选项卡

mvvm-light - MVVM Light框架的 "token"方法中的参数 "Register"的用途是什么

wpf - 无法使MVVM Light EventToCommand正常工作

c# - 我可以覆盖 Convert.ToDateTime() 吗?

C# NetworkStream - 在读取时区分关闭的套接字和 0 字节数组

c# - 在基于 View 的WPF应用程序中从ViewModel更改 View

c# - .Net Core CLI 可以从 C# 应用程序中运行吗

c# - 如何在MVVM Light的SimpleIoc中注册一个实现多个接口(interface)的类?