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

コマンドソースがCanExecuteを呼び出すことを認識するために、CanExecuteChangedを起動する必要があります。

これを行う簡単な方法は、を呼び出すこと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 に答える
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 に答える