ViewModelのパワー

ViewModelをベースに開発していると画面の作成も普通のクラスと同じような仕組みで開発ができます。これはC#などの仕組みを効果的に使えることを意味しており非常に強力です。

DataEditViewModel

ViewMakerでもViewModelをベースに開発をしています。その中にデータ編集用のDataEditViewModelというクラスがあります。このクラスはIEditableObjectを型パラメータにしてキャンセル可能なデータ編集を行う汎用的なViewModelになっています。

#if !SILVERLIGHT
    [ViewProperty(PanelViewControl.Properties.WindowResizeMode, System.Windows.ResizeMode.NoResize)]
#endif
    [ViewProperty(PanelViewControl.Properties.LoadCommand, "BeginCommand")]
    [ViewProperty(PanelViewControl.Properties.UnloadCommand, "CancelCommand")]
    public class DataEditViewModel<T> : ViewModel where T : IEditableObject
    {
        private const int buttonWidth = 60;

        private bool editing = false;

        [Browsable(true)]
        public T Data { get; set; }

        [Browsable(false)]
        public ICommand BeginCommand { get { return CreateCommand(Begin); } }
        private void Begin()
        {
            Data.BeginEdit();
            editing = true;
        }

        [Display(Name="OK",Order=1)]
        [ViewProperty(ButtonViewControl.Properties.Width, buttonWidth)]
        public ICommand OkCommand { get { return CreateCommand(Ok); } }
        private void Ok()
        {
            if (editing)
            {
                Data.EndEdit();
                editing = false;
            }
            ExecuteViewCommand(ViewCommandId.Close);
        }

        [Display(Name = "Cancel",Order=2)]
        [ViewProperty(ButtonViewControl.Properties.Width, buttonWidth)]
        public ICommand CancelCommand { get { return CreateCommand(Cancel); } }
        private void Cancel()
        {
            if (editing)
            {
                Data.CancelEdit();
                editing = false;
            }
            ExecuteViewCommand(ViewCommandId.Close);
        }

        public DataEditViewModel(T data)
        {
            Data = data;
        }
    }

ViewMaker用の属性がいろいろ入っていますが、コンストラクタで受け取ったデータをBeginCommand、OkCommand、CancelCommandのコマンドで制御するようなシンプルなプログラムです。これだけで以下のようなデータ編集ができるViewModelが作成できます。

ちなみに「[ViewProperty(PanelViewControl.Properties.LoadCommand, "BeginCommand")]」はパネルのロード時にBeginCommandが実行されるようなViewを生成するViewジェネレータに対するメタ情報です。ViewModelは編集が開始される前にBeginCommandが実行されるのであればあとはView側が自由に実装して構わないのですが、そのタイミングとしてロードを使いましょうというヒントになります。ロードの代わりに開始ボタンを用意して編集を開始するようなViewを用意することももちろん可能です。

ViewModelファーストな開発

ViewからViewModelを作成して実装が面倒だと感じている方は、ViewModelを作成してそのうえでViewを作成するような考え方に変えてみると、MVVMが高い生産性や保守性を持っていると感じることができるかもしれません。(考え方を変えるのが一番大変なんですけどね)