WinForm中實(shí)現(xiàn)雙向數(shù)據(jù)綁定的示例詳解
前言
在開發(fā) WinForm 應(yīng)用程序時(shí),常常需要將數(shù)據(jù)模型與用戶界面進(jìn)行同步。傳統(tǒng)的做法是手動(dòng)監(jiān)聽 UI 變化并更新數(shù)據(jù)模型,或者反過(guò)來(lái)更新 UI 控件,這種方式不僅繁瑣,而且容易出錯(cuò)。
為了解決這個(gè)問(wèn)題,許多現(xiàn)代 UI 框架都支持雙向數(shù)據(jù)綁定(Two-Way Data Binding),即當(dāng)模型數(shù)據(jù)發(fā)生變化時(shí),UI 自動(dòng)更新;而當(dāng)用戶通過(guò) UI 修改數(shù)據(jù)時(shí),模型也會(huì)自動(dòng)同步變化。這種機(jī)制極大提升了開發(fā)效率和代碼可維護(hù)性。
本文將以 WinForms 中的 DataGridView
控件為例,演示不使用雙向綁定時(shí)的數(shù)據(jù)同步問(wèn)題,并詳細(xì)介紹如何通過(guò)實(shí)現(xiàn) INotifyPropertyChanged
接口和使用 BindingList<T>
來(lái)實(shí)現(xiàn)真正的雙向數(shù)據(jù)綁定。
什么是雙向數(shù)據(jù)綁定?
雙向數(shù)據(jù)綁定是一種允許我們創(chuàng)建持久連接的技術(shù),使模型數(shù)據(jù)和用戶界面(UI)之間的交互能夠自動(dòng)同步。這意味著:
當(dāng)模型數(shù)據(jù)發(fā)生變化時(shí),UI 會(huì)自動(dòng)更新;
當(dāng)用戶在 UI 上修改數(shù)據(jù)后,模型數(shù)據(jù)也會(huì)自動(dòng)更新。
這種雙向數(shù)據(jù)綁定極大地簡(jiǎn)化了 UI 和模型數(shù)據(jù)之間的同步,開發(fā)可以更專注于業(yè)務(wù)邏輯,而不是手動(dòng)處理 UI 和數(shù)據(jù)的同步。
不使用雙向綁定的示例
通常在 WinForms 中使用 DataGridView
控件展示數(shù)據(jù)時(shí),我們會(huì)創(chuàng)建一個(gè)類作為數(shù)據(jù)模型,并將其對(duì)象列表綁定到 DataGridView
的 DataSource
屬性中。
例如,我們定義一個(gè) Person
類:
public class Person { public string? Name { get; set; } public string? Home { get; set; } }
然后創(chuàng)建一個(gè) List<Person>
數(shù)據(jù)源并綁定:
// 創(chuàng)建一個(gè)Person對(duì)象的列表 List<Person> people = new List<Person>() { new Person {Name = "張三", Home = "武漢" }, new Person {Name = "李四", Home = "南昌" }, new Person {Name = "王五", Home = "福州" }, }; dataGridView1.DataSource = people;
綁定后的效果如下圖所示:
當(dāng)我們對(duì) dataGridView1
中的數(shù)據(jù)進(jìn)行修改后,查看 people
列表中的數(shù)據(jù)是否也被更新:
Debug.WriteLine(people[0].Home); Debug.WriteLine(people[1].Home);
結(jié)果如下圖所示:
說(shuō)明在 dataGridView1
上修改數(shù)據(jù)后,people
列表也確實(shí)發(fā)生了變化。
但如果我們反向操作,在代碼中直接修改 people
列表的數(shù)據(jù):
people[0].Home = "廈門"; people[1].Home = "廈門";
此時(shí)發(fā)現(xiàn) dataGridView1
上的數(shù)據(jù)并不會(huì)立即刷新,必須點(diǎn)擊某個(gè)單元格才能觸發(fā)更新。
如果我們調(diào)用以下方法強(qiáng)制刷新:
dataGridView1.UpdateCellValue(1, 1); dataGridView1.UpdateCellValue(1, 2);
則可以看到部分?jǐn)?shù)據(jù)更新成功,但仍需手動(dòng)干預(yù):
這表明:默認(rèn)情況下,List<T>
并不能自動(dòng)通知 UI 進(jìn)行更新,因此無(wú)法實(shí)現(xiàn)真正的“雙向綁定”。
在 WinForms 中實(shí)現(xiàn)雙向數(shù)據(jù)綁定示例
為了實(shí)現(xiàn)雙向綁定,我們需要做兩件事:
1、模型類實(shí)現(xiàn) INotifyPropertyChanged
接口;
2、使用 BindingList<T>
替代 List<T>
作為數(shù)據(jù)源。
定義 Student 類并實(shí)現(xiàn) INotifyPropertyChanged
public class Student : INotifyPropertyChanged { private string? _name; public string Name { get => _name; set { _name = value; OnPropertyChanged(nameof(Name)); } } private string? _home; public string Home { get => _home; set { _home = value; OnPropertyChanged(nameof(Home)); } } public event PropertyChangedEventHandler? PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
創(chuàng)建 BindingList< Student> 數(shù)據(jù)源
BindingList<Student> students = new BindingList<Student>() { new Student { Name = "張三", Home = "武漢" }, new Student { Name = "李四", Home = "南昌" }, new Student { Name = "王五", Home = "福州" } }; dataGridView1.DataSource = students;
注意這里使用的不再是 List<T >
,而是 BindingList<T >
。這是關(guān)鍵所在,因?yàn)?nbsp;BindingList<T >
支持?jǐn)?shù)據(jù)變更的通知。
測(cè)試雙向綁定效果
我們?cè)诖a中修改數(shù)據(jù)源:
students[0].Home = "廈門"; students[1].Home = "廈門";
此時(shí) dataGridView1
會(huì)自動(dòng)更新,無(wú)需任何額外操作:
同樣地,如果我們?cè)?nbsp;dataGridView1
中編輯數(shù)據(jù),students
數(shù)據(jù)源也會(huì)隨之改變:
Debug.WriteLine(students[0].Home); Debug.WriteLine(students[1].Home);
輸出結(jié)果如下:
這表明雙向綁定已經(jīng)生效。
BindingList< T> 與 List< T> 的區(qū)別
特性 | BindingList< T> | List< T> |
---|---|---|
數(shù)據(jù)綁定支持 | ? 支持,自動(dòng)通知控件更新 | ? 不支持 |
更改通知事件 | ? 提供 ListChanged 事件 | ? 不提供 |
性能 | 相對(duì)稍慢 | 更快 |
適用場(chǎng)景 | 需要數(shù)據(jù)綁定的 UI 應(yīng)用 | 僅用于存儲(chǔ)數(shù)據(jù) |
總結(jié)
本文通過(guò)一個(gè)完整的案例,詳細(xì)講解了在 WinForms 中如何實(shí)現(xiàn)真正的雙向數(shù)據(jù)綁定。核心要點(diǎn)如下:
雙向數(shù)據(jù)綁定的本質(zhì) 是讓模型數(shù)據(jù)和 UI 界面保持自動(dòng)同步;
默認(rèn)情況下,List< T> + DataGridView 只能實(shí)現(xiàn)單向綁定(UI -> 數(shù)據(jù)),不能自動(dòng)響應(yīng)數(shù)據(jù)變化;
實(shí)現(xiàn)雙向綁定的關(guān)鍵:
模型類必須實(shí)現(xiàn)
INotifyPropertyChanged
接口;數(shù)據(jù)源應(yīng)使用
BindingList<T>
而不是List<T>
。
通過(guò)上述方式,我們可以輕松實(shí)現(xiàn) WinForm 中的數(shù)據(jù)綁定功能,提高開發(fā)效率,減少手動(dòng)同步帶來(lái)的錯(cuò)誤和復(fù)雜度。
希望這篇文章對(duì)大家理解 WinForm 中的雙向數(shù)據(jù)綁定有所幫助!大家如果正在開發(fā) WinForm 應(yīng)用,不妨嘗試使用這些技術(shù)來(lái)提升的項(xiàng)目質(zhì)量。
最后
以上就是WinForm中實(shí)現(xiàn)雙向數(shù)據(jù)綁定的示例詳解的詳細(xì)內(nèi)容,更多關(guān)于WinForm雙向數(shù)據(jù)綁定的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C# 實(shí)現(xiàn)ADSL自動(dòng)斷網(wǎng)和撥號(hào)的方法(適用于撥號(hào)用戶)
下面小編就為大家?guī)?lái)一篇C# 實(shí)現(xiàn)ADSL自動(dòng)斷網(wǎng)和撥號(hào)的方法(適用于撥號(hào)用戶)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-12-12Winform中實(shí)現(xiàn)圖片格式轉(zhuǎn)換
這篇文章主要介紹了Winform中實(shí)現(xiàn)圖片格式轉(zhuǎn)換的示例代碼,幫助大家更好的理解和使用winform開發(fā),感興趣的朋友可以了解下2020-12-12C#中DataTable 轉(zhuǎn)實(shí)體實(shí)例詳解
這篇文章主要介紹了C#中DataTable 轉(zhuǎn)實(shí)體實(shí)例詳解,需要的朋友可以參考下2017-04-04C#使用HtmlAgilityPack實(shí)現(xiàn)解析提取HTML內(nèi)容
HtmlAgilityPack是一個(gè)HTML解析類庫(kù),這篇文章主要為大家詳細(xì)介紹了C#如何使用HtmlAgilityPack實(shí)現(xiàn)解析提取HTML內(nèi)容,感興趣的小伙伴可以參考一下2023-12-12