c# - 在这种情况下如何调用 ICommand.CanExecute?

标签 c# .net wpf xaml mvvm

好的。这是场景。这是 WPF + MVVM (.net 4.0) 应用程序:

  1. View:有一个 DataGrid 和两个按钮 Move Up/Move Down,它们应该在 DataGrid 中向上或向下移动选定的记录。网格和按钮都使用基于 XAML 的绑定(bind)。
  2. ViewModel:具有 DataView 类型的公共(public)属性,我的 DataGrid 将绑定(bind)到该类型。然后就是下面列出的两个ICommand实现。这两个按钮将绑定(bind)到这两个命令。最后但并非最不重要的是,有两个名为 MoveUp()MoveDown() 的函数可以完成显而易见的任务。
  3. 两个ICommand实现:在每个命令中,CanExecute()分别返回所选记录是否可以向上或向下移动,Execute() 实际上是通过调用我上面描述的 ViewModel 的 MoveUp()MoveDown() 函数来移动记录。这些命令对象在其构造函数中获取 VM 对象的引用。

首先,我想知道这个架构是否正确并符合 MVVM 模式?其次,手头的问题是,当我更改 DataGrid 中的选定记录时,我的按钮没有启用/禁用,这带来了 2 个子问题:

  1. 谁调用 CanExecute() 以及何时调用?
  2. 如何手动调用它?在阅读了一些其他 SO 问题后,我尝试了 CommandManager.InvalidateRequerySuggested(),但这也没有帮助。

这是我的 CommandBase 类,我的两个 Command 类都继承自该类:

internal abstract class CommandBase : DependencyObject, ICommand
{
    public virtual bool CanExecute(Object parameter)
    {
        return true;
    }

    public abstract void Execute(Object parameter);
    public event EventHandler CanExecuteChanged;

    protected void OnCanExecuteChanged(Object sender, EventArgs e)
    {
        CanExecuteChanged(sender, e);
    }
}

最佳答案

I want to know if this architecture correct and in line with MVVM pattern?

是的,这完全符合 MVVM 模式。


Who calls CanExecute() and when?

只要引发 CanExecuteChanged 事件,就会调用 CanExecute()。

命令在内部 Hook 此事件并启用/禁用按钮或任何基于 CanExecute 委托(delegate)返回的 bool 属性的 frameworkElement


How can I call it manually?

首先在您的具体实现中创建 RaiseCanExecuteChanged() 方法(如果尚未创建),以便可以手动调用它。这看起来像这样:

    public void RaiseCanExecuteChanged()
    {
        EventHandler canExecuteChangedHandler = CanExecuteChanged;
        if (canExecuteChangedHandler != null)
        {
           canExecuteChangedHandler(this, EventArgs.Empty);
        }
    }

因为在您的情况下,只要 dataGrid 中的 SelectedItem 发生变化,您就需要调用 CanExecute()。我建议将 DataGrid 的 SelectedItem 绑定(bind)到您的 ViewModel 和 setter 中的某些属性,您手动调用 RaiseCanExecuteChanged() 以便可以在您的命令实例上调用 CanExecute。


但是,如果您不想手动调用 RaiseCanExecuteChanged() 方法,还有另一种方法。您可以 Hook CommandManager.RequerySuggested 事件,只要 CommandManager 感觉 UI 需要刷新,就会引发该事件。

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

RequerySuggested event Occurs when the System.Windows.Input.CommandManager detects conditions that might change the ability of a command to execute.

因此,无论何时引发 CommandManager.RequerySuggested,它最终都会引发您的 CanExecuteChanged,从而调用您的命令的 CanExecute。因此,基于 CanExecute 委托(delegate)返回的 bool 值启用/禁用按钮。

关于c# - 在这种情况下如何调用 ICommand.CanExecute?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21647872/

相关文章:

c# - 装箱值只是指向存储在托管堆中的值副本的指针吗?

c# - 如何在 C# 中不使用绝对路径访问/打开文件?

c# - MVC4中基于下拉选择的FluentValidation Rule依赖验证

c# - .NET 中应用程序域的常见用途和最佳实践?

c# - 将 DependencyProperty 的值设置为 ViewModel 属性

c# - 如何合并集合中的两个源并在组合框中正确显示它们?

c# - IIS 应用程序上的 ProtectedData.Unprotect - 在 IISRESET 后无法工作

c# - C# 中具有两个泛型参数的泛型方法

c# - 代码优先,当我启用迁移时,我得到 “No context type was found in the assembly ' DOC'”

c# - 可以将事件的 Microsoft Word 窗口转换到 WPF 窗口吗?