在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 == )
{
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 == )
{
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(-);
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);

[WinForm] 使用反射将业务对象绑定到窗体或控件容器的更多相关文章

  1. Winform中怎样根据Name获取同窗体的控件

    场景 在同一个Winform窗体中,点击一个Button按钮时, 获取同窗体的其他控件的属性. 首先需要对要获取的控件赋予Name属性,然后就可以通过Name进行获取. 实现 在Button的点击事件 ...

  2. Winform 获取当前单击的控件名称 和 向窗体添加控件

    Winform如何获取当前单击的控件名称,比如有100个Button 和一个button_Click()的按钮事件 ,分别点击不同按钮后显示所点击的按钮名称?private void button_C ...

  3. WinForm窗体及其控件的自适应

    3步骤: 1.在需要自适应的Form中实例化全局变量   AutoSizeFormClass.cs源码在下方 AutoSizeFormClass asc = new AutoSizeFormClass ...

  4. Winform跨窗体操作控件(使用委托)

    Winform跨窗体操作控件是winform开发中很常见的形式,最常见且简单有效的方式便是使用委托的方式来进行操作,下面我将通过一个小实例来说明如何使用委托跨窗体实现控件操作. 实例介绍:两个窗体,F ...

  5. 转:C# WinForm窗体及其控件的自适应

    一.说明 2012-11-30 曾经写过 <C# WinForm窗体及其控件自适应各种屏幕分辨率>  ,其中也讲解了控件自适应的原理.近期有网友说,装在panel里面的控件,没有效果? 这 ...

  6. C# WinForm窗体及其控件自适应各种屏幕分辨率

    C# WinForm窗体及其控件自适应各种屏幕分辨率 一.说明  我们自己编写程序的界面,会遇到各种屏幕分辨率,只有自适应才能显的美观.实际上,做到这点也很简单,就是首先记录窗体和它上面控件的初始位置 ...

  7. Winform中怎样跨窗体获取另一窗体的控件对象

    场景 Winform中实现跨窗体获取ZedGraph的ZedGraphControl控件对象: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/de ...

  8. C#跨窗体调用控件(委托回调函数使用例子)

    问题: 有两个窗体,FORM1(含一个label控件,一个名为显示form2的button控件)和FORM2(含一个button控件).启动时,FORM1中点击button控件显示form2使FORM ...

  9. 最佳实践扩展Windows窗体DataGridView控件 .net 4.5 附示例代码

    Windows窗体DataGridView控件的性能调优.net 4.5   在处理大量数据时, DataGridView 控制可以消耗大量的内存开销,除非你仔细地使用它. 在客户有限的内存,你可以避 ...

随机推荐

  1. B - Kefa and Company

    B - Kefa and Company Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I6 ...

  2. hdu 5424 Rikka with Graph II (BestCoder Round #53 (div.2))(哈密顿通路判断)

    http://acm.hdu.edu.cn/showproblem.php?pid=5424 哈密顿通路:联通的图,访问每个顶点的路径且只访问一次 n个点n条边 n个顶点有n - 1条边,最后一条边的 ...

  3. [iOS微博项目 - 3.4] - 获取用户信息

    github: https://github.com/hellovoidworld/HVWWeibo   A.获取用户信息 1.需求 获取用户信息并储存 把用户昵称显示在“首页”界面导航栏的标题上   ...

  4. POJ2947Widget Factory(高斯消元解同模方程)

    http://poj.org/problem?id=2947 题目大意:有n 种装饰物,m 个已知条件,每个已知条件的描述如下:p start enda1,a2......ap (1<=ai&l ...

  5. CodeForces Gym 100685C Cinderella (水题)

    题意:给定 n 个杯子,里面有不同体积的水,然后问你要把所有的杯子的水的体积都一样,至少要倒少多少个杯子. 析:既然最后都一样,那么先求平均数然后再数一下,哪个杯子的开始的体积就大于平均数,这是一定要 ...

  6. AFNetworking上传文件

    -(void)upload{ AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; NSD ...

  7. Linux下生成动态链接库是否必须使用 -fPIC 的问题[转]

    在 Linux 下制作动态链接库,“标准” 的做法是编译成位置无关代码(Position Independent Code,PIC),然后链接成一个动态链接库.经常遇到的一个问题是 -fPIC 是不是 ...

  8. 数据库 SQL :有关 NULL 值引发 TRUE、FALSE、UNKNOW 三值逻辑

    在 Java.C# 中,相信如果是 boolean 类型值,只有两种选择 true.false.然而,在 SQL 查询中,NULL 值的引入,使得新增了 UNKNOW ,因此,就产生了 TRUE.FA ...

  9. 学习JQuery中文文档之get()函数

    前端大神群的群主告诉我们:学习一个框架最好的方法是去把官方文档研究一遍. 现在正式开始我的前端之路,从JQuery的中文文档开始. 基础不牢固,看起来有点慢,但是我会一直坚持下去的.把遇到的问题都记录 ...

  10. 系列文章--JavaScript教程文章

    JavaScript教程文章专题列表如下: 我们应该如何去了解JavaScript引擎的工作原理 JavaScript探秘:编写可维护的代码的重要性 JavaScript探秘:谨慎使用全局变量 Jav ...