WinForm数据绑定--BindingContext

 前面章节中,对简单绑定和复杂绑定做了简单的描述。在这章中,我们将所有的这些东西串在一起看看数据绑定的全貌。

 

     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对象。

 

 

Code

其注意以上的第9行的语句this.BindingContext[list]。其中窗体有一个BindingContext属性,它在发生数据绑定后会自动维持一个key/value的集合,这个集合是一数据源对象作为KEY的,我们可以通过指定特定的数据源对象找到相应的“管理者”。注意前面我已经说过对于每个数据源而言都会有一个对应的“管理者”。上面的代码中应为数据源是集合类型所以会产生一个CurrencyManager对象。

 

     现在可以做个小结:BindingContext类维持一组可能BindingManagerBase对象,而这些BindingManagerBase对象和数据源对象又是一一对应的。

 

 


     复杂的讲解到此,下面我就做一个实际的例子来体会一下上面的描述。

 

     1.首先:我们创建一个自定义的对象:Person类

     

 

 

using  System;
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对象。

 

 

Code

 

 代码下载

 

     

    先下载上面的代码看看,体会一下CurrencyManager的作用.你也可以看看CurrencyManager的其他的方法和属性,其实大致就可以明白这个对象是做什么用.

它公布出来的很多方法其实都是用于操作集合用的.然而这种"操作"是依赖数据绑定完成的,而不是单纯的为了操作集合而操作.

 

 到上一篇文章结束,你应该知道简单绑定的原理了及Binding对象在简单绑定起到的作用。如果你留心的话,你会发现我在上一篇中留下了一个列表。其中列举了能够被数据绑定支持的“数据源”都有那些。其中主要包含单一对象、集合及集合中包含集合这样的三大类别的对象。其中在简单绑定中,我已经描述了如何绑定对象到控件中。而绑定到集合和集合中的集合就需要了解复杂绑定了。
    复杂绑定可以简单的理解为如何将集合或集合的集合绑定到控件的过程。在这个过程中,你对发现有某些地方和简单绑定很相似,但实际上当控件绑定到集合类的对象的时候和我们认识的简单绑定的过程是有区别的。复杂绑定是依赖与简单绑定过程的。先来看看下面的例子:
    项目包含两个部分:Person类和Form类。
    Person类的代码:

 1 using  System;
 2 using  System.Collections.Generic;
 3 using  System.Text;
 4
 5 namespace  ComplexBinding
 6 {
 7    //将要用于集合中的项对象。
 8    class Person
 9    {
10        private string _name;
11
12        public string Name
13        {
14            get return _name; }
15            set { _name = value; }
16        }

17        private int _age;
18
19        public int Age
20        {
21            get return _age; }
22            set { _age = value; }
23        }

24        //请保留这个构造函数。
25        public Person() { }
26        
27        public Person(string name, int age)
28        {
29            this.Name = name;
30            this.Age = age;
31        }

32    }

33}

34

    Form1的界面:


    
    











    
    Form1.cs代码
 

 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  ComplexBinding
10 {
11    public partial class Form1 : Form
12    {
13        public Form1()
14        {
15            InitializeComponent();
16            //建立一个集合,让它维持多个Person对象。
17            List<Person> list = new List<Person>();
18            list.Add(new Person("Caipeng"32));
19            list.Add(new Person("WangLiLi"30));
20            list.Add(new Person("Colin.Cai"0));
21            this.txtName.DataBindings.Add("Text", list, "Name");
22            this.txtAge.DataBindings.Add("Text", list, "Age");
23        }

24
25     
26    }

27}

    看看上面的代码中的21行和22行。你会发现两个TextBox中指定的数据源都是list(集合),在前面我讲过了,在此之后的那个参数一般是对象的属性名称。可list哪来的Name和Age属性呢?我在这里指定的"Name" 和 "Age"确实是属性,不过是Person对象中的属性。是不是满是疑问。其中可能的两个疑问是
1.TextBox怎么能显示一个集合呢,是不是数据绑定老人家搞错了?
2.list中没有Name和Age属性呀!!!就算指定的是list中维持的某个对象的属性,那应该关联的是第一个还是第二个呢??

    要确定的第一件事情,集合确实无法显示在TextBox这样的控件中。它可以很好的显示在类似DataGridView这样的控件中。其次要确定的事情是,两个TextBox中显示的数据确实来自list,但准确的说是来自list中包含的某一个Person对象。如果你现在就运行这个程序的话,你会发现两个TextBox中显示的数据是list中的第一个Person对象的Name和Age的值。

    我要解释一下,当数据源是一个集合的时候,到底发生了什么。
    首先,当数据绑定机制发现你绑定的数据源是一个集合,那么它会采取一种不同简单绑定的方式来对待这个数据源。如果是绑定到的是TextBox这样的控件话,它会先从那个集合中猎取一项出来。在这个例子里就是第一个person对象。
    接下来,数据绑定机制会将这个对象中的属性和控件中的属性关联起来(和简单绑定中所描述的一样。)
    再接下来,我不能欺骗大家没有“再接下来”了。上面的两个步骤就已经完成了一个复杂绑定。
    谁负责处理以上的过程呢?是BindingContext类,它管理着这个过程。(如果我的理解能力没有问题的话)
    没有你们想象中的复杂吧!简单到你想骂我。别骂,之所以这样简单只因为我还没有讲到难的地方。不管怎样,你已经认识了复杂绑定了。
    
    接下来我们将上面的例子做进一步的修改。看看下面的代码:
    Form1界面:
    
    Form1的代码:
    

 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  ComplexBinding
10 {
11    public partial class Form1 : Form
12    {
13        CurrencyManager cm;
14        public Form1()
15        {
16            InitializeComponent();
17            //建立一个集合,让它维持多个Person对象。
18            List<Person> list = new List<Person>();
19            list.Add(new Person("Caipeng"32));
20            list.Add(new Person("WangLiLi"30));
21            list.Add(new Person("Colin.Cai"0));
22            this.txtName.DataBindings.Add("Text", list, "Name");
23            this.txtAge.DataBindings.Add("Text", list, "Age");
24            //增加以下的语句,获得管理集合的管理对象.
25            //下面的两个button演示cm如果管理集合的简单方法.
26            cm = (CurrencyManager)this.BindingContext[list];
27        }

28
29        private void button2_Click(object sender, EventArgs e)
30        {
31            //将当前的位置++
32            cm.Position++;
33        }

34
35        private void button1_Click(object sender, EventArgs e)
36        {
37            //将当前的位置--
38            cm.Position--;
39        }

40
41     
42    }

43}

    可先看看上面的例子的效果。你会发现当你点击Button2或Button1的时候,两个控件中的数据会发生相应的变化。我想从这个例子证明我以上描述复杂绑定的过程是正确的并且也想从这个例子衍生出另一个我们值得关注的问题。那就是你不得不去认识的一个BindingContext类,如果你想深入的了解数据绑定机制的话。
    下一篇中我将进一步对数据绑定进行解释。
    代码下载

    完成...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值