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對象。
1 //建立數據源對象
2 List<Human> list = new List<Human>();
3 list.Add(new Human("cai", "peng"));
4 list.Add(new Human("cai", "peng"));
5 //發生綁定
6 this.TextBox1.DataBindings.Add("Text", list, "LastName");
7 this.TextBox1.DataBindings.Add("Text", list, "FirstName");
8 //獲得CurrencyManager
9 CurrencyManager cm = (CurrencyManager)this.BindingContext[list];
10
11
其注意以上的第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 }