自分の前の関連エントリ:[WPF][C#]データに知能を持たせる
Rさんのところの関連エントリ:
データに知能を持たせる
データに知能を持たせる(その2)
データに知能を持たせる(その3)
ということで、色々やってるうちに下のような感じで使えるようなものが出来ました。
まずは普通のModelクラス
using System;
namespace Kazuki.MVVMInfra.Test.Models
{
/// <summary>
/// 従業員情報
/// </summary>
public class Employee
{
/// <summary>
/// 従業員番号
/// </summary>
public int ID { get; set; }
/// <summary>
/// 名前
/// </summary>
public string Name { get; set; }
/// <summary>
/// 入社日
/// </summary>
public DateTime? EntDate { get; set; }
}
}
これをViewに公開するためのViewModelクラスは、以下のような感じでいけます。
// ViewModelBaseクラスを継承する
public class EmployeeViewModel : ViewModelBase
{
}
ViewModelのプロパティは、下のように定義していきます。
/// <summary>
/// _model.IDをView用に公開するプロパティ
/// TextBoxにバインドするために文字列型として定義
/// </summary>
public ViewModelProperty<string> ID { get; private set; }
// -------------------------------------------------
// コンストラクタでプロパティの初期化を行う
// IDプロパティは_modelのIDプロパティを文字列として公開する
// 入力値は、整数値に変換できることが必須条件
this.ID = Prop(
// ModelからViewModel用に値を変換するロジックを指定する
() => _model.ID.ToString(),
// ViewModelからModel用に値を変換するロジックを指定する
value => _model.ID = int.Parse(value),
// ViewModelの値を検証するためのロジックを指定する。
// OKの場合nullを返して、NGの場合にはエラーメッセージを返す
value =>
{
int dummy = 0;
return int.TryParse(value, out dummy) ?
null : "従業員IDは、整数値で入力して下さい";
});
単純に値を保持するだけのプロパティでよければ以下のように簡単に定義できるようになっています。
/// <summary>
/// 普通のプロパティ
/// </summary>
public ViewModelProperty<string> Message { get; private set; }
// --------------------------------
// コンストラクタでプロパティの初期化
// Messageプロパティはstring型の普通のプロパティ
this.Message = Prop<string>();
ここで、使用しているPropメソッドは、ViewModelBaseクラスに定義されたprotectedなメソッドです。
ViewModelPropertyクラスのファクトリメソッドをViewModelBaseに持たせることで、ViewModelが、どんなプロパティを持っているかという管理をViewModel内部でこっそり出来るようにしました。
ViewModelBaseクラスとViewModelProperty<T>クラスはIEditableObjectも実装してるので、BeginEdit、EndEdit、CancelEditなどもサポートするようにしてみました。
なので、キャンセル処理とかもお手軽に作ることが出来ます。
どういう風にViewModelとViewModelProperty<T>を作ったかは後で説明するかもしれませんが、とりあえずソースコードをあげておきます。