關於 Data Binding 與 ItemTemplate

  • 4876
  • 0

關於 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>
 
接著就是在 Code Behind 上新增聯結:
   1: MyComboBox1.ItemSource = personList; // persionList 是剛才建立的 ObservableCollection<Person>

這樣一來就完成了 Binding 了。你的 personList 內的資料有任何變動,UI上也是會跟者變動。

最後,如果有更好的方式也歡迎前輩們給予指點!!! ^_^