界面数据绑定
一、关于数据绑定
在.NET中,把控件链接到数据源的过程称为数据绑定。如果开发与用户直接交互的软件,为了显示给用户系统的数据信息,往往需要花费很多的时间把数据显示在界面上。
目前,很多C#书上都介绍了DataGrid控件与数据源进行绑定的过程。这也是.NET运行时最常用的显示数据的控件。在.Net中Dataset、DataTable等可以与Datagrid绑定,Dataset、DataTable中的数据就会自动的填充到Datagrid中,而当用户修改了Datagrid中的数据,这些数据会自动的更新Dataset、DataTable中的数据,这样的功能是非常方便的。
绑定一般有两种方式:简单绑定和复杂绑定。对于把DataSet绑定到控件DataGrid上就不多说了,读者可以在很多书上都能见过。下面主要介绍一下如何把自定义业务类绑定到控件上。
二、简单绑定
支持单一绑定的控件一般一次只显示一个值,例如文本框TextBox、标签Label等控件,都是只能与类的一个属性相绑定。与简单绑定相关的属性主要有:DataBindings。
以下User类是我们自定义的类,它有两个成员变量,我们将示例如何把User的两个成员绑定到控件上。
public class User
{
public User()
{
}
public User(int Age,string Name)
{
_Age=Age;
_Name=Name;
}
private int _Age;
private string _Name;
public int Age
{
set{_Age=value;}
get{return _Age;}
}
public string Name
{
set{_Name=value;}
get{return _Name;}
}
}
假设界面上有两个文本框:tbxName,tbxAge,准备分别显示用户的名字及年龄。
将你可以在代码中增加如下绑定代码:
{
User user = new User(10,"Tom");
tbxName.DataBindings.Add("Text", user, "Name");
tbxAge.DataBindings.Add("Text", user, "Age");
}
这样就可以了,你会发现界面的文本框可以直接显示对象user的两个属性。
当你修改文本框中的用户名及年龄时,你同时也会发现对象user中的两个成员值也跟着自动更新了。这是不是很简单,且非常有用?
三、复杂绑定
有的控件可以显示多行一列或多行多列。比如象ListView控件、DataGrid控件可以显示多行多列,象ListBox、ComboBox控件可以显示多行一列。下面分别来看一下怎样把多个数据绑定到控件中。
多行一列:
对于ListBox控件,绑定涉及的属性有:DataSource,DisplayMember。DataSource用来指定对象,而DisplayMember用来指示对象中的成员变量名。
{
User[] users = new User[2];
users[0] = new User(20,"Tom");
users[1] = new User(22,"Jerry");
// //以前需要使用for循环来显示
// for(int i=0; i
// lbxUser.Items.Add(users[i].Name);
// }
//使用数据绑定
lbxUser.DataSource = users;
lbxUser.DisplayMember = "Name";
}
上一段代码就把ListBox控件绑定到数组users上,并且控件自动把数组users中对应Name属性的数据显示出来了。这样,我们再也不需要使用for循环遍历数组users把对应的变量值加到lbxUser中了。
多行多列:
象DataGrid控件可以绑定多行多列。将数组或ArrayList绑定到DataGrid控件也很简单:
dataGrid1.DataSource = users;
简简单单的一行代码,你会发现DataGrid控件已经把对象的成员名称都在标题中正确地显示出来了。真的很简单!
四、ListView控件的绑定。
我想,对于ListView控件是最常用的数据显示控件,可是遗憾的是,在C#中,这个多行多列的控件却没有给我们提供DataSource或者DisplayMember属性来绑定业务数据。甚至是DataBindings也没能给我们什么帮助。
所以,出于工作的需要,我自己对ListView控件进行了扩展,制作了DataListView控件。它主要在原来控件的基础上,作了如下的变更:
#region 使用说明
/*
* Author: fusx
* Create Date:2005-11-13
* Description:
* 继承ListView控件,实现绑定数据源功能。可以绑定数组及单个对象。
* 新增加的属性:
* 1、DataSource 数据源,设置需要显示的数据源
* 2、AutoGetColumnHeader 是否自动获取列标题,默认为true。
* 当调用AddColumnHeader时会变为false,调用ClearColumnHeader时又自动变为true。
* 3、SelcetedDatas 选中的数据源列表
* 4、AllDatas 列表中所有的数据项数组
* 新增加的方法
* 5、DataRefresh 重新刷新显示
* 6、AddColumnHeader 自定义增加列表标题
* 7、ClearColumnHeader 清除所有列表标题
* 8、AddDataSource 增加新的数据源到控件
* 9、RemoveDataSource 移除指定的数据项
* 10、RemoveSelectedDataSource 移除所有选定的数据项
*
* 使用说明
* 1、由于显示需要,所以加入到列表的对象需要实现ToString()函数。
* 2、外面数据源的改变会影响到控件中的数据,但外面数组的移除与增加不会反应到控件中。
* 如果要在控件中增加或移除,则请使用AddDataSource和RemoveDataSource。
*/
#endregion
使用方法很简单:
this.DataListView1.DataSource = users;
本控件可以自动发现对象类User的所有public属性,并自动正确地显示在列表的标题中,其数据项就是数组users具体的值。
当然,如果你觉得DataListView控件显示的列标题("Name","Age")不友好想用中文或别的自定义标题,也很简单:
this.DataListView1.AddColumnHeader("名字","Name");
this.DataListView1.AddColumnHeader("年龄","Age");
甚至,如果你想把年龄显示在名字前面的一列,也简单。把上面的两行代码调换一下顺序即可。是不是很酷?!
如果你想往控件中再添加数据源,请使用AddDataSource方法。如果你想知道当前控件中显示了哪些数组或选中了哪些数组源,可以根据属性SelectedDatas及AllDatas得到。
当然,请记住本控件使用的都是引用,所以,如果我们传入的数据源的值在控件外已经改变了,意味着在控件中的值也是改变了的,但有可能控件显示的不是最新的值。该怎么办?很简单,使用DataRefresh()方法刷新一下界面显示即可。
所以,如果你在控件外面改变了users中数据的值,控件中使用AllDatas返回的数组也是改变后的数组。
很简单吧,我花了一天的时间做出来,可以支持简单类型、字符串、枚举等数据源及数组。想知道是怎样做出来的吧,提示你一下:利用反射机制,你也可以做出你想要的ListView控件来。
如果需要,可以给我留下E-Mail,我可以发给你们参考。