關於 Data Binding 與 ItemTemplate
前些日子在開發 Windows 8 Metro Apps 遇到了一個問題,也就是 Data Binding 與 ItemTemplate 之間的關係一直搞不定。由於是利用工作之餘的時間來開發,所以,也沒太多時間來找出如何達到 Binding 的方法。因為,一開始在 Visual Studio 11 Beta 時,它的 Grid 範例都幫你做得好好的。所以,這部份一下子就讓我給忽略了。導致我後來在開發時 “踏到鐵幫”XD
後來我才發現,其實,這一點都不難~冏
如果你是從 Blank App 開始的話:
首先先建立一個 BindableBase 的 Class (其實如果是從 Grid App 開始,Visual Studio 就會幫你準備好了 ),其內容也很簡單: 一個 event 以及兩個 method。其最主要的目的就是當你的變數值改變時,可以去通知另外相關的物件也要跟著變。
1: public abstract class BindableBase : INotifyPropertyChanged {
2:
3: public event PropertyChangedEventHandler PropertyChanged;
4:
5: protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] String propertyName = null) {
6: if (object.Equals(storage, value))
7: return false;
8:
9: storage = value;
10: this.OnPropertyChanged(propertyName);
11: return true;
12: }
13:
14: protected void OnPropertyChanged([CallerMemberName] string propertyName = null) {
15: var eventHandler = this.PropertyChanged;
16: if (eventHandler != null) {
17: eventHandler(this, new PropertyChangedEventArgs(propertyName));
18: }
19: }
20: }
再來就是讓要做 Binding 的 Class 去繼承 BindableBase 這個類別: 這裡我以一個 Person Class 為例
1: class Person : BindableBase{
2: string _name = string.Empty;
3: public String Name{
4: get { return this._name; }
5: set { this.SetProperty(ref this._name, value); }
6: }
7:
8: string _telephone = string.Empty;
9: public String Telephone{
10: get{ return this._telephone; }
11: set{ this.SetProperty(ref this._telephone, value); }
12: }
13:
14: string _address = string.Empty;
15: public String Address{
16: get{ return this._address; }
17: set{ this.SetProperty(ref this._address, value); }
18: }
19:
20: public Person(string name, string telephone, string address){
21: Name = name;
22: Telephone = telephone;
23: Address = address;
24: }
25: }
第三:在 XAML 的 code behind 上去新增一個 ObservableCollection<T> ;以剛才的 Person 為例: 新增如下
1: private ObservableCollection<Person> personList = new ObservableCollection<Person>();
假設我們所要 Binding 的資料是要顯示在 ComboBox 上, 則先在 XAML 上新增一個 ComboBox 的 ItemTemplate。其中我們可以看到,Binding Path 的部份就是指 Person 類別的 Property (這裡是以 Name 和 Telephone為範例)
1: <ComboBox x:Name="MyComboBox1" Width="300" Height="50">
2: <ComboBox.ItemTemplate>
3: <DataTemplate>
4: <TextBlock Text="{Binding Path="Name" verticalAlignment="Center"/>
5: <TextBlock Text="{Binding Path="Telephone" verticalAlignment="Center"/>
6: </DataTemplate>
7: </ComboBox.ItemTemplate>
8: </ComboBox>
1: MyComboBox1.ItemSource = personList; // persionList 是剛才建立的 ObservableCollection<Person>
這樣一來就完成了 Binding 了。你的 personList 內的資料有任何變動,UI上也是會跟者變動。
最後,如果有更好的方式也歡迎前輩們給予指點!!! ^_^