綁定動态資料是做 Silverlight 程式時經常會遇到的問題。本文介紹 Silverlight 通過綁定索引器實作綁定動态資料,即在設計時不知道資料的結構,如在設計時不知道要綁定的類有哪些屬性。
綁定索引器是 Silverlight 4 新增的特性,這一特性使用我們可以在設計時不必知道要綁定的類有哪些屬性,但是還可以綁定。下面先看一下如何綁定索引器。
<code>1</code>
<code><TextBox Grid.Row=</code><code>"0"</code> <code>Height=</code><code>"23"</code> <code>Width=</code><code>"148"</code>
<code>2</code>
<code> </code><code>HorizontalAlignment=</code><code>"Center"</code> <code>VerticalAlignment=</code><code>"Center"</code>
<code>3</code>
<code> </code><code>Name=</code><code>"txtName"</code> <code>Text=</code><code>"<span style="</code><code>color: #ff0000;</code><code>" color="</code><code>#ff0000</code><code>">{Binding Path=[name]}</span>"</code> <code>/></code>
<code>4</code>
<code><TextBox Grid.Row=</code><code>"1"</code> <code>Height=</code><code>"23"</code> <code>Width=</code><code>"148"</code>
<code>5</code>
<code>6</code>
<code> </code><code>Name=</code><code>"txtAge"</code> <code>Text=</code><code>"<span style="</code><code>color: #ff0000;</code><code>" color="</code><code>#ff0000</code><code>">{Binding Path=[age]}</span>"</code> <code>/></code>
綁定索引器的文法和通常綁定資料的文法非常相似,格式為:Binding="{Binding Path=[Key]}" 。下面建立一個要綁定的 Person 類,并添加一個索引器,完整的代碼如下:
<code>01</code>
<code>public</code> <code>class</code> <code>Person : INotifyPropertyChanged</code>
<code>02</code>
<code>{</code>
<code>03</code>
<code> </code><code>private</code> <code>Dictionary<</code><code>string</code><code>,</code><code>object</code><code>> data =</code><code>new</code> <code>Dictionary<</code><code>string</code><code>,</code><code>object</code><code>>();</code>
<code>04</code>
<code>05</code>
<code> </code><code>public</code> <code>object</code> <code>this</code><code>[</code><code>string</code> <code>key]</code>
<code>06</code>
<code> </code><code>{</code>
<code>07</code>
<code> </code><code>get</code>
<code>08</code>
<code> </code><code>{</code>
<code>09</code>
<code> </code><code>if</code> <code>(!data.ContainsKey(key))</code>
<code>10</code>
<code> </code><code>data[key] =</code><code>null</code><code>;</code>
<code>11</code>
<code>12</code>
<code> </code><code>return</code> <code>data[key];</code>
<code>13</code>
<code> </code><code>}</code>
<code>14</code>
<code> </code><code>set</code>
<code>15</code>
<code>16</code>
<code> </code><code>data[key] = value;</code>
<code>17</code>
<code> </code><code>NotifyPropertyChanged(</code><code>""</code><code>);</code>
<code>18</code>
<code>19</code>
<code> </code><code>}</code>
<code>20</code>
<code>21</code>
<code> </code><code>public</code> <code>string</code><code>[] Keys</code>
<code>22</code>
<code>23</code>
<code>24</code>
<code>25</code>
<code> </code><code>return</code> <code>data.Keys.ToArray();</code>
<code>26</code>
<code>27</code>
<code>28</code>
<code>29</code>
<code> </code><code>public</code> <code>event</code> <code>PropertyChangedEventHandler PropertyChanged;</code>
<code>30</code>
<code>31</code>
<code> </code><code>public</code> <code>void</code> <code>NotifyPropertyChanged(</code><code>string</code> <code>propertyName)</code>
<code>32</code>
<code>33</code>
<code> </code><code>if</code> <code>(PropertyChanged !=</code><code>null</code><code>)</code>
<code>34</code>
<code> </code><code>PropertyChanged(</code><code>this</code><code>,</code><code>new</code> <code>PropertyChangedEventArgs(propertyName));</code>
<code>35</code>
<code>36</code>
<code>}</code>
下面建立一個 Person 類的執行個體,并綁定到第一段代碼建立的兩個TextBox上面。
<code>Person person =</code><code>new</code> <code>Person();</code>
<code>person[</code><code>"name"</code><code>] =</code><code>"avatar"</code><code>;</code>
<code>person[</code><code>"age"</code><code>] = 123456;</code>
<code>LayoutRoot.DataContext = person;</code>
運作結果如下:
上面的代碼将索引器的參數名直接寫在代碼中了,如果在設計時不知道類的結構,上面的代碼依然無法解決問題。我們可以通過下面的代碼輕松解決這個問題:
<code>for</code> <code>(</code><code>int</code> <code>i = 0; i < person.Keys.Length; i++)</code>
<code> </code><code>TextBox txt =</code><code>new</code> <code>TextBox()</code>
<code> </code><code>Width = 200,</code>
<code> </code><code>HorizontalAlignment = HorizontalAlignment.Center,</code>
<code> </code><code>VerticalAlignment = VerticalAlignment.Center</code>
<code> </code><code>};</code>
<code> </code><code>Binding binding =</code><code>new</code> <code>Binding(</code><code>"["</code> <code>+ person.Keys[i] +</code><code>"]"</code><code>)</code>
<code> </code><code>Mode = BindingMode.TwoWay</code>
<code> </code><code>txt.SetBinding(TextBox.TextProperty, binding);</code>
<code> </code><code>txt.SetValue(Grid.RowProperty, i);</code>
<code> </code><code>LayoutRoot.Children.Add(txt);</code>
這段代碼的運作結果和上面的代碼的運作結果完全一樣。
以上講的是通過索引器将單個類綁定到 Silverlight 控制上,如果要将包含多個類的清單綁定到 DataGrid 上呢?這個問題我們可以通過類似的方式輕松解決。下面是将多個類的清單綁定到 DataGrid 上的代碼:
<code>private</code> <code>List<Person> lst =</code><code>new</code> <code>List<Person>();</code>
<code>Person person1 =</code><code>new</code> <code>Person();</code>
<code>person1[</code><code>"name"</code><code>] =</code><code>"Avatar"</code><code>;</code>
<code>person1[</code><code>"age"</code><code>] = 52342;</code>
<code>Person person2 =</code><code>new</code> <code>Person();</code>
<code>person2[</code><code>"name"</code><code>] =</code><code>"Harry Potter"</code><code>;</code>
<code>person2[</code><code>"age"</code><code>] = 33432;</code>
<code>lst.Add(person1);</code>
<code>lst.Add(person2);</code>
<code>string</code><code>[] headers = person1.Keys;</code>
<code>for</code> <code>(</code><code>int</code> <code>i = 0; i < headers.Length; i++)</code>
<code> </code><code>dataGrid1.Columns.Add(</code><code>new</code> <code>DataGridTextColumn()</code>
<code> </code><code>Header = headers[i],</code>
<code> </code><code>CanUserSort =</code><code>true</code><code>,</code>
<code> </code><code>IsReadOnly =</code><code>false</code><code>,</code>
<code> </code><code>Binding =</code><code>new</code> <code>Binding(</code><code>"["</code> <code>+ headers[i] +</code><code>"]"</code><code>)</code>
<code> </code><code>Mode = BindingMode.TwoWay</code>
<code> </code><code>});</code>
<code>dataGrid1.ItemsSource = lst;</code>
注意:如果想讓使用者可以點選表頭排序,需要設定每一列的 CanUserSort = true 。運作結果如下圖:
如果需要顯示 Person 類的性别,隻需在上面的代碼中添加:person1["gender"] = "男"; person2["gender"] = "男"; 就可以實作,運作結果如下: