C# 如何启用/禁用按钮?

C# 如何启用/禁用按钮?,c#,wpf,mvvm,controls,C#,Wpf,Mvvm,Controls,虽然我已经找到了这个问题的几个答案,但不知怎么的,我还是不明白。所以请原谅我问 我有一个遵循MVVM模式的WPF应用程序。它包含一个按钮,该按钮绑定到视图模型中的命令: 这些命令使用的是RelayCommand。现在我想做以下几点: 用户单击按钮并执行相应的命令。这很有效 在该命令中,另一个按钮应被停用,即不可点击 我发现使用CanExecute应该可以做到这一点,但老实说:我就是不明白。我可以将按钮设置为启用/禁用吗 这是RelayCommand.cs: namespace MyApp.

虽然我已经找到了这个问题的几个答案,但不知怎么的,我还是不明白。所以请原谅我问

我有一个遵循MVVM模式的WPF应用程序。它包含一个按钮,该按钮绑定到视图模型中的命令:

这些命令使用的是
RelayCommand
。现在我想做以下几点:

  • 用户单击按钮并执行相应的命令。这很有效
  • 在该命令中,另一个按钮应被停用,即不可点击
我发现使用
CanExecute
应该可以做到这一点,但老实说:我就是不明白。我可以将按钮设置为启用/禁用吗

这是RelayCommand.cs:

namespace MyApp.Helpers {
    class RelayCommand : ICommand {

    readonly Action<object> execute;
    readonly Predicate<object> canExecute;

    public RelayCommand(Action<object> execute) : this(execute, null) {
    }

    public RelayCommand(Action<object> execute, Predicate<object> canExecute)
    {
      if (execute == null)
          throw new ArgumentNullException("execute");

      this.execute = execute;
      this.canExecute = canExecute;           
    }

    public bool CanExecute(object parameter)
    {
      return canExecute == null ? true : canExecute(parameter);
    }

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

  public void Execute(object parameter)
  {
      execute(parameter);
  }
 }
}

创建RelayCommand对象时,必须传递can谓词,该谓词可以是(除其他外)具有以下签名的方法:

布尔方法名(对象参数)

如果不需要该参数,请使用例如bool MethodName(),但将其传递给RelayCommand构造函数,如下所示:(o)=>MethodName()


在这个方法中,您应该执行逻辑并返回一个值,指示是否可以执行命令。其余部分应由WPF命令基础结构处理。

创建RelayCommand对象时,必须传递一个can谓词,该谓词可以是(除其他外)具有以下签名的方法:

布尔方法名(对象参数)

如果不需要该参数,请使用例如bool MethodName(),但将其传递给RelayCommand构造函数,如下所示:(o)=>MethodName()


在这个方法中,您应该执行逻辑并返回一个值,指示是否可以执行命令。其余部分应由WPF命令基础结构处理。

使用RelayCommand时,可以指定两种方法。第一个方法是调用命令时要运行的主方法。第二种方法用于外接程序检查,如验证,这将返回bool。如果返回false,那么main方法将不会运行

它如何影响命令绑定到的按钮,是它将持续运行布尔方法,当它返回false时,命令绑定到的按钮将被禁用

因此,在命令属性中:

public ICommand GetProjectListCommand {
get {
    if (getProjectListCommand == null) {
        getProjectListCommand = new RelayCommand(param => this.ProjectLogin(), CanProjectLogin());
    }
    return getProjectListCommand;
}
添加新方法:

public bool CanProjectLogin()
{
    //here check some properties to make sure everything is set that you'd want to use in your ProjectLogin() method
}

如果在bool方法中设置断点,则可以看到CanExecute的工作方式。

使用RelayCommand时,可以指定两种方法。第一个方法是调用命令时要运行的主方法。第二种方法用于外接程序检查,如验证,这将返回bool。如果返回false,那么main方法将不会运行

它如何影响命令绑定到的按钮,是它将持续运行布尔方法,当它返回false时,命令绑定到的按钮将被禁用

因此,在命令属性中:

public ICommand GetProjectListCommand {
get {
    if (getProjectListCommand == null) {
        getProjectListCommand = new RelayCommand(param => this.ProjectLogin(), CanProjectLogin());
    }
    return getProjectListCommand;
}
添加新方法:

public bool CanProjectLogin()
{
    //here check some properties to make sure everything is set that you'd want to use in your ProjectLogin() method
}

如果在bool方法中添加断点,您可以看到CanExecute的工作方式。

如果在使用CanExecute回调时遇到问题,您可能会发现使用更简单版本的RelayCommand更容易:

class RelayCommand : ICommand 
{
    readonly Action execute;
    private bool canExecute;

    public RelayCommand(Action execute) 
    {
        this.execute = execute;
        this.canExecute = true;
    }

    public bool CanExecute(object parameter)
    {
        return canExecute;
    }

    public void SetCanExecute(bool canExecute)
    {
        this.canExecute = canExecute;
        var handler = CanExecuteChanged;
        if (handler != null) handler(this, EventArgs.Empty);
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        execute();
    }
}
使用这种方法,可以保存对所创建的RelayCommand对象的引用,从而可以禁用如下命令:

getProjectListCommand.SetCanExecute(false);

如果您在使用canExecute回调时遇到问题,您可能会发现使用更简单版本的RelayCommand更容易:

class RelayCommand : ICommand 
{
    readonly Action execute;
    private bool canExecute;

    public RelayCommand(Action execute) 
    {
        this.execute = execute;
        this.canExecute = true;
    }

    public bool CanExecute(object parameter)
    {
        return canExecute;
    }

    public void SetCanExecute(bool canExecute)
    {
        this.canExecute = canExecute;
        var handler = CanExecuteChanged;
        if (handler != null) handler(this, EventArgs.Empty);
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        execute();
    }
}
使用这种方法,可以保存对所创建的RelayCommand对象的引用,从而可以禁用如下命令:

getProjectListCommand.SetCanExecute(false);

能否显示两个命令的
Execute
CanExecute
的代码?添加了命令用法。但是实际上,我没有
Execute
CanExecute
的代码,除了
RelayCommand
类中的代码。谢谢Robert。按钮的启用/禁用会自动绑定到
命令。CanExecute
,因此您需要让Button1在运行时将
CanButton2Execute
设置为false,然后按钮2将被禁用。能否显示两个命令的
Execute
CanExecute
的代码?添加了命令用法。但是实际上,我没有
Execute
CanExecute
的代码,除了
RelayCommand
类中的代码。谢谢Robert。按钮的启用/禁用会自动绑定到
命令。CanExecute
因此您需要让Button1在运行时将
CanButton2Execute
设置为false,然后Button2将被禁用。忘记指定:将谓词作为构造函数中的第二个参数传递:new RelayCommand(param=>this.ProjectLogin(),param=>this.MethodName())谢谢,这个注释与emybobs答案结合在一起只是让它正确:-)忘记指定:将谓词作为构造函数中的第二个参数传递:new RelayCommand(param=>this.ProjectLogin(),param=>this.MethodName())谢谢,此注释与emybobs答案相结合,正好说明问题:-)此解释使我可以理解:-)但是,第二个参数缺少param=>语句。此解释使我可以理解:-)但是,第二个参数缺少param=>语句。