ICommandインターフェイスの実装を簡略化する
前回私のブログ(http://azumal.hatenablog.com/entry/2014/04/13/105502)で MVVM のサンプルプログラムを公開しました。
サンプルの中で ICommand インターフェイスを実装したクラスを定義していましたが、下記の記事を読んで、もっと簡単に実装できることがわかりました。
「Model-View-ViewModel デザイン パターンによる WPF アプリケーション」
(http://msdn.microsoft.com/ja-jp/magazine/dd419663.aspx#id0090030)
上記記事で紹介されている RelayCommand クラスを利用することで、
コマンドの定義を簡略化することができます。
「MainWindowViewModel」クラス(RelayCommand での実装)
public class MainWindowViewModel {
public Person RegisteredPerson { get; set; }
public ObservableCollection<Person> People { get; set; }
public ICommand RegisterPersonCommand { get; set; }
public ICommand CancelCommand { get; set; }
public List<Sexes> Roles { get; set; }
public MainWindowViewModel() {
People = new ObservableCollection<Person>();
RegisteredPerson = new Person();
RegisterPersonCommand = new RelayCommand(param => this.RegisterPerson(param));
CancelCommand = new RelayCommand(param => this.Cancel(param));
}
public void RegisterPerson(object parameter) {
var p = (Person)parameter;
People.Add(new Person(p.PersonID, p.FirstName, p.LastName, p.Sex, p.BirthDay));
RegisteredPerson.PersonID++;
RegisteredPerson.FirstName = string.Empty;
RegisteredPerson.LastName = string.Empty;
RegisteredPerson.Sex = Sexes.男性;
RegisteredPerson.BirthDay = DateTime.Today;
}
public void Cancel(object parameter) {
var p = (Person)parameter;
p.PersonID = People.Max<Person>(u => u.PersonID) + 1;
p.FirstName = string.Empty;
p.LastName = string.Empty;
p.Sex = Sexes.男性;
p.BirthDay = DateTime.Today;
}
}
「MainWindowViewModel」クラス(前回ブログより ICommand での実装)
public class MainWindowViewModel {
public Person RegisteredPerson { get; set; }
public ObservableCollection<Person> People { get; set; }
public ICommand RegisterPersonCommand { get; set; }
public ICommand CancelCommand { get; set; }
public List<Sexes> Roles { get; set; }
public MainWindowViewModel() {
People = new ObservableCollection<Person>();
RegisteredPerson = new Person();
RegisterPersonCommand = new RegisterPerson(this);
CancelCommand = new Cancel(this);
}
}
public class RegisterPerson : ICommand {
private ObservableCollection<Person> _people;
private Person _person;
public RegisterPerson(MainWindowViewModel view) {
_people = view.People;
_person = view.RegisteredPerson;
}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter) {
return true;
}
public void Execute(object parameter) {
var p = (Person)parameter;
_people.Add(new Person(p.PersonID, p.FirstName, p.LastName, p.Sex, p.BirthDay));
_person.PersonID++;
_person.FirstName = string.Empty;
_person.LastName = string.Empty;
_person.Sex = Sexes.男性;
_person.BirthDay = DateTime.Today;
}
}
public class Cancel : ICommand {
private ObservableCollection<Person> _people;
public Cancel(MainWindowViewModel view) {
_people = view.People;
}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter) {
return true;
}
public void Execute(object parameter) {
var p = (Person)parameter;
p.PersonID = _people.Max<Person>(u => u.PersonID) + 1;
p.FirstName = string.Empty;
p.LastName = string.Empty;
p.Sex = Sexes.男性;
p.BirthDay = DateTime.Today;
}
}
いかがでしょうか。
RelayCommand クラスを定義しておくだけで、コマンドのために実装するコード量が削減されたと共に、MainWindowViewModel クラスにコマンドの実装が内包されています。MSDN マガジンに感謝です!