I ran into a situation where I wanted to setup some data binding between a POCO property and a TextBox. You can do this with a BindingSource and a control's DataBindings collection, of course, but a BindingSource expects both a DataSource and DataMember, and is not POCO-friendly, really. (A BindingSource seems to expect a tabular data source instead of a single row, as it were.) So, I had a DataSource, but no DataMember.
I accomplished this with this a TextBox extension method using reflection, passing the POCO object and property to bind to as a string:
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);
};
}
In my situation, the calling code looks like this:
tbProjectConnection.Bind(_modelBuilder, "ProjectConnection");
tbOutputFolder.Bind(_modelBuilder, "OutputFolder");
chkWebMatrix.Bind(_modelBuilder, "UseWebMatrix");
tbNamespace.Bind(_modelBuilder, "ProjectNamespace");
tbDbClassName.Bind(_modelBuilder, "DbClassName");
In my example, _modelBuilder is a DataSet object and the properties shown ("ProjectConnection", "OutputFolder", etc) are simple string properties of the DataSet--not of records in the dataset, but of the dataset as a whole.
I'm not crazy about passing a property name as a string, and wonder if it's possible to re-write this function as a lambda, so it looks like this when called:
tbProjectConnection.Bind(property => _modelBuilder.ProjectConnection);
tbOutputFolder.Bind(property => _modelBuilder.OutputFolder);
I'm a novice with lambdas, so any help is much appreciated!