有没有办法让C#绑定工作静态?

前端之家收集整理的这篇文章主要介绍了有没有办法让C#绑定工作静态?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
这可能适用于其他地方,但在WinForms中,当我使用绑定时,我发现许多方法都希望将属性名称绑定到.就像是:
  1. class Person
  2. {
  3. public String Name { get { ... } set { ... } }
  4. public int Age { get { ... } set { ... } }
  5. }
  6.  
  7. class PersonView
  8. {
  9. void Bind(Person p)
  10. {
  11. nameControl.Bind(p,"Name");
  12. ageControl.Bind(p,"Age");
  13. }
  14. }

我一直遇到的一个大问题是“Name”和“Age”被指定为字符串.这意味着如果有人重命名Person的一个属性,编译器就无济于事.代码编译正常,但绑定将被破坏.

我错过了解决这个问题的标准方法吗?感觉我需要一些关键字,也许叫做stringof来匹配现有的typeof.你可以使用它:

  1. ageControl.Bind(p,stringof(p.Age).Name);

stringof可以返回一些具有获取完整路径,路径的一部分或字符串的属性的类,以便您可以自己解析它.

这样的事情已经可以吗?

解决方法

您可以使用表达式来获取编译器检查的绑定.
例如,在当前的一个项目中,我们设置了这样的绑定:
  1. DataBinder
  2. .BindToObject(this)
  3. .ObjectProperty(c => c.IsReadOnly)
  4. .Control(nameTextBox,n => n.ReadOnly)
  5. .Control(addressControl,n => n.ReadOnly)

支持此样式的代码分为几个类:

  1. public static class DataBinder
  2. {
  3. public static DataBinderBindingSourceContext<TDataSource> BindToObject<TDataSource>(TDataSource dataSource)
  4. {
  5. return new DataBinderBindingSourceContext<TDataSource>(dataSource);
  6. }
  7. }
  8.  
  9. public class DataBinderBindingSourceContext<TDataSource>
  10. {
  11. public readonly object DataSource;
  12.  
  13. public DataBinderBindingSourceContext(object dataSource)
  14. {
  15. DataSource = dataSource;
  16. }
  17.  
  18. public DataBinderControlContext<TDataSource,TProperty> ObjectProperty<TProperty>(Expression<Func<TDataSource,TProperty>> property)
  19. {
  20. return new DataBinderControlContext<TDataSource,TProperty>(this,property);
  21. }
  22. }
  23.  
  24. public class DataBinderControlContext<TDataSource,TProperty>
  25. {
  26. readonly DataBinderBindingSourceContext<TDataSource> BindingSourceContext;
  27. readonly string ObjectProperty;
  28.  
  29. public DataBinderControlContext
  30. (
  31. DataBinderBindingSourceContext<TDataSource> bindingSourceContext,Expression<Func<TDataSource,TProperty>> objectProperty
  32. )
  33. {
  34. BindingSourceContext = RequireArg.NotNull(bindingSourceContext);
  35. ObjectProperty = ExpressionHelper.GetPropertyName(objectProperty);
  36. }
  37.  
  38. public DataBinderControlContext<TDataSource,TProperty> Control<TControl>(TControl control,Expression<Func<TControl,TProperty>> property)
  39. where TControl : Control
  40. {
  41. var controlPropertyName = ExpressionHelper.GetPropertyName(property);
  42. control.DataBindings.Add(controlPropertyName,BindingSourceContext.DataSource,ObjectProperty,true);
  43.  
  44. return this;
  45. }
  46. }
  47.  
  48. public static class ExpressionHelper
  49. {
  50. public static string GetPropertyName<TResult>(Expression<Func<TResult>> property)
  51. {
  52. return GetMemberNames(((LambdaExpression)property).Body).Skip(1).Join(".");
  53. }
  54.  
  55. public static string GetPropertyName<T,TResult>(Expression<Func<T,TResult>> property)
  56. {
  57. return GetMemberNames(((LambdaExpression)property).Body).Join(".");
  58. }
  59.  
  60. static IEnumerable<string> GetMemberNames(Expression expression)
  61. {
  62. if (expression is ConstantExpression || expression is ParameterExpression)
  63. yield break;
  64.  
  65. var memberExpression = (MemberExpression)expression;
  66.  
  67. foreach (var memberName in GetMemberNames(memberExpression.Expression))
  68. yield return memberName;
  69.  
  70. yield return memberExpression.Member.Name;
  71. }
  72. }
  73.  
  74. public static class StringExtentions
  75. {
  76. public static string Join(this IEnumerable<string> values,string separator)
  77. {
  78. if (values == null)
  79. return null;
  80.  
  81. return string.Join(separator,values.ToArray());
  82. }
  83. }

猜你在找的C#相关文章