Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 理解没有MVVM的ICommand实现_C#_Wpf_Mvvm_Command Pattern - Fatal编程技术网

C# 理解没有MVVM的ICommand实现

C# 理解没有MVVM的ICommand实现,c#,wpf,mvvm,command-pattern,C#,Wpf,Mvvm,Command Pattern,我试图理解如何使用命令。 我读了很多关于命令的书,我知道大多数时候命令都是在MVVM模式中使用的。我还知道,有一个RoutedCommand类,通常用于在开发时节省时间 但是-我想了解基本知识-这正是问题所在。我们开始: 在我的应用程序中,我定义了一个类“MyCommand”: public class MyCommand :ICommand { public void Execute(object parameter) { Console.WriteLine(

我试图理解如何使用命令。 我读了很多关于命令的书,我知道大多数时候命令都是在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>
所以,让我们运行我的项目。如您所见,我制作了一些控制台输出。 如果单击按钮2,输出为:

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

所以,在我看来,这就是发生的事情: 1.)按钮上的命令为“激活”。为了检查是否应该调用execute方法,将调用CanExecute方法。 2.)如果CanExecute方法返回true,则调用Execute方法。 3.)在execute方法中,我定义应该引发事件“CanExecuteChanged”。调用它将首先检查“CanExecute”,然后调用eventhandler

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

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

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

在我看来,有些重要的东西我看不见,但我真的找不到


您能帮助我吗?

您的
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);
            }
        }
    }
}

我已经修改了您的标签,使其围绕问题主题更广泛。我选择了WPF,但不确定是这个还是Silverlight/WP。太好了!解决方法是如此简单,以至于很痛:)非常感谢你-你让我开心!你能把整个项目的文件放在你的答案里吗?@Fulproof这是个奇怪的问题。一大堆不可读的XML不会改善这个答案,所以我很想说不,我不打算这么做。但如果你能解释一下你遇到的任何问题,我很乐意看一看。@hvd,谢谢,我已经看过了
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);
            }
        }
    }
}