Xamarin(C#)で、メンバ変数変更時に自動で値を表示するような事をやってみたかった。の続きです。
C#にはgenericsがあるので、「値がセットされたらEventHandlerを呼び出すクラス」は作れるなぁと思ったので作ってみました。
ただ、このような仕組みというか考え方は、きっと誰かがすでに考えてるはずなので、C#に組み込まれてるとか、オープンソースで公開されてるとかがあるはずです。あるはずなのですが、それをググるためのキーワードが思い付きませんでした。誰か教えてください。
namespace HelloDatePicker
{
// このWrapper<>相当のもの、C#の標準品であってもおかしくない、とは思うけど
// 何になるのかがわからない
// Instanceの入れ替えには反応できるけど、Instanceの中内容の変化には事には対応できないので
// 不完全な実装。
public class Wrapper<Type>
{
private Type _instance;
public Type Instance {
get {
return _instance;
}
set {
_instance = value;
if (this.updateHandler != null) {
this.updateHandler (this, _instance);
}
}
}
// Instanceが変更されたら、このEventHandlerが呼び出される
public event EventHandler<Type> updateHandler;
}
[Activity (Label = "HelloDatePicker", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity
{
private TextView dateDisplay;
private Button pickDate;
private Wrapper<DateTime> dateWrapper; // DateTimeをラップしている
protected override void OnCreate (Bundle savedInstanceState)
{
base.OnCreate (savedInstanceState);
SetContentView (Resource.Layout.Main);
// capture our View elements
dateDisplay = FindViewById<TextView> (Resource.Id.dateDisplay);
pickDate = FindViewById<Button> (Resource.Id.pickDate);
// ラッパーをセット
this.dateWrapper = new Wrapper<DateTime> ();
// add a click event handler to the button
pickDate.Click += delegate {
DateTime date = this.dateWrapper.Instance;
DatePickerDialog dialog = new DatePickerDialog (this, OnDateSet, date.Year, date.Month - 1, date.Day);
dialog.Show ();
};
// this.dateが変更されたらdateDisplayに反映するイベント登録
this.dateWrapper.updateHandler += delegate(object sender, DateTime e) {
this.dateDisplay.Text = e.ToString ("d");
};
// .Instanceが邪魔だよなぁ。
this.dateWrapper.Instance = DateTime.Today;
}
// the event received when the user "sets" the date in the dialog
void OnDateSet (object sender, DatePickerDialog.DateSetEventArgs e)
{
// DatePickerDelegateで設定おされたら呼び出される
// this.dateを更新してるだけ。
this.dateWrapper.Instance = e.Date;
}
}
}