前面章節中,對簡單綁定和複雜綁定做了簡單的描述。在這章中,我們將所有的這些東西串在一起看看數據綁定的全貌。
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對象。
先下載上面的代碼看看,體會一下CurrencyManager的作用.你也可以看看CurrencyManager的其他的方法和屬性,其實大致就可以明白這個對象是做什麼用.
它公佈出來的很多方法其實都是用於操作集合用的.然而這種"操作"是依賴數據綁定完成的,而不是單純的爲了操作集合而操作.
到上一篇文章結束,你應該知道簡單綁定的原理了及Binding對象在簡單綁定起到的作用。如果你留心的話,你會發現我在上一篇中留下了一個列表。其中列舉了能夠被數據綁定支持的“數據源”都有那些。其中主要包含單一對象、集合及集合中包含集合這樣的三大類別的對象。其中在簡單綁定中,我已經描述瞭如何綁定對象到控件中。而綁定到集合和集合中的集合就需要了解複雜綁定了。
複雜綁定可以簡單的理解爲如何將集合或集合的集合綁定到控件的過程。在這個過程中,你對發現有某些地方和簡單綁定很相似,但實際上當控件綁定到集合類的對象的時候和我們認識的簡單綁定的過程是有區別的。複雜綁定是依賴與簡單綁定過程的。先來看看下面的例子:
項目包含兩個部分:Person類和Form類。
Person類的代碼:
2using System.Collections.Generic;
3using System.Text;
4
5namespace 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代碼
2using System.Collections.Generic;
3using System.ComponentModel;
4using System.Data;
5using System.Drawing;
6using System.Text;
7using System.Windows.Forms;
8
9namespace 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的代碼:
2using System.Collections.Generic;
3using System.ComponentModel;
4using System.Data;
5using System.Drawing;
6using System.Text;
7using System.Windows.Forms;
8
9namespace 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類,如果你想深入的瞭解數據綁定機制的話。
下一篇中我將進一步對數據綁定進行解釋。
代碼下載
完成...