POCO プロパティと TextBox の間のデータ バインディングをセットアップしたい状況に遭遇しました。もちろん、BindingSource とコントロールの DataBindings コレクションを使用してこれを行うことができますが、BindingSource は DataSource と DataMember の両方を想定しており、実際には POCO フレンドリーではありません。(BindingSource は、いわば単一の行ではなく、表形式のデータ ソースを想定しているようです。) したがって、DataSource はありましたが、DataMember はありませんでした。
リフレクションを使用して、POCO オブジェクトとプロパティをバインド先の文字列として渡す TextBox 拡張メソッドでこれを実現しました。
public static void Bind(this TextBox textBox, object dataObject, string propertyName)
{
PropertyInfo property = dataObject.GetType().GetProperty(propertyName);
textBox.Text = property.GetValue(dataObject, null).ToString();
textBox.TextChanged += delegate(object sender, EventArgs e)
{
PropertyInfo pi = dataObject.GetType().GetProperty(propertyName);
pi.SetValue(dataObject, textBox.Text, null);
};
}
私の状況では、呼び出しコードは次のようになります。
tbProjectConnection.Bind(_modelBuilder, "ProjectConnection");
tbOutputFolder.Bind(_modelBuilder, "OutputFolder");
chkWebMatrix.Bind(_modelBuilder, "UseWebMatrix");
tbNamespace.Bind(_modelBuilder, "ProjectNamespace");
tbDbClassName.Bind(_modelBuilder, "DbClassName");
この例では、_modelBuilder は DataSet オブジェクトであり、表示されるプロパティ ("ProjectConnection"、"OutputFolder" など) は、データセット内のレコードではなく、データセット全体の単純な文字列プロパティです。
プロパティ名を文字列として渡すことに夢中になっているわけではなく、この関数をラムダとして書き直すことができるかどうか疑問に思っているので、呼び出されると次のようになります。
tbProjectConnection.Bind(property => _modelBuilder.ProjectConnection);
tbOutputFolder.Bind(property => _modelBuilder.OutputFolder);
私はラムダの初心者なので、どんな助けでも大歓迎です!