在WebForm中,可以使用反射将业务对象绑定到 ASP.NET 窗体控件。最近做Winform项目,也参考WebForm中的代码实现同样的功能。
Winform没有提供类似WebForm中的FindControl方法,我于是用遍历控件的方式,写了一个类似WebForm中的这个方法,考虑到Winform中的很多控件放在Label、TabControl中,方法采用了递归的方式。
Winform和Winform的控件也有些区别,如在Winform中,DateTimePicker取值是用Value属性,在WebForm中使用 SelectDate属性,在Winform中,有NumericUpDown控件,取值也是用Value属性,因此,具体绑定方式上也和WebForm 中有些区别。
////代码如下: using System; using System.Windows.Forms; using System.Reflection; using System.Collections; namespace BindTest { public sealed class FormBinding { /// <summary> /// 将业务对象绑定到窗体或控件容器 /// </summary> /// <param name="obj">业务对象</param> /// <param name="container">窗体或控件容器</param> public static void BindObjectToControls(object obj, Control container) { if (obj == null) return; Type objType = obj.GetType(); PropertyInfo[] objPropertiesArray = objType.GetProperties(); foreach (PropertyInfo objProperty in objPropertiesArray) { Control control = FindControl(container, objProperty.Name); if (control == null) continue; if (control is DateTimePicker) { DateTimePicker dateTimePicker = (DateTimePicker)control; dateTimePicker.Value = (DateTime)objProperty.GetValue(obj, null); } else { //获取控件的属性 Type controlType = control.GetType(); PropertyInfo[] controlPropertiesArray = controlType.GetProperties(); //通用属性 bool success = false; success = FindAndSetControlProperty(obj, objProperty, control, controlPropertiesArray, "Checked", typeof(bool)); if (!success) success = FindAndSetControlProperty(obj, objProperty, control, controlPropertiesArray, "Value", typeof(String)); if (!success) success = FindAndSetControlProperty(obj, objProperty, control, controlPropertiesArray, "Text", typeof(String)); if (!success) success = FindAndSetControlProperty(obj, objProperty, control, controlPropertiesArray, "SelectedValue", typeof(String)); } } } /// <summary> /// 根据控件名找出容器中的控件,考虑有些控件放在窗体的容器中,采用了递归查找。 /// </summary> /// <param name="container">控件容器</param> /// <param name="controlName">控件名称</param> /// <returns></returns> private static Control FindControl(Control container, string controlName) { Control findControl = null; foreach(Control control in container.Controls) { if (control.Controls.Count == 0) { if (control.Name == controlName) { findControl = control; break; } } else { findControl = FindControl(control, controlName); } } return findControl; } /// <summary> /// 设置控件的值 /// </summary> /// <param name="obj"></param> /// <param name="objProperty"></param> /// <param name="control"></param> /// <param name="controlPropertiesArray"></param> /// <param name="propertyName"></param> /// <param name="type"></param> /// <returns></returns> private static bool FindAndSetControlProperty(object obj, PropertyInfo objProperty, Control control, PropertyInfo[] controlPropertiesArray, string propertyName, Type type) { foreach (PropertyInfo controlProperty in controlPropertiesArray) { if (controlProperty.Name == propertyName && controlProperty.PropertyType == type) { controlProperty.SetValue(control, Convert.ChangeType(objProperty.GetValue(obj, null), type), null); return true; } } return false; } public static void BindControlsToObject(object obj, Control container) { if (obj == null) return; //获取业务对象的属性 Type objType = obj.GetType(); PropertyInfo[] objPropertiesArray = objType.GetProperties(); foreach (PropertyInfo objProperty in objPropertiesArray) { Control control = FindControl(container, objProperty.Name); if (control == null) continue; if (control is DateTimePicker) { DateTimePicker dateTimePicker = (DateTimePicker)control; objProperty.SetValue(obj, Convert.ChangeType(dateTimePicker.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, "Value", typeof(String)); if (!success) success = FindAndGetControlProperty(obj, objProperty, control, controlPropertiesArray, "Text", typeof(String)); if (!success) success = FindAndGetControlProperty(obj, objProperty, control, controlPropertiesArray, "SelectedValue", typeof(String)); } } } private static bool FindAndGetControlProperty(object obj, PropertyInfo objProperty, Control control, PropertyInfo[] controlPropertiesArray, string propertyName, Type type) { // 在整个控件属性中进行迭代 foreach (PropertyInfo controlProperty in controlPropertiesArray) { // 检查匹配的名称和类型 if (controlProperty.Name == "Text" && controlProperty.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; } } } //使用方法: //业务对象: public class Model { public Model() { } private string test1; private DateTime test2; private string test3; public string Test1 { set { test1 = value; } get { return test1; } } public DateTime Test2 { set { test2 = value; } get { return test2; } } public string Test3 { set { test3 = value; } get { return test3; } } }////代码如下: using System; using System.Windows.Forms; using System.Reflection; using System.Collections; namespace BindTest { public sealed class FormBinding { /// <summary> /// 将业务对象绑定到窗体或控件容器 /// </summary> /// <param name="obj">业务对象</param> /// <param name="container">窗体或控件容器</param> public static void BindObjectToControls(object obj, Control container) { if (obj == null) return; Type objType = obj.GetType(); PropertyInfo[] objPropertiesArray = objType.GetProperties(); foreach (PropertyInfo objProperty in objPropertiesArray) { Control control = FindControl(container, objProperty.Name); if (control == null) continue; if (control is DateTimePicker) { DateTimePicker dateTimePicker = (DateTimePicker)control; dateTimePicker.Value = (DateTime)objProperty.GetValue(obj, null); } else { //获取控件的属性 Type controlType = control.GetType(); PropertyInfo[] controlPropertiesArray = controlType.GetProperties(); //通用属性 bool success = false; success = FindAndSetControlProperty(obj, objProperty, control, controlPropertiesArray, "Checked", typeof(bool)); if (!success) success = FindAndSetControlProperty(obj, objProperty, control, controlPropertiesArray, "Value", typeof(String)); if (!success) success = FindAndSetControlProperty(obj, objProperty, control, controlPropertiesArray, "Text", typeof(String)); if (!success) success = FindAndSetControlProperty(obj, objProperty, control, controlPropertiesArray, "SelectedValue", typeof(String)); } } } /// <summary> /// 根据控件名找出容器中的控件,考虑有些控件放在窗体的容器中,采用了递归查找。 /// </summary> /// <param name="container">控件容器</param> /// <param name="controlName">控件名称</param> /// <returns></returns> private static Control FindControl(Control container, string controlName) { Control findControl = null; foreach(Control control in container.Controls) { if (control.Controls.Count == 0) { if (control.Name == controlName) { findControl = control; break; } } else { findControl = FindControl(control, controlName); } } return findControl; } /// <summary> /// 设置控件的值 /// </summary> /// <param name="obj"></param> /// <param name="objProperty"></param> /// <param name="control"></param> /// <param name="controlPropertiesArray"></param> /// <param name="propertyName"></param> /// <param name="type"></param> /// <returns></returns> private static bool FindAndSetControlProperty(object obj, PropertyInfo objProperty, Control control, PropertyInfo[] controlPropertiesArray, string propertyName, Type type) { foreach (PropertyInfo controlProperty in controlPropertiesArray) { if (controlProperty.Name == propertyName && controlProperty.PropertyType == type) { controlProperty.SetValue(control, Convert.ChangeType(objProperty.GetValue(obj, null), type), null); return true; } } return false; } public static void BindControlsToObject(object obj, Control container) { if (obj == null) return; //获取业务对象的属性 Type objType = obj.GetType(); PropertyInfo[] objPropertiesArray = objType.GetProperties(); foreach (PropertyInfo objProperty in objPropertiesArray) { Control control = FindControl(container, objProperty.Name); if (control == null) continue; if (control is DateTimePicker) { DateTimePicker dateTimePicker = (DateTimePicker)control; objProperty.SetValue(obj, Convert.ChangeType(dateTimePicker.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, "Value", typeof(String)); if (!success) success = FindAndGetControlProperty(obj, objProperty, control, controlPropertiesArray, "Text", typeof(String)); if (!success) success = FindAndGetControlProperty(obj, objProperty, control, controlPropertiesArray, "SelectedValue", typeof(String)); } } } private static bool FindAndGetControlProperty(object obj, PropertyInfo objProperty, Control control, PropertyInfo[] controlPropertiesArray, string propertyName, Type type) { // 在整个控件属性中进行迭代 foreach (PropertyInfo controlProperty in controlPropertiesArray) { // 检查匹配的名称和类型 if (controlProperty.Name == "Text" && controlProperty.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; } } } //使用方法: //业务对象: public class Model { public Model() { } private string test1; private DateTime test2; private string test3; public string Test1 { set { test1 = value; } get { return test1; } } public DateTime Test2 { set { test2 = value; } get { return test2; } } public string Test3 { set { test3 = value; } get { return test3; } } }
在一个Winform中,放两个TextBox控件,一个DateTimePicker控件,一个Panel控件,分别命名位Test1、Test2、Test3,其中把Text3控件放在Panel1中。
将业务对象绑定到窗体:
Model model = new Model(); model.Test1 = "Hello,World!"; model.Test2 = DateTime.Now.AddMonths(-2); model.Test3 = "Nice to meet u!"; FormBinding.BindObjectToControls(model, this);
将窗体绑定到业务对象:
Model model = new Model(); FormBinding.BindControlsToObject(model, this); MessageBox.Show(model.Test1 + " " + model.Test2.ToShortDateString() + " " + model.Test3);