了解没有 MVVM 的 ICommand 实现

本文关键字:ICommand 实现 MVVM 了解 | 更新日期: 2023-09-27 18:35:47

我正在尝试了解如何使用命令。我读了很多关于命令的信息,我知道,大多数时候命令都是在 MVVM 模式中使用的。我也知道,有一个 RoutedCommand 类 - 它通常用于在开发时节省时间。

但是 - 我想了解基础知识 - 这正是问题所在。来吧:

在我的应用程序中,我定义了一个类"MyCommand":

 public class MyCommand :ICommand
{
    public void Execute(object parameter)
    {
        Console.WriteLine("Execute called!");
        CanExecuteChanged(null, null);
    }
    public bool CanExecute(object parameter)
    {
        Console.WriteLine("CanExecute called!");
        return true;
    }
    public event EventHandler CanExecuteChanged;
}

好吧 - 为了获得静态访问权限,我决定创建一个类,仅用于所有应用程序命令:

 public static class AppCommands
    {
        private static ICommand anyCommand = new MyCommand();
        public static ICommand AnyCommand
        {
            get { return anyCommand; }
        }
    }

快到了。现在我在主窗口中放了两个按钮。其中一个被"绑定"到命令:

<StackPanel>
    <Button Content="Button" Height="23" Name="button1" Width="75" Click="button1_Click" />
    <Button Content="Button" Height="23" Name="button2" Width="75" Command="{x:Static local:AppCommands.AnyCommand}" CommandParameter="Hello"/>
</StackPanel>

这是主窗口.cs :

public MainWindow()

  {
        InitializeComponent();
        AppCommands.AnyCommand.CanExecuteChanged += MyEventHandler;
    }

    private void button1_Click(object sender, RoutedEventArgs e)
    {
       // Nothing for the moment
    }
    private void MyEventHandler(object sender, EventArgs e)
    {
        Console.WriteLine("MyEventHandler called");
    }

所以 - 让我们运行我的项目。如您所见,我制作了一些控制台输出。如果我单击按钮 2,输出为:

可以执行调用!执行调用!可以执行调用!调用的 MyEventHandler

所以,在我看来,这就是发生的事情:1.) 按钮上的命令是"激活"。若要检查是否应调用执行方法,请调用 CanExecute 方法。2.) 如果 CanExecute 方法返回 true,则调用 Execute 方法。3.) 在执行方法中,我定义了应该引发事件"CanExecuteChanged"。调用它将首先检查"CanExecute",然后调用事件处理程序。

这对我来说不清楚。调用事件的唯一方法是在 Execute 方法中。但是执行方法是在检查CanExecute后通过命令逻辑调用的。调用该事件也会检查 CanExecute,但为什么呢?我很困惑。

当我尝试禁用按钮时,事情变得越来越混乱。比方说,有一个"CommandParameter" - 并且"CanExecute"现在可以使用它。因此,该方法返回 false。在这种情况下,按钮被禁用 - 好的。

但是:如何重新激活它?正如我们已经知道的:我只能从我的命令类中引发 CanExecuteChange 事件。因此 - 由于我们无法单击禁用的按钮 - 该命令不会调用 CanExecute(甚至执行)方法。

在我看来,有一些重要的东西我看不到——但我真的找不到它。

你能帮帮我吗?

了解没有 MVVM 的 ICommand 实现

你的CanExecuteChanged不应该被Execute引发,当CanExecute开始返回不同的值时,它应该被引发。何时取决于您的命令类。在最简单的形式中,您可以添加一个属性:

public class MyCommand : ICommand
{
    bool canExecute;
    public void Execute(object parameter)
    {
        Console.WriteLine("Execute called!");
    }
    public bool CanExecute(object parameter)
    {
        Console.WriteLine("CanExecute called!");
        return CanExecuteResult;
    }
    public event EventHandler CanExecuteChanged;
    public bool CanExecuteResult
    {
        get { return canExecute; }
        set {
            if (canExecute != value)
            {
                canExecute = value;
                var canExecuteChanged = CanExecuteChanged;
                if (canExecuteChanged != null)
                    canExecuteChanged.Invoke(this, EventArgs.Empty);
            }
        }
    }
}