2011-08-03 1 views
3

CanExecuteデリゲートで初期化されたRelayCommandsにバインドされたボタンを使用しています。RelayCommand RaiseCanExecuteChanged()が失敗します。

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

... 

DeleteCommand = new RelayCommand(Delete, CanDelete); 

BoolProp1BoolProp2が正しくPropertyChangedを上げるセッターとの定期的な性質であるが、我々はすべて知っているように、これはコマンドにSLの再評価CanExecuteを作るのに十分ではありません。それで私は両方のセッターでDelete.RaiseCanExecuteChanged()とも呼ぶのです。

これはすべて正常に動作します(ボタンは無効になり、適切に有効になります)。その時点で、Delete.RaiseCanExecuteChanged()を呼び出すと、もはやCanDelete()に私のブレークポイントが発生せず、ボタンは永遠にそのまま残っています。

実際の原因を特定するのに2時間を費やしています。私は単一の "バインディング反復"の間に何とか複数のメカニズムを破ると複数の疑問がある。

ヒント私はすでにINotifyPropertyChangedてリフレッシュ追加IsExecutableフィールドを使用して検討している...

UPDATE

RelayCommandは実際にMVVM Light ToolkitからGalaSoft.MvvmLight.Command.RelayCommandです。 _canExecuteは、コンストラクタに渡された値を一度設定Func<bool>ことで

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

:ILSpyはのICommandの非常に簡単な実装を示しています。

私はまだ問題を最小限に再現するよう努めています。

UPDATE

私の答えを参照してください。

+1

コードを投稿してください。 RelayCommandExとは何ですか?コマンドの実装はどのように見えますか?可能であれば、非常にシンプルなreproを作成し、完全なコードを投稿してください。 –

+0

'' RelayCommandEx''は、これを処理しようとして失敗しました(CanExecute()値をキャッシュしようとしましたが、必要ない場合はCanExecuteChangedを起動しませんでした)。 –

+1

私はこれに執着する漠然とした思い出を持っています、そして、何かと関係がありました(私のケースではWPFボタンだと思います)、EventHandlerと弱い参照をキャッシュしていませんでした。私は時間があるときのことを理解しようとしますが、あなたを正しい道に導くのに役立ちます。 CanExecuteChangedイベントの追加/削除アクセサを実装して、削除時にブレークポイントを設定して、いつ削除するかを確認することができます。 – CodeNaked

答えて

6

PEBKAC。場合によっては私のフレームワークは、実際に新しいインスタンスで表示するように実際にバインドされたコマンドを上書きするコードを複数回実行しました。

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

関連する問題