了解没有MVVM的ICommand实现

Cod*_*bal 2 c# wpf mvvm command-pattern

我试图了解如何使用命令.我读了很多关于命令的知识,我知道,大多数时候命令都是在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;
}
Run Code Online (Sandbox Code Playgroud)

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

 public static class AppCommands
    {
        private static ICommand anyCommand = new MyCommand();

        public static ICommand AnyCommand
        {
            get { return anyCommand; }
        }
    }
Run Code Online (Sandbox Code Playgroud)

就快到了.现在我在MainWindow中放了两个按钮.其中一个是"绑定"到命令:

<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>
Run Code Online (Sandbox Code Playgroud)

这是MainWindow.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");
    }
Run Code Online (Sandbox Code Playgroud)

所以 - 让我们运行我的项目.如您所见,我制作了一些控制台输出.如果我点击button2,输出结果为:

CanExecute叫了!执行叫!CanExecute叫了!MyEventHandler打来电话

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

这对我来说并不清楚.调用事件的唯一方法是在Execute方法中.但是在检查CanExecute之后,通过命令逻辑调用Execute方法.调用事件也检查CanExecute,但为什么?我很迷惑.

当我尝试禁用按钮时,事情变得更加困惑.可以说,有一个'CommandParameter' - 'CanExecute'现在可以使用它.所以可能是,该方法返回false.在这种情况下,按钮被禁用 - 好吧.

但是:我该如何重新激活它?我们已经知道:我只能在命令类中引发CanExecuteChange事件.所以 - 因为我们无法单击禁用按钮 - 该命令不会调用CanExecute(甚至是Execute)方法.

在我看来有一些我看不到的重要事项 - 但我真的找不到它.

请你帮助我好吗?

小智 5

CanExecuteChangedExecute应该被提出,当它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);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)