此篇介紹如何繫結到資料集合的元件,如ListBox、ListView等等的元件。
這些元件都是集合,皆有繼承ItemsControl,所以在繫結實的方式會比較不一樣。
在這邊以ListBox元件作為範例。
並且分別介紹與用List
介紹
在此篇介紹如何繫結到資料集合的元件,如ListBox、ListView等等的元件。
這些元件都是集合,皆有繼承ItemsControl,所以在繫結實的方式會比較不一樣。
在這邊以ListBox元件作為範例。
並且分別介紹與用List<T> 與 ObservableCollection<T> 作為繫結的資料來源的差異
範例介紹:
本範例如用Windows Store App
為了要繫結至ListBox顯示資料的元件,在邏輯端通常會與用List<T>作為保存資料的結構方式,這邊以WantedData類別為例:
用來記錄想要的東西與價錢
public class WantedData {
public string Content{ get; set; }
public int Price { get; set; }
}
首先是XAML中的程式碼,在這邊用了一個ListBox顯示列出來的願望清單
並另外給予新增的部分,分別可以輸入想要的物品名稱與價錢,如下
<ListBox Name="wantedListBox1" FontSize="32" HorizontalAlignment="Left" Height="599" Margin="30,144,0,0" VerticalAlignment="Top" Width="382">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Content}" FontSize="24"/>
<TextBlock Text="{Binding Price}" FontSize="24"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox x:Name="wantedListBox2" FontSize="32" HorizontalAlignment="Left" Height="599" Margin="481,144,0,0" VerticalAlignment="Top" Width="388">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Content}" FontSize="24"/>
<TextBlock Text="{Binding Price}" FontSize="24"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Content="加入清單" FontSize="32" HorizontalAlignment="Left" Margin="921,422,0,0" VerticalAlignment="Top" Height="66" Width="154" Click="Button_Click"/>
<TextBox Name="wantedText" HorizontalAlignment="Left" Margin="921,211,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Height="48" Width="154"/>
<TextBlock HorizontalAlignment="Left" Margin="921,144,0,0" TextWrapping="Wrap" Text="想要的東西:" FontSize="40" VerticalAlignment="Top"/>
<TextBox x:Name="wantedPriceText" HorizontalAlignment="Left" Margin="921,353,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Height="48" Width="154"/>
<TextBlock HorizontalAlignment="Left" Margin="921,281,0,0" TextWrapping="Wrap" Text="價錢:" FontSize="40" VerticalAlignment="Top"/>
重新定義了ListBox的資料樣板DataTemplate,並繫結到WantedData 的資料
介面如下圖:
以下便來介紹如何實作。
透過ObservableCollection<T> 作為繫結的資料來源
一般而言會建議使用ObservableCollection<T> 作為繫結的資料來源,因為ObservableCollection<T>實作了INotifyCollectionChanged介面,相當於前一篇的INotifyPropertyChanged介面,告知UI端繫結的集合資料更改。
1.在MainPage中建立資料
ObservableCollection<WantedData> wantedDataCollection = new ObservableCollection<WantedData>
{
new WantedData{Content = "筆記本" , Price = 30},
new WantedData{Content = "鞋子" , Price = 2000}
};
這邊是範例資料,如果沒有的話就是new就好。
2.並在建構子設定ItemsSource的繫結來源為wantedDataList
//繫結來源
wantedListBox2.ItemsSource = wantedDataCollection;
3.在按鈕Click時新增資料到wantedDataCollection
//ObservableCollection
wantedDataCollection.Add(new WantedData { Content = wantedText.Text, Price = Convert.ToInt16(wantedPriceText.Text) });
以上完成!因為ObservableCollection幫我們實現了介面,所以我們不用像一般的簡單資料繫結,要去實現介面,只要向上面這樣,三個步驟加上自己要淳放資料的類別建立好即可。
List<T>作為繫結的資料來源
透過List<T>會因為沒有實現INotifyCollectionChanged介面所以要多兩個小步驟
1.初始化
List<WantedData> wantedDataList = new List<WantedData>
{
new WantedData{Content = "筆記本" , Price = 30},
new WantedData{Content = "鞋子" , Price = 2000}
};
2.建構時繫結來源
//繫結來源
wantedListBox1.ItemsSource = wantedDataList;
3.新增資料時,重新指定ItemsSource來源!
wantedDataList.Add(new WantedData { Content = wantedText.Text ,Price = Convert.ToInt16(wantedPriceText.Text) });
//使用List需要在指定一次
wantedListBox1.ItemsSource = null;
wantedListBox1.ItemsSource = wantedDataList;
因為沒有告知UI更新的關係,所以我們要主動重新在指定一次。
最後的畫面如下;
結合更新資料繫結
但是只有這樣,當我們要新增更改資料的話,會無法更改,原因在於,我們的WantedData沒有實作INotifyPropertyChanged的關係,所以當資料被更改時,UI的部分不會被更改
於是改成如下:
//INotifyPropertyChanged 用來協助更新資料
public class WantedData : INotifyPropertyChanged
{
string content;
int price;
public string Content
{
get { return content; }
set
{
content = value;
NotifyPropertyChanged("Content");
}
}
public int Price
{
get { return price; }
set
{
price = value;
NotifyPropertyChanged("Price");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{ PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); }
}
參考資料:
Update Listbox.ItemsSource when not using ObservableCollection
文章中的敘述如有觀念不正確錯誤的部分,歡迎告知指正 謝謝 =)
另外要轉載請附上出處 感謝