在C#操作數(shù)據(jù)庫(kù)過程中,針對(duì)一般的文本控件,比如TextBox,Label等,我們賦值直接使用類似TextBox.Text=****的方式來進(jìn)行,這種方式從某種意義上來說的確是最簡(jiǎn)便的方式,但是對(duì)于復(fù)雜一些的空間,比如說DataGridView,這個(gè)時(shí)候,綁定數(shù)據(jù)源我們一般使用DataGridView1.DataSource=****的方式來進(jìn)行,如果數(shù)據(jù)源稍微有更改,那么只需要重新調(diào)用綁定一遍即可??梢哉f這種方式是單向的,也即從數(shù)據(jù)庫(kù)到UI,但是有沒有一種方式能夠?qū)崿F(xiàn)數(shù)據(jù)源改變的時(shí)候,不用重新綁定DataGridView就讓它能夠自動(dòng)刷新數(shù)據(jù)呢,當(dāng)然,這里要提到的就是DataBinding了。
下面來一步一步的進(jìn)行。
首先來看看示例一,主要是利用TextBox的DataBindings方式來進(jìn)行數(shù)據(jù)綁定:
在界面上放置一個(gè)TextBox,名稱為textBox1,再放置一個(gè)TrackBar,名稱為trackBar1,然后編寫綁定代碼如下:
textBox1.DataBindings.Add("Text", trackBar1, "Value", false, DataSourceUpdateMode.OnPropertyChanged);
這樣,我們就可以非常明顯的看到,當(dāng)textBox1文本框里面的值改變的時(shí)候,trackBar1的值跟著改變;當(dāng)trackBar1的值改變的時(shí)候,文本框中的值也跟著改變,看來,這種改變是雙向的。
在這里我要啰嗦下DataBindings的用法,雖然網(wǎng)上和MSDN上對(duì)其的介紹已經(jīng)是多如牛毛:
/************************************************ * 第一個(gè)值:要綁定到TextBox的什么地方 * 第二個(gè)值:數(shù)據(jù)源是什么 * 第三個(gè)值:應(yīng)該取數(shù)據(jù)源的什么屬性 * 第四個(gè)值:是否開啟數(shù)據(jù)格式化 * 第五個(gè)值:在什么時(shí)候啟用數(shù)據(jù)源綁定 * *********************************************/ textBox1.DataBindings.Add("Text", trackBar1, "Value", false, DataSourceUpdateMode.OnPropertyChanged);
上面只是一種最簡(jiǎn)便的方式,但是我們能不能綁定自己定義的類,把自定義類當(dāng)做數(shù)據(jù)源呢?當(dāng)然能。DataBindings能夠接受任意類型的Object類型的數(shù)據(jù)源。
定義類如下:
public class MyDataSource { public string Myvalue { get; set; } }
然后我們?cè)诖a中可以按照如下方式綁定:
MyDataSource mydatasource = new MyDataSource(); //應(yīng)用于第二種方式
private void mainFrm_Load(object sender, EventArgs e) { /********************************************* * 這個(gè)主要就是通過一個(gè)外部的類,當(dāng)做數(shù)據(jù)源 * *********************************************/ mydatasource.Myvalue = "這是個(gè)測(cè)試"; textBox2.DataBindings.Add("Text",mydatasource,"Myvalue",false,DataSourceUpdateMode.OnPropertyChanged);
那么,當(dāng)我們?cè)诮缑嫔峡吹臅r(shí)候,就會(huì)發(fā)現(xiàn),textBox2中顯示的是“這是個(gè)測(cè)試”五個(gè)字。
但是,有時(shí)候定義類太麻煩,能不能通過給定的屬性來充當(dāng)數(shù)據(jù)源呢?這個(gè)當(dāng)然也能,這樣的方式,只適合在一些應(yīng)用很簡(jiǎn)單的場(chǎng)合,可以按照如下方式綁定:
public int Num { get; set; } //應(yīng)用于第三種方式
private void mainFrm_Load(object sender, EventArgs e) { /***************************************** *這個(gè)主要就是通過本身?yè)碛械膶傩裕?dāng)做數(shù)據(jù)源 ****************************************/ Num = 5; textBox3.DataBindings.Add("Text",this,"Num", false,DataSourceUpdateMode.OnPropertyChanged); }
這樣,我們就可以把一個(gè)類內(nèi)部的屬性當(dāng)做數(shù)據(jù)源來使用了。需要注意的是,之所以利用this來充當(dāng)數(shù)據(jù)源,是因?yàn)榇绑w他本身就是一個(gè)類,Num充當(dāng)了這個(gè)類中的屬性而已。
接下來,我們就需要說到重頭戲了,DataGridView的表現(xiàn)形式。
對(duì)于這個(gè)數(shù)據(jù)控件,我相信大家都不會(huì)陌生,但是如何實(shí)現(xiàn)自定義的數(shù)據(jù)綁定呢?請(qǐng)看代碼:
這里我們首先應(yīng)該定義一個(gè)Model類,以便保存數(shù)據(jù):
public class BlogNew { public int BlogID { get; set; } public string BlogTitle { get; set; } }
然后我們利用List<T>泛型來保存數(shù)據(jù),最后是將這個(gè)數(shù)據(jù)源綁定到dataGridView1控件上:
public List<BlogNew> blogNews { get; set; } //應(yīng)用于第四種方式
private void mainFrm_Load(object sender, EventArgs e) { blogNews = new List<BlogNew>(); blogNews.Add(new BlogNew { BlogID = 1, BlogTitle = "人生若只如初見" }); blogNews.Add(new BlogNew { BlogID = 2, BlogTitle = "何事秋風(fēng)悲畫扇" }); blogNews.Add(new BlogNew { BlogID=3,BlogTitle="最喜歡納蘭性德"});
dataGridView1.DataBindings.Add("DataSource", this, "blogNews", false, DataSourceUpdateMode.OnPropertyChanged);
}
這樣綁定完畢以后,在界面上,我們可以非常自豪的看到自己新加的三條數(shù)據(jù)。當(dāng)然,這個(gè)沒有什么奇怪的。需要注意的是,在這里,我們?cè)O(shè)置了DataSourceUpdateMode.OnPropertyChanged,也就是說,當(dāng)數(shù)據(jù)源的改變的時(shí)候,數(shù)據(jù)將重新加載,那么為了測(cè)試數(shù)據(jù)能不能夠自動(dòng)重新加載(不需要重新綁定數(shù)據(jù)源),我們來做個(gè)測(cè)試,界面上加一個(gè)按鈕,用來添加一條新的記錄:
private void button3_Click(object sender, EventArgs e) { //在這里向DataGridView中插入一行 var data = dataGridView1.DataSource as List<BlogNew>; data.Add(new BlogNew { BlogID = 4, BlogTitle = "取次花叢懶回顧,半緣修道半緣君" });
foreach(BlogNew blogNew in dataGridView1.DataSource as List<BlogNew>) { /*********** * 當(dāng)我們心插入一條BlogID記錄為4的數(shù)據(jù)的時(shí)候,在界面上可以看出dataGridView1的dataSource已經(jīng)被更新, * 但是界面上依舊顯示為BlogID為1,2,3三條數(shù)據(jù),很奇怪 * *********************/ MessageBox.Show(blogNew.BlogID + "--" + blogNew.BlogTitle); } }
好了,這里我添加了一條新的數(shù)據(jù),并且沒有進(jìn)行數(shù)據(jù)重新綁定,點(diǎn)擊按鈕,但是悲劇發(fā)生了,界面上沒有任何新的記錄出現(xiàn),怎么回事?但是通過foreach循環(huán),我們發(fā)現(xiàn)第四條記錄明明被添加到數(shù)據(jù)源中了呀?怎么回事呢?其實(shí)我這里也沒有搞明白到底為什么,還請(qǐng)大家指教,要解決這個(gè)問題,我們應(yīng)該利用BindingList<T>泛型類來替換掉List<T>泛型類:
public BindingList<BlogNew> blogNewsRegardUI {get;set; } //應(yīng)用于DataGridView界面UI更新
private void mainFrm_Load(object sender, EventArgs e) { blogNewsRegardUI = new BindingList<BlogNew>(); blogNewsRegardUI.Add(new BlogNew { BlogID = 11, BlogTitle = "僵臥孤村不自哀" }); blogNewsRegardUI.Add(new BlogNew { BlogID = 12, BlogTitle = "尚思為國(guó)戍輪臺(tái)" }); blogNewsRegardUI.Add(new BlogNew { BlogID = 13, BlogTitle = "夜闌臥聽風(fēng)吹雨" });
dataGridView2.DataBindings.Add("DataSource", this, "blogNewsRegardUI", false, DataSourceUpdateMode.OnPropertyChanged);
}
private void button4_Click(object sender, EventArgs e) { /*這里主要用來解決DataGridView1界面不更新的問題,其實(shí)原因在于使用了List<BlogNew>,這里我們采用BindList<BlogNew> *通過測(cè)試,我們發(fā)現(xiàn),只要數(shù)據(jù)源改變,界面就可以自動(dòng)的進(jìn)行更新了,很是方便,不需要重新綁定 */ var dataRegardUI = dataGridView2.DataSource as BindingList<BlogNew>; dataRegardUI.Add(new BlogNew { BlogID = 20, BlogTitle = "竹外桃花三兩枝,春江水暖鴨先知" }); }
然后當(dāng)我們?cè)冱c(diǎn)擊添加按鈕的時(shí)候,我們發(fā)現(xiàn),雖然我們沒有重新綁定數(shù)據(jù)源(只是數(shù)據(jù)源有所改變),就導(dǎo)致界面正確的添加進(jìn)去數(shù)據(jù)了。
呵呵,希望有用,謝謝,下面附上截圖和全部代碼:

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms;
namespace WindowsFormsApplication1 { public partial class mainFrm : Form { public mainFrm() { InitializeComponent(); }
MyDataSource mydatasource = new MyDataSource(); //應(yīng)用于第二種方式 public int Num { get; set; } //應(yīng)用于第三種方式
public List<BlogNew> blogNews { get; set; } //應(yīng)用于第四種方式
public BindingList<BlogNew> blogNewsRegardUI {get;set; } //應(yīng)用于DataGridView界面UI更新
private void mainFrm_Load(object sender, EventArgs e) { #region 測(cè)試一 /************************************************ * 第一個(gè)值:要綁定到TextBox的什么地方 * 第二個(gè)值:數(shù)據(jù)源是什么 * 第三個(gè)值:應(yīng)該取數(shù)據(jù)源的什么屬性 * 第四個(gè)值:是否開啟數(shù)據(jù)格式化 * 第五個(gè)值:在什么時(shí)候啟用數(shù)據(jù)源綁定 * *********************************************/ textBox1.DataBindings.Add("Text", trackBar1, "Value", false, DataSourceUpdateMode.OnPropertyChanged); #endregion
#region 測(cè)試二 /********************************************* * 這個(gè)主要就是通過一個(gè)外部的類,當(dāng)做數(shù)據(jù)源 * *********************************************/ mydatasource.Myvalue = "這是個(gè)測(cè)試"; textBox2.DataBindings.Add("Text",mydatasource,"Myvalue",false,DataSourceUpdateMode.OnPropertyChanged); #endregion
#region 測(cè)試三 /***************************************** *這個(gè)主要就是通過本身?yè)碛械膶傩?,?dāng)做數(shù)據(jù)源 ****************************************/ Num = 5; textBox3.DataBindings.Add("Text",this,"Num", false,DataSourceUpdateMode.OnPropertyChanged); #endregion
#region 測(cè)試四 : List<T> blogNews = new List<BlogNew>(); blogNews.Add(new BlogNew { BlogID = 1, BlogTitle = "人生若只如初見" }); blogNews.Add(new BlogNew { BlogID = 2, BlogTitle = "何事秋風(fēng)悲畫扇" }); blogNews.Add(new BlogNew { BlogID=3,BlogTitle="最喜歡納蘭性德"});
dataGridView1.DataBindings.Add("DataSource", this, "blogNews", false, DataSourceUpdateMode.OnPropertyChanged);
#endregion
#region 測(cè)試五 : BindingList<T> blogNewsRegardUI = new BindingList<BlogNew>(); blogNewsRegardUI.Add(new BlogNew { BlogID = 11, BlogTitle = "僵臥孤村不自哀" }); blogNewsRegardUI.Add(new BlogNew { BlogID = 12, BlogTitle = "尚思為國(guó)戍輪臺(tái)" }); blogNewsRegardUI.Add(new BlogNew { BlogID = 13, BlogTitle = "夜闌臥聽風(fēng)吹雨" });
dataGridView2.DataBindings.Add("DataSource", this, "blogNewsRegardUI", false, DataSourceUpdateMode.OnPropertyChanged);
#endregion }
private void button1_Click(object sender, EventArgs e) { //從這里可以看出,改變了TextBox2中的值,這里的值也改變了,原因是因?yàn)轭悓儆谝妙愋?/span> MessageBox.Show(mydatasource.Myvalue); }
private void button2_Click(object sender, EventArgs e) { //從這里可以看出,改變了TextBox3中的值,這里的值也改變了, //原因是Num被當(dāng)做了當(dāng)前窗體的一個(gè)屬性(窗體本身就是一個(gè)類),也屬于引用類型 MessageBox.Show(Num.ToString()); }
private void button3_Click(object sender, EventArgs e) { //在這里向DataGridView中插入一行 var data = dataGridView1.DataSource as List<BlogNew>; data.Add(new BlogNew { BlogID = 4, BlogTitle = "取次花叢懶回顧,半緣修道半緣君" });
foreach(BlogNew blogNew in dataGridView1.DataSource as List<BlogNew>) { /*********** * 當(dāng)我們心插入一條BlogID記錄為4的數(shù)據(jù)的時(shí)候,在界面上可以看出dataGridView1的dataSource已經(jīng)被更新, * 但是界面上依舊顯示為BlogID為1,2,3三條數(shù)據(jù),很奇怪 * *********************/ MessageBox.Show(blogNew.BlogID + "--" + blogNew.BlogTitle); } }
private void button4_Click(object sender, EventArgs e) { /*這里主要用來解決DataGridView1界面不更新的問題,其實(shí)原因在于使用了List<BlogNew>,這里我們采用BindList<BlogNew> *通過測(cè)試,我們發(fā)現(xiàn),只要數(shù)據(jù)源改變,界面就可以自動(dòng)的進(jìn)行更新了,很是方便,不需要重新綁定 */ var dataRegardUI = dataGridView2.DataSource as BindingList<BlogNew>; dataRegardUI.Add(new BlogNew { BlogID = 20, BlogTitle = "竹外桃花三兩枝,春江水暖鴨先知" }); } }
public class MyDataSource { public string Myvalue { get; set; } }
public class BlogNew { public int BlogID { get; set; } public string BlogTitle { get; set; } } }

截圖如下:

參考文檔:http://laiyuhan.blog.163.com/blog/static/1060389320101130101421991/
|