深入淺出WPF(9)——資料的綠色通道,Binding(下)
 
小序:
看著自己上一篇技術文章,指算來,已經月餘沒有動筆了——實在是不像話。最近一來是忙工作,二來是興趣點放在了設計模式上,而且嘗試著把設計模式也“深入淺出”了一把,當然啦,因為對於design pattern我也是初學,在沒有經過大家檢驗之前我是不敢拿到blog裡丟人現眼滴~~~現在專案組裡由喵喵同學、美女燕、大馬同學和小馬同學一同push一個“設計模式沙龍”,大家一起學習和討論這些模式和如何應用在我們的專案裡做重構。等活動結束後,我心裡有底了,就把文章放上來:)
 
N久不動筆了……上回寫到哪兒了?呃~~~我們們繼續吧!
 
正文
如果用一句話概括前幾篇關於data binding的文章,那就是:介紹了資料驅動(介面)開發的基本原理,以及如何使用Binding類的例項連線資料來源與資料表現元素、形成一對一的binding(為了讓資料有效、安全,我們還可以新增Converter和ValidationRule等附件)
 
注意啦,我強調了一下——是一對一的binding哦!也就是說,一個binding例項一端是資料來源、一端是表現元素。現在問題來了:實際工作中,我們操作的大部分資料都是集合,怎麼進行“群體binding”呢?呵呵,這就引出了我們今天的第一個topic——對集合進行binding。
 
集合Binding揭祕
我們想這樣一個問題——如果我有一個List<Student>的例項,裡面裝著二十個Student物件,現在我想讓一個ListBox顯示出學生的Name,並且當集合中有Student物件的Name發生改變時,ListBox的Item也立刻顯示出來,應該怎麼做呢?
有人會說:那還不好辦?做一個迴圈,按照集合元素的數量生成相應多的ListBoxItem,並把每個ListBoxItem的Text屬性(如果有)用Binding一對一連線到List中的Student物件上不就結了?
我沒試過這樣行不行,但我知道,這違反了“資料驅動UI”的原則——請記住,在WPF開發時,不到萬不得已,不要去打UI元素的主意、不要把UI元素摻合進任何運算邏輯。拿上面的例子來說,手動地去生成ListBoxItem就已經超越了“資料驅動UI”的限制,是不恰當的作法。
OK,讓我們看看微軟提供的“正宗集合binding”吧!
首先我們得準備一個用來存放資料的集合,對於這個集合有一個特殊的要求,那就是,這個集合一定要是實現了IEnumerable介面的集合。為什麼呢?原因很簡單,實現了IEnumerable介面就意味著這個集合裡的元素是可列舉的,可列舉就意味著這個集合裡的元素是同一個型別的(至少具有相同的父類),元素是同一個型別的就意味著在每個元素中我都能找到同樣的屬性。舉個例子,如果一個實現了IEnumerable的集合裡裝的是Student元素,這就意味著每個元素都有諸如ID、Name、Age等屬性,對於任何一個元素我都不會找不到ID、Name或者Age——不然就沒辦法“批量binding”了;如果一個實現了IEnumerable介面的集合裡除了有Student物件,還有Teacher物件、Programmer物件,怎麼辦呢?這時候,這個集合肯定只能拿Student、Teacher、Programmer的共同基類來進行列舉了,假設它們的共同基類是Human,那Human至少會有Name和Age屬性吧——我們可以拿這兩個屬性去做binding的Path,而集合裡的每一個元素都作為一個獨立的資料來源。
下面我給出核心程式碼。
 
首先我們準備了一個Student類,包含StuNum、Name、Age三個屬性,
  1. class Student   
  2. {   
  3.     public int StuNum { getset; }