例えばこんな ViewModel があるとします。
public class CustomerViewModel : ViewModelBase { private Customer _model; private Command _loadCommand; public CustomerViewModel() { _model = new Customer(); _loadCommand = new Command("Load"); _loadCommand.Executed += loadCommand_Executed; } public Command LoadCommand { get { return _loadCommand; } } public string Code { get { return _model.Code; } set { if (_model.Code == value) { return; } _model.Code = value; OnPropertyChanged("Code"); } } public string Name1 { get { return _model.Name1; } set { if (_model.Name1 == value) { return; } _model.Name1 = value; OnPropertyChanged("Name1"); } } public string Name2 { get { return _model.Name2; } set { if (_model.Name2 == value) { return; } _model.Name2 = value; OnPropertyChanged("Name2"); } } private void loadCommand_Executed(object sender, ExecutedEventArgs e) { // ここに Model を取得して差し替える処理を記述する。 } }
Silverlight で作成&未完成です。あと ViewModelBase は INotifyPropertyChanged インタフェースを実装しただけのクラスです。
LoadCommand を実行したときビジネスロジックを呼び出して Model を取得し、_model フィールドに代入しようと思っています。でも _model を差し替えるだけでは PropertyChanged イベントが発生しないので View の内容が更新されません。
私の頭で思いつく対策は、今のところ次の2つ。
- 新しい Model を _model に代入しないで、ViewModel の Code プロパティや Name1 プロパティを使って値をコピーする
private void loadCommand_Executed(object sender, ExecutedEventArgs e) { // ビジネスロジックを呼び出して Model を取得 var model = SampleBusinessLogic.Load(Code); // プロパティをコピー this.Code = model.Code; this.Name1 = model.Name1; this.Name2 = model.Name2; }
- 新しい Model を _model に代入したあと、OnPropertyChanged メソッドを View に公開しているプロパティのぶんだけ呼び出す
private void loadCommand_Executed(object sender, ExecutedEventArgs e) { // ビジネスロジックを呼び出して Model を取得 // _model に代入 this._model = SampleBusinessLogic.Load(Code); // OnPropertyChanged をまとめて呼び出す OnPropertyChanged("Code"); OnPropertyChanged("Name1"); OnPropertyChanged("Name2"); }
ただ、これらの方法だと Model のプロパティが増えた場合に ViewModel に新しいプロパティを追加するだけじゃなく、そのプロパティに値をコピーするか OnPropertyChanged メソッドを呼び出すコードも書く必要があります。
なにか上手いやり方が無いんだろうか…?