在 ViewModelBase 中调用 CommandManager.InvalidateRequerySuggested?

Calling CommandManager.InvalidateRequerySuggested in ViewModelBase?

初始问题:
我在我的 MVVM 应用程序中使用典型的 RelayCommand 实现。 我意识到我的 RelayCommandCanExecute 并不总是被调用,即使我的 ViewModel 的有意义的属性已经改变。

我读到我们可以手动调用 CommandManager.InvalidateRequerySuggested 来引发 RequerySuggested 事件。这最终将使命令源调用 CanExecute 方法。

当某些 UI 事件发生时,

RequerySuggestedCommandManager 自动引发。我觉得如果在 PropertyChanged.

上也提出它会很有用

我目前的解决方案:
我修改了我的 ViewModelBase class 的 属性 更改方法,如下所示:

protected virtual void OnPropertyChanged(string propertyName)
{
    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    Application.Current.Dispatcher?.Invoke(CommandManager.InvalidateRequerySuggested);
}

顾虑:
我还没有在网上找到任何 ViewModelBase 以这种方式实现的,我觉得这应该是一个危险信号。

RelayCommand 在 MVVM 中被强烈推荐,因为它很简单,所以我发现我最终不得不手动调用 CommandManager 很奇怪。那为什么不喜欢 DelegateCommand 呢?

我知道这会导致 CanExecute 被更频繁地调用,但无论如何每次 UI 事件发生时它都已经被垃圾邮件发送了。

"typical"中继命令?

如果您使用的是 MVVMLight 的中继命令,则来源是:

https://github.com/lbugnion/mvvmlight/blob/master/GalaSoft.MvvmLight/GalaSoft.MvvmLight%20(PCL)/Command/RelayCommand.cs

您可以在中继命令上调用 CanExecutechanged。

将 using 语句添加到任何视图模型时,请确保使用 CommandWPF 版本。

当有用户输入事件时调用InvalidateRequerySuggested。因此,当用户输入任何内容并更改 属性 时,您将提高它两次,而您提高 属性changed on。这意味着你的方法是个坏主意。

很少有数据在 属性 到 属性 的基础上从模型传输到视图模型。更常见的是引发事件,然后视图模型将视图模型中的数据组合到属性中。您可能只在获得新记录或更改事件后立即引发 canexecutechanged 一次,或者您的数据更改发生在它们不是用户输入驱动时。