I have written a generic extension method, which basically adds a binding to a windows form ui element (like a form or a button).
It does work fine for now, tried it in a few projects, however it's still a quite complex method with 3 generic "T-arguments".
public static void Add<T1, T2, T3>(
this ControlBindingsCollection collection,
T2 dataSrc,
Expression<Func<T1, T3>> p1,
Expression<Func<T2, T3>> p2)
where T1 : class
where T2 : class
{
var prop1Name = PropertyNameResolver.GetPropertyName(p1);
var prop2Name = PropertyNameResolver.GetPropertyName(p2);
collection.Add(prop1Name, dataSrc, prop2Name, false, DataSourceUpdateMode.OnPropertyChanged);
}
GetPropertyName looks like this:
public static string GetPropertyName<T1,T2>(Expression<Func<T1,T2>> propertyExpression)
{
return ((MemberExpression)propertyExpression.Body).Member.Name;
}
This are two examples of how I call the method:
DataBindings.Add<Form, FrmOptionsPresenter, double>(
m_frmOptionsPresenter,
binder => binder.Opacity,
dataSrc => dataSrc.Opacity);
Like I've said above, the call kinda looks heavy.
What I would like to know now: Is there anything you can suggest me to make these method more simple and readable?
Thanks in advance!
Look at our implementation:
public static class BindableComponentExtensions
{
public static void Bind<T>(this IBindableComponent component, T value, Expression<Func<object>> controlProperty, Expression<Func<T, object>> modelProperty)
where T : INotifyPropertyChanged
{
component.DataBindings.Add(new Binding(
StringExtensions.PropertyName(controlProperty),
value,
StringExtensions.PropertyName(modelProperty),
true,
DataSourceUpdateMode.OnPropertyChanged));
}
public static void Bind<TComponent, T>(this TComponent component, T value,
Expression<Func<TComponent, object>> controlProperty, Expression<Func<T, object>> modelProperty)
where TComponent : IBindableComponent
where T : INotifyPropertyChanged
{
component.DataBindings.Add(new Binding(
StringExtensions.PropertyName(controlProperty),
value,
StringExtensions.PropertyName(modelProperty),
true,
DataSourceUpdateMode.OnPropertyChanged));
}
public static void OneWayBind<TComponent, T>(
this TComponent component, T value,
Expression<Func<TComponent, object>> controlProperty,
Expression<Func<T, object>> modelProperty
)
where TComponent : IBindableComponent
where T : INotifyPropertyChanged
{
component.DataBindings.Add(new Binding(
StringExtensions.PropertyName(controlProperty),
value,
StringExtensions.PropertyName(modelProperty),
true,
DataSourceUpdateMode.Never));
}
}
And usage:
combobox.Bind(name, c => c.SelectedValueId, v => v.OrganizationLegalFormId);
_auditName.OneWayBind(_model, c => c.Text, v => v.DisplayName);
Where name
or _model
is data model class, c => c.SelectedValueId
or c => c.Text
is control property, v => v.DisplayName
or v => v.OrganizationLegalFormId
is model property.
StringExtensions.PropertyName
is your PropertyNameResolver.GetPropertyName
:
public static class StringExtensions
{
public static string MethodName<T>(Expression<Action<T>> action)
{
return ReflectionExtensions.GetMethodInfo(action).Name;
}
public static string PropertyName<T, TProperty>(Expression<Func<T, TProperty>> propertyExpression)
{
return PropertyNameInternal(propertyExpression);
}
public static string PropertyName<T>(Expression<Func<T>> propertyExpression)
{
return PropertyNameInternal(propertyExpression);
}
private static string PropertyNameInternal(LambdaExpression propertyExpression)
{
if (propertyExpression == null)
throw new ArgumentNullException(@"propertyExpression");
var memberExpression = propertyExpression.Body as MemberExpression;
if (memberExpression == null)
{
var ubody = (UnaryExpression)propertyExpression.Body;
memberExpression = ubody.Operand as MemberExpression;
}
if (memberExpression == null)
throw new ArgumentException(@"The expression is not a member access expression.", @"propertyExpression");
var property = memberExpression.Member as PropertyInfo;
if (property == null)
throw new ArgumentException(@"The member access expression does not access a property.", @"propertyExpression");
return memberExpression.Member.Name;
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.