4

CanExecute デリゲートで初期化された RelayCommands にバインドされたいくつかのボタンを使用しています。

RelayCommand DeleteCommand;
bool CanDelete()
{
    return BoolProp1 && BoolProp2;
}

...

DeleteCommand = new RelayCommand(Delete, CanDelete);

BoolProp1BoolProp2はセッターが を正しく発生させる通常のプロパティですが、ご存知のように、これは SLがコマンドでPropertyChanged再評価するのに十分ではありません。そのため、両方のセッターCanExecuteも呼び出します。Delete.RaiseCanExecuteChanged()

これはすべて正常に機能します(ボタンは無効になり、適切に有効になります)、ある時点まではすべて停止します。その時点で、呼び出しによってDelete.RaiseCanExecuteChanged()ブレークポイントが起動されなくなりCanDelete()、ボタンは元の状態のままになります。

正確な原因を特定するために 2 時間費やしましたが、効果はありませんでした。RaiseCanExecuteChanged()単一の「バインディング反復」中に複数の呼び出しが何らかの形でメカニズムを壊していると思われます。

ヒントはありますか?私はすでにIsExecutable更新された追加のフィールドを使用することを検討していINotifyPropertyChangedます...

アップデート

RelayCommand実際にはMVVM Light ToolkitGalaSoft.MvvmLight.Command.RelayCommandからのものです。ILSpy は、ICommand の非常に簡単な実装を示しています。

public bool CanExecute(object parameter)
{
    return this._canExecute == null || this._canExecute.Invoke();
}

public void RaiseCanExecuteChanged()
{
    EventHandler canExecuteChanged = this.CanExecuteChanged;
    if (canExecuteChanged != null)
    {
         canExecuteChanged.Invoke(this, EventArgs.Empty);
    }
}

コンストラクターに渡される値に一度設定されます_canExecuteFunc<bool>

私はまだ問題を最小限に再現するために取り組んでいます。

アップデート

私の答えを見てください。

4

2 に答える 2

8

ペブカック。特定のケースで私のフレームワークはコードを実行しました

DeleteCommand = new RelayCommand(Delete, CanDelete);

実際にビューにバインドされていたコマンドを新しいインスタンスで上書きします。

誰かがこの問題を抱えている場合RelayCommand.RaiseCanExecuteChanged()は、ビューがバインドされているのと同じインスタンスで呼び出していることを確認してください。

于 2011-08-03T22:01:32.743 に答える