三、如何建立Control/DataSource映射集合
BindingMapping表示的一个实体类型的数据属性和具体控件之间的映射关系,而这种关系在使用过程中是以批量的方式进行创建的。具体来说,我们通过指定实体类型和一个作为容器的空间,如果容器中的存在满足映射规则的子控件,相应的映射会被创建。映射的批量创建是通过DataBinder的静态方法BuildBindingMappings来实现的。
在具体介绍BuildBindingMappings方法之前,我们需要先来讨论一个相关的话题:在进行数据绑定的时候,如何决定数据应该赋值给控件的那个属性。我们知道,不同的控件类型拥有不同的数据绑定属性,比如TextBox自然是Text属性,CheckBox则是Checked属性。ASP.NET在定义控件类型的时候,采用了一个特殊性的特性ControlValuePropertyAttribute来表示那个属性表示的是控件的“值”。比如TextBox和CheckBox分别是这样定义的。
- [ControlValueProperty("Text")]
- public class TextBox : WebControl, IPostBackDataHandler, IEditableTextControl, ITextControl
- {
- //...
- }
- ControlValueProperty("Checked")]
- public class CheckBox : WebControl, IPostBackDataHandler, ICheckBoxControl
- {
- //...
- }
在这里我们直接将ControlValuePropertyAttribute中指定的名称作为控件绑定的属性名,即BindingMapping的ControlValueProperty属性。该值得获取通过如下一个GetControlValuePropertyName私有方法完成。为了避免重复反射操作,这里采用了全局缓存。
- private static string GetControlValuePropertyName(Control control)
- {
- if (null == control)
- {
- return null;
- }
- Type entityType = control.GetType();
- if (controlValueProperties.ContainsKey(entityType))
- {
- return controlValueProperties[entityType];
- }
- lock (typeof(DataBinder))
- {
- if (controlValueProperties.ContainsKey(entityType))
- {
- return controlValueProperties[entityType];
- }
- ControlValuePropertyAttribute controlValuePropertyAttribute = (ControlValuePropertyAttribute)entityType.GetCustomAttributes(typeof(ControlValuePropertyAttribute), true)[0];
- controlValueProperties[entityType] = controlValuePropertyAttribute.Name;
- return controlValuePropertyAttribute.Name;
- }
- }
最终的映射通过如下定义的BuildBindingMappings方法来建立,缺省参数suffix代表的是控件的后缀,其中已经在《上篇》介绍过了。
- public static IEnumerable<BindingMapping> BuildBindingMappings(Type entityType, Control container, string suffix = "")
- {
- //...
- suffixsuffix = suffix??string.Empty;
- return (from property in DataPropertyAttribute.GetDataProperties(entityType)
- let control = container.FindControl(string.Format("{1}{0}", suffix, property))
- let controlValueProperty = GetControlValuePropertyName(control)
- where null != control
- select new BindingMapping(entityType, control, controlValueProperty, property)).ToArray();
- }
本站文章为和通数据库网友分享或者投稿,欢迎任何形式的转载,但请务必注明出处.
同时文章内容如有侵犯了您的权益,请联系QQ:970679559,我们会在尽快处理。