1

视图上有不同的按钮,在执行命令时如何控制按钮的 IsEnabled 状态?

如果我执行这个命令:

public ICommand DoSomethingCommand
{
  get
  {
    if (doSomethingCommand == null)
    {
      doSomethingCommand = new RelayCommand(
        (parameter) =>
          {
            this.IsBusy = true;
            this.someService.DoSomething(
              (b, m) =>
                {
                  this.IsBusy = false;
                }
              );
          },
        (parameter) => !this.IsBusy);
    }
    return this.doSomethingCommand ;
  }
}

我设置了触发 OnPropertyChanged 事件的 IsBusy 属性。所有其他按钮在其命令的 CanExecute 中检查此属性。但是,当执行上述命令时,按钮不会被禁用。

我该怎么做?

4

2 回答 2

1

为什么不在您自己的 RelayCommand 类的自定义版本上实现 INotifyPropertyChanged。这将符合 MVVM:

public class RelayCommand : ICommand, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private readonly Action execute;
    private readonly Func<bool> canExecute;

    private bool isBusy;
    public bool IsBusy
    {
        get { return isBusy; }   
        set
        {
            isBusy = value;
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs("IsBusy"));
            }
        }
    }

    public event EventHandler CanExecuteChanged
    {
        add
        {
            if (this.canExecute != null)
            {
                CommandManager.RequerySuggested += value;
            }
        }
        remove
        {
            if (this.canExecute != null)
            {
                CommandManager.RequerySuggested -= value;
            }
        }
    }

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

    public RelayCommand(Action execute, Func<bool> canExecute)
    {
        if (execute == null)
        {
            throw new ArgumentNullException("execute");
        }
        this.execute = execute;
        this.canExecute = canExecute;
    }

    public void Execute(object parameter)
    {
        this.IsBusy = true;
        this.execute();
        this.IsBusy = false;
    }

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

然后使用这样的命令:

<Button Command="{Binding Path=DoSomethingCommand}" 
        IsEnabled="{Binding Path=DoSomethingcommand.IsBusy, 
            Converter={StaticResource reverseBoolConverter}}" 
        Content="Do It" />
于 2012-04-25T09:28:17.493 回答
1

CanExecuteChanged 需要触发,以便命令源知道调用 CanExecute。

一个简单的方法是调用CommandManager.InvalidateRequerySuggested().

bool _isBusy;
public bool IsBusy
{
    get { return _isBusy; }
    set
    {
        if (value == _isBusy)
            return;
        _isBusy = value;
        //NotifyPropertyChanged("IsBusy"); // uncomment if IsBusy is also a Dependency Property
        System.Windows.Input.CommandManager.InvalidateRequerySuggested();
    }
}
于 2012-04-25T07:52:54.420 回答