ICommandを実装したクラスがINotifyPropertyChangedを実装して良いか
私はいまMVVMパターンを試している。MVVMパターンの説明は割愛する。
ViewModelはMyCommand(ICommandを実装したクラス)クラスのプロパティを公開し、Viewはそれを添付プロパティにバインドする。XAML部分を書くと、こんな感じ。
<Button local:CommandService.Command="{Binding UpdateCommand}" />
で、次にICommand.CanExecute()を生かして、有効無効を切り替えることにした。けれども、メソッドはXAMLとの連携には向かない(と思う)ので、IsEnabledプロパティを用意した。コードで書くと、こんな感じ。
public class MyCommand : ICommand { /* 略 */ private bool _IsEnabled; public bool IsEnabled { get { return this._IsEnabled; } set { this._IsEnabled = value; var h = CanExecuteChanged; if (h != null) h(this, EventArgs.Empty); } } public bool CanExecute(object parameter) { return this.IsEnabled; } /* 略 */ }
使い方としては、適当にValidateして、実行できそうならIsEnabledをtrueにする。メソッドの処理が軽く、プロパティの処理が重いってどうなんだ、という気はするけど、それはおいておく。
で、本題。このMyCommandはINotifyPropertyChangedを実装していいものだろうか。要するに以下のコードはありかどうかってこと。
<Button local:CommandService.Command="{Binding UpdateCommand}" IsEnabled="{Binding UpdateCommand.IsEnabled}" />
ViewModel.UpdateCommandプロパティ(MyCommand型)はView側に公開されていて、MyCommand.IsEnabledプロパティは変更がかかる。最初、CanExecuteChangedイベントのハンドラーでIsEnabledの変更をかけていたのだけど、Buttonの参照の扱いが面倒だし、こちらの方が良い気がしている。