欢迎投稿

今日深度:

一句代码实现批量数据绑定 下(1)(4)

三、如何建立Control/DataSource映射集合

BindingMapping表示的一个实体类型的数据属性和具体控件之间的映射关系,而这种关系在使用过程中是以批量的方式进行创建的。具体来说,我们通过指定实体类型和一个作为容器的空间,如果容器中的存在满足映射规则的子控件,相应的映射会被创建。映射的批量创建是通过DataBinder的静态方法BuildBindingMappings来实现的。

在具体介绍BuildBindingMappings方法之前,我们需要先来讨论一个相关的话题:在进行数据绑定的时候,如何决定数据应该赋值给控件的那个属性。我们知道,不同的控件类型拥有不同的数据绑定属性,比如TextBox自然是Text属性,CheckBox则是Checked属性。ASP.NET在定义控件类型的时候,采用了一个特殊性的特性ControlValuePropertyAttribute来表示那个属性表示的是控件的“值”。比如TextBox和CheckBox分别是这样定义的。

  1. [ControlValueProperty("Text")]  
  2. public class TextBox : WebControl, IPostBackDataHandler, IEditableTextControl, ITextControl  
  3. {  
  4.     //...  
  5. }  
  6.     
  7. ControlValueProperty("Checked")]  
  8. public class CheckBox : WebControl, IPostBackDataHandler, ICheckBoxControl  
  9. {  
  10.     //...  
  11. }  

在这里我们直接将ControlValuePropertyAttribute中指定的名称作为控件绑定的属性名,即BindingMapping的ControlValueProperty属性。该值得获取通过如下一个GetControlValuePropertyName私有方法完成。为了避免重复反射操作,这里采用了全局缓存。

  1. private static string GetControlValuePropertyName(Control control)  
  2. {  
  3.     if (null == control)  
  4.     {  
  5.         return null;  
  6.     }  
  7.     Type entityType = control.GetType();  
  8.     if (controlValueProperties.ContainsKey(entityType))  
  9.     {  
  10.         return controlValueProperties[entityType];  
  11.     }  
  12.     lock (typeof(DataBinder))  
  13.     {  
  14.         if (controlValueProperties.ContainsKey(entityType))  
  15.         {  
  16.             return controlValueProperties[entityType];  
  17.         }  
  18.         ControlValuePropertyAttribute controlValuePropertyAttribute = (ControlValuePropertyAttribute)entityType.GetCustomAttributes(typeof(ControlValuePropertyAttribute), true)[0];  
  19.         controlValueProperties[entityType] = controlValuePropertyAttribute.Name;  
  20.         return controlValuePropertyAttribute.Name;  
  21.     }  
  22. }  

最终的映射通过如下定义的BuildBindingMappings方法来建立,缺省参数suffix代表的是控件的后缀,其中已经在《上篇》介绍过了。

  1. public static IEnumerable<BindingMapping> BuildBindingMappings(Type entityType, Control container, string suffix = "")  
  2. {  
  3.     //...  
  4.     suffixsuffix = suffix??string.Empty;  
  5.     return (from property in DataPropertyAttribute.GetDataProperties(entityType)  
  6.             let control = container.FindControl(string.Format("{1}{0}", suffix, property))  
  7.             let controlValueProperty = GetControlValuePropertyName(control)  
  8.             where null != control  
  9.             select new BindingMapping(entityType, control, controlValueProperty, property)).ToArray();  
  10. }  


www.htsjk.Com true http://www.htsjk.com/shujukujc/18883.html NewsArticle 三、如何建立Control/DataSource映射集合 BindingMapping表示的一个实体类型的数据属性和具体控件之间的映射关系,而这种关系在使用过程中是以批量的方式进行...
评论暂时关闭