FormDataBinder.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Web.UI;
  6. using System.Reflection;
  7. using System.ComponentModel;
  8. using Bowin.Common.Utility;
  9. namespace Bowin.Common
  10. {
  11. public class FormDataBinder
  12. {
  13. private static Dictionary<Type, PropertyInfo> controlValueProperties = new Dictionary<Type, PropertyInfo>();
  14. public event EventHandler<DataBindingEventArgs> DataItemBinding;
  15. public event EventHandler<DataBindingEventArgs> DataItemBound;
  16. public static IEnumerable<BindingMapping> BuildBindingMappings(Type entityType, Control container, string suffix = "")
  17. {
  18. Guard.ArgumentNotNullOrEmpty(entityType, "entityType");
  19. Guard.ArgumentNotNullOrEmpty(container, "container");
  20. suffix = suffix??string.Empty;
  21. return (from property in DataPropertyAttribute.GetDataProperties(entityType)
  22. let control = container.FindControl(string.Format("{1}{0}", suffix, property.Name))
  23. let controlValueProperty = GetControlValueProperty(control)
  24. where null != control
  25. select new BindingMapping(control, controlValueProperty, property)).ToArray();
  26. }
  27. public void BindData(object entity, Control container, string suffix = "")
  28. {
  29. Guard.ArgumentNotNullOrEmpty(entity, "entity");
  30. Guard.ArgumentNotNullOrEmpty(container, "container");
  31. var bingingMappings = BuildBindingMappings(entity.GetType(), container, suffix);
  32. this.BindData(entity, bingingMappings);
  33. }
  34. public void BindData( object entity,IEnumerable<BindingMapping> bindingMappings)
  35. {
  36. Guard.ArgumentNotNullOrEmpty(bindingMappings, "bindingMappings");
  37. Guard.ArgumentNotNullOrEmpty(entity, "entity");
  38. this.OnBindData(bindingMappings, entity);
  39. }
  40. protected virtual void OnBindData(IEnumerable<BindingMapping> bindingMappings, object entity)
  41. {
  42. foreach (var bindingMapping in bindingMappings)
  43. {
  44. object value = bindingMapping.DataSourceProperty.GetValue(entity, null);
  45. if (null != this.DataItemBinding)
  46. {
  47. this.DataItemBinding(this, new DataBindingEventArgs(bindingMapping, value));
  48. }
  49. if (!bindingMapping.AutomaticBind)
  50. {
  51. continue;
  52. }
  53. if (!string.IsNullOrEmpty(bindingMapping.FormatString))
  54. {
  55. value = Format(value, bindingMapping.FormatString);
  56. }
  57. value = ChangeType(value, bindingMapping.ControlValueProperty.PropertyType);
  58. if (null != value)
  59. {
  60. bindingMapping.ControlValueProperty.SetValue(bindingMapping.Control, value, null);
  61. if (null != this.DataItemBound)
  62. {
  63. this.DataItemBound(this, new DataBindingEventArgs(bindingMapping, value));
  64. }
  65. }
  66. }
  67. }
  68. private static object Format(object value, string formatString)
  69. {
  70. if (null == value)
  71. {
  72. return string.Empty;
  73. }
  74. IFormattable formattable = value as IFormattable;
  75. if (null != formattable)
  76. {
  77. return formattable.ToString(formatString, null);
  78. }
  79. if (value.GetType().IsGenericType && value.GetType().GetGenericTypeDefinition() == typeof(Nullable<>))
  80. {
  81. object underlyingValue = Convert.ChangeType(value, Nullable.GetUnderlyingType(value.GetType()));
  82. return Format(underlyingValue, formatString);
  83. }
  84. return value;
  85. }
  86. private static PropertyInfo GetControlValueProperty(Control control)
  87. {
  88. if (null == control)
  89. {
  90. return null;
  91. }
  92. Type entityType = control.GetType();
  93. if (controlValueProperties.ContainsKey(entityType))
  94. {
  95. return controlValueProperties[entityType];
  96. }
  97. lock (typeof(FormDataBinder))
  98. {
  99. if (controlValueProperties.ContainsKey(entityType))
  100. {
  101. return controlValueProperties[entityType];
  102. }
  103. var controlValuePropertyAttribute = (ControlValuePropertyAttribute)entityType.GetCustomAttributes(typeof(ControlValuePropertyAttribute), true)[0];
  104. var property = entityType.GetProperty(controlValuePropertyAttribute.Name);
  105. controlValueProperties[entityType] = property;
  106. return property;
  107. }
  108. }
  109. private static object ChangeType(object value, Type type)
  110. {
  111. if (null == value)
  112. {
  113. if (type == typeof(string))
  114. {
  115. return string.Empty;
  116. }
  117. if (type == typeof(bool))
  118. {
  119. return false;
  120. }
  121. return null;
  122. }
  123. if (type.IsGenericType)
  124. {
  125. if (type.GetGenericTypeDefinition() == typeof(Nullable<>))
  126. {
  127. return new NullableConverter(type).ConvertTo(value, type);
  128. }
  129. throw new InvalidCastException(string.Format("Invalid cast from \"{0}\" to \"{1}\".",
  130. value.GetType().FullName, type.FullName));
  131. }
  132. else
  133. {
  134. return Convert.ChangeType(value, type);
  135. }
  136. }
  137. }
  138. }