lPropertiesArray,
"Checked", typeof(bool) );
if (!success)
success = FindAndSetControlProperty(obj,
objProperty, control, controlPropertiesArray,
"SelectedDate", typeof(DateTime) );
if (!success)
success = FindAndSetControlProperty(obj,
objProperty, control, controlPropertiesArray,
"Value", typeof(String) );
if (!success)
success = FindAndSetControlProperty(obj,
objProperty, control, controlPropertiesArray,
"Text", typeof(String) );
}
private static void FindAndSetControlProperty(object obj,
PropertyInfo objProperty, Control control,
PropertyInfo[] controlPropertiesArray, string propertyName,
Type type) {
// 在整个控件属性中进行迭代
foreach (PropertyInfo controlProperty in
controlPropertiesArray) {
// 检查匹配的名称和类型
if (controlPropertiesArray.Name == "Text" &&
controlPropertiesArray.PropertyType == typeof(String)) {
// 将控件的属性设置为
// 业务对象属性值
controlProperty.SetValue(control,
Convert.ChangeType(
objProperty.GetValue(obj, null), type) , null);
return true;
}
}
return false;
}
以上属性检查的顺序很重要,因为有些控件具有以上属性中的多个,但我们只想设置一个。例如,CheckBox 控件既有 .Text 属性也有 .Checked 属性。在此示例中,我们希望使用 .Checked 属性而不是 .Text 属性,所以将 .Checked 放在属性搜索顺序的首位。任何情况下,如果找到具有正确名称和类型的控件属性,则尝试将控件的属性设置为业务对象属性的值。 从这个角度来看,我们拥有了功能齐全的 BindObjectToControls 方法。利用该方法,我们可以在 ASPX 窗体上的任何地方,使用任何类和控件的任意组合进行调用,而这确实有效。现在,我们需要创建在提交窗体时进行反转的方法。我们需要从表示用户输入的控件中检索新值,而不是将控件属性的值设置为业务对象的值。 返回页首反转过程:BindControlsToObject在 BindControlsToObject 方法中,我们将以同样的方式开始,即从业务对象中检索属性的列表,然后使用 FindControl 方法找到具有与对象属性相匹配的 ID 的控件。如果找到控件,则检索值并将该值返回给业务对象。此部分还将包含 ListControl 的单独代码,因为这些控件具有公用接口。我们将使用另一种辅助方法来搜索并检索控件中的值,然后将该值返回给业务对象。 public static void BindControlsToObject(object obj,
Control container) {
Type objType = obj.GetType();
PropertyInfo[] objPropertiesArray = objType.GetProperties();
foreach (PropertyInfo objProperty in objPropertiesArray) {
if (control is ListControl) {
ListControl listControl = (ListControl) control;
if (listControl.SelectedItem != null)
objProperty.SetValue(obj,
Convert.ChangeType(list.SelectedItem.Value,
objProperty.PropertyType), null);
} else {
// 获取控件的属性
//
Type controlType = control.GetType();
PropertyInfo[] controlPropertiesArray =
controlType.GetProperties();
bool success = false;
success = FindAndGetControlProperty(obj,
objProperty, control, controlPropertiesArray,
"Checked", typeof(bool) );
if (!success)
success = FindAndGetControlProperty(obj,
objProperty, control, controlPropertiesArray,
"SelectedDate", typeof(DateTime) );
if (!success)
success = FindAndGetControlProperty(obj,
objProperty, control, controlPropertiesArray,
"Value", typeof(String) );
if (!success)
success = FindAndGetControlProperty(obj,
objProperty, control, controlPropertiesArray,
"Text", typeof(String) );
}
}
}
private static void FindAndGetControlProperty(object obj,
PropertyInfo objProperty, Control control, PropertyInfo[]
controlPropertiesArray, string propertyName, Type type) {
// 在整个控件属性中进行迭代
foreach (PropertyInfo controlProperty in
controlPropertiesArray) {
// 检查匹配的名称和类型
if (controlPropertiesArray.Name == "Text" &&
controlPropertiesArray.PropertyType == typeof(String)) {
// 将控件的属性设置为
// 业务对象属性值
try {
objProperty.SetValue(obj,
Convert.ChangeType(
controlProperty.GetValue(control, null),
objProperty.PropertyType) , null);
return true;
} catch {
// 无法将来自窗体控件
// 的数据转换为
// objProperty.PropertyType
return false;
}
}
}
return true;
}
完成这两种方法后,我们的窗体语法将得到简化,如以上简化和缩短窗体代码中所述。每个属性和控件的类型转换与错误更正都是自动进行的。这两种方法(BindObjectToControls 和 BindControlsToObject)为开发人员创建窗体提供了很大的灵活性。它们还可以用于处理以下这些常见方案: •如果将新属性添加到业务对象,并且需要在窗体上访问该新属性,那么开发人员只需将控件添加到页面,并将控件的 ID 设置为新属性的名称,FormBinding 方法将处理剩下的一切。 •如果开发人员需要更改用于特定属性的控件的类型,例如从 TextBox 更改为第三方的 HTML 编辑器控件,他/她仅需要确保新控件具有以上属性之一(例如 .Text ),窗体将以与之前完全一致的方式进行工作。 •全部使用 TextBox 控件也可以快速生成窗体,但输入仍将转换为适用于业务对象属性的正确类型。例如,可以用 TextBox 控件来代替 Calendar 控件或第三方的日期选取器控件。只要用户输入 DateTime 字符串作为值,便会将 TextBox 的 .Text 属性中的值转换为 DateTime,就如同它是日历控件上的 SelectedDate 属性一样。如果以后将 TextBox 更改为日期选取器控件,逻辑关系将保持不变。 •通过将所有控件更改为 Literal 控件,开发人员还可以快速创建“视图”页面。Literal 的 .Text 属性将被设置为业务对象属性的值,就如同它是 TextBox 一样。 •在实际方案中,窗体还包含其他数据类型和自定义配置。用于处理这些特定操作的代码可以放置在对 BindObjectToControls 和 BindControlsToObject 的调用之后。 返回页首性能和 FormBinding 方案的扩展有些开发人员可能想知道,使用反射引起的性能下降是否值得。在我的测试中,使用了具有七种属性(int DocumentID、bool Active、DateTime Created、int CategoryID、String Title、string Author 和 String htmlText)的对象,BindObjectToControls 用时约 1/3 毫秒,BindControlsToObject 用时大约 1 毫秒。这些值是通过循环运行 1000 次 BindObjectToControls 和 BindControlsToObject 方法得到的。对于常见的“添加”和“编辑”窗体方案,这样的性能应不会引起任何重大的问题,而且确实能够提高开发速度和灵活性。 尽管此方法几乎适用于每种窗体,但有时可能需要修改以上代码。在某些方案中,开发人员要使用的控件可能并不使用以上属性之一作为其主要接口。在此情形中,需要更新 FormBinding 方法,以包括该属性和类型。 返回页首结论这两种 FormBinding 方法(BindObjectToControls 和 BindControlsToObject)可用于极大地简化窗体代码,并为 ASP.NET 窗体的开发提供了最大的灵活性。对它们的使用使我获益良多,希望您的团队同样能够从中受益。 返回页首转到原英文页面
上一页 [1] [2] [C语言系列]NET 中C#的switch语句的语法 [系统软件]托拽Explore中的文件到VB.net的窗口 [系统软件]Boost库在XP+Visual C++.net中的安装 [常用软件]新配色面板:Paint.Net3.0RC1官方下载 [常用软件]用内建的“Net Meeting”聊天 [VB.NET程序]Henry的VB.NET之旅(三)—共享成员 [VB.NET程序]Henry的VB.NET之旅(二)—构造与析构 [VB.NET程序]Henry的VB.NET之旅(一)—失踪的窗体 [VB.NET程序]在托盘上显示Balloon Tooltip(VB.NET) [VB.NET程序]Henry手记-VB.NET中动态加载Treeview节点(二)
|