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