前面章节中,对简单绑定和复杂绑定做了简单的描述。在这章中,我们将所有的这些东西串在一起看看数据绑定的全貌。
Binding对象:代表某对象属性值和某控件属性值之间的简单绑定。其主要负责将控件的属性和对象的属性进行关联。
BindingManagerBase:管理绑定到相同数据源和数据成员的所有 Binding 对象。 这个对象在前面的章节中没有涉及,但实际上不管是简单绑定还是复杂绑定中都使用到了这个对象的相应的派生类。
BindingContext对象: 负责管理从Control类继承的任意对象的 BindingManagerBase对象集合只要发生数据绑定,那在一个FORM中就一定存在一个BindingContext对象。我们可以通过Form对象BindingContext属性获得一个BindingContext对象。
这三个对象掌管着数据绑定的主要功能。我们先来看看其关系:
1. Binding对象负责将控件的属性和对象的属性关联起来。对象的属性值会被自动传递个控件的属性,而控件的属性值更改后也会直接传回对象的属性(双向绑定)。
2. 在一个WinForm界面中总是会存在多个控件。所以,一般都会有一组Binding对象来管理不同控件中的属性和相同数据源中属性的关联关系。为了能方便的管理这样的一组Binding对象,我们使用继承至BindingManagerBase的子对象进行管理工作。BindingManagerBase有两个子类:PropertyManager和CurrencyManager.
其中:PropertyManager : 维护对象的属性与数据绑定控件属性之间的 Binding。(见简单绑定的描述)
CurrencyManager : 管理 Binding 对象的列表。管理列表或集合类型的数据源对象。(见复杂绑定的描述)
无论是PropertyManager还是CurrencyManager总是和一个数据源对象的对应的。也就是说,一个特定的数据源对象(无论是单一对象还是集合类对象)都会有一个对应的BindingManagerBase的子对象。
3.对同一窗体而言,通常都会面对多个数据源而不是一个。所以,也就会产生多个PropertyManager或CurrencyManager对象。BindingContext就主要负责管理多个BindingManagerBase的子对象。BindingContext可以通过窗体的BindingContext属性获得。它是一个字典的集合。
为了更好的说明这三类对象之间的关系,请查看下图。
上面图例表明了一下几件事情:
1.当你的窗体中绑定了3个不同的数据源,数据绑定机制就会自动产生三个对应的BindingManagerBase的子对象与数据源对象对应。其实更为准确的说法是,如果你的窗体绑定了三个不同的对象,那么就会产生三个独立的BindingManagerBase的子对象与其对应。至于是产生PropertyManager还是CurrencyManager就要取决与你绑定的数据源是单一对象还是列表(集合)对象了。上图说明了这一个点,如果是绑定的是单一对象就会产生PorpertyManager,而如果是列表(集合)对象就会产生一个CurrencyManager。
2. PropertyManager主要管理一组相关的Binding对象,而CurrencyManager主要管理着相应的对象集合(列表对象)。两个对象管理的侧重点不同,一个主要管理数据绑定的基础对象Binding,而一个主要管理数据绑定的后端数据源对象集合。
比如CurrencyManager可以每次从集合对象中猎取一个对象然后将其绑定的到窗体控件中去,它也可以在集合对象中进行导航。或也可以新增新的对象集合中,等等。
3.因为对于同一窗体而言,可能绑定到多个数据源也就会产生多个“管理者”,而每一个数据源都会对应一个独立的“管理者”。所以我们可以通过窗体的BindingContext对象获得某个特定数据源对应的“管理者”。
比如:窗体中的数据源是HumanList(集合),那么当窗体和这个集合发生绑定后,我们就可以通过一下的方式获得一个CurrencyManager对象。
其注意以上的第9行的语句this.BindingContext[list]。其中窗体有一个BindingContext属性,它在发生数据绑定后会自动维持一个key/value的集合,这个集合是一数据源对象作为KEY的,我们可以通过指定特定的数据源对象找到相应的“管理者”。注意前面我已经说过对于每个数据源而言都会有一个对应的“管理者”。上面的代码中应为数据源是集合类型所以会产生一个CurrencyManager对象。
现在可以做个小结:BindingContext类维持一组可能BindingManagerBase对象,而这些BindingManagerBase对象和数据源对象又是一一对应的。
复杂的讲解到此,下面我就做一个实际的例子来体会一下上面的描述。
1.首先:我们创建一个自定义的对象:Person类
using System.Collections.Generic;
using System.Text;
namespace AppBindingContext
{
public class Person
{
private string _lastName;
public string LastName
{
get { return _lastName; }
set { _lastName = value; }
}
private string _firstName;
public string FirstName
{
get { return _firstName; }
set { _firstName = value; }
}
private int _age;
public int Age
{
get { return _age; }
set { _age = value; }
}
public Person() { }
public Person( string lastName, string firstName, int age)
{
this .LastName = lastName;
this .FirstName = firstName;
this .Age = age;
}
}
}
2. 我们建立一个Winform界面,然后使用List<T>作为集合来保存多个Person对象。
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Text;
7 using System.Windows.Forms;
8
9 namespace AppBindingContext
10 {
11 public partial class Form1 : Form
12 {
13 //声明一个管理者
14 private CurrencyManager cm;
15 public Form1()
16 {
17 InitializeComponent();
18 //建立数据源集合.
19 List<Person> list = new List<Person>();
20 list.Add(new Person("LastName1", "FirstName1", 30));
21 list.Add(new Person("LastName2", "FirstName2", 31));
22 list.Add(new Person("LastName3", "FirstName3", 32));
23 list.Add(new Person("LastName4", "FirstName4", 33));
24 //数据绑定
25 this.textBox1.DataBindings.Add("Text", list, "LastName");
26 this.textBox2.DataBindings.Add("Text", list, "FirstName");
27 this.textBox3.DataBindings.Add("Text", list, "Age");
28 this.dataGridView1.DataSource = list;
29 //通过指定的数据源对象获得相应的CurrencyManager对象.
30 cm = (CurrencyManager)this.BindingContext[list];
31 }
32 //点击此按钮可以导航到上一条记录
33 private void button1_Click(object sender, EventArgs e)
34 {
35 cm.Position--;
36 }
37 //点击此按钮可以导航到下一条记录
38 private void button2_Click(object sender, EventArgs e)
39 {
40 cm.Position++;
41 }
42 }
43 }
先下载上面的代码看看,体会一下CurrencyManager的作用.你也可以看看CurrencyManager的其他的方法和属性,其实大致就可以明白这个对象是做什么用.
它公布出来的很多方法其实都是用于操作集合用的.然而这种"操作"是依赖数据绑定完成的,而不是单纯的为了操作集合而操作.