現在起將新開一個系列記錄自己在學習與開發Windows Phone項目時遇到的問題的解決方案以及一些開發方面的小技巧,希望能起到溫故而知新的作用。在Windows Phone開發中,經常會與ListBox打交道,ListBox也是一個很方便的控制項,特別是經過資料繫結之後,關於ListBox,有很多的知識可以學習,園子裡也有不少關於ListBox應用方面的文章,之前在使用ListBox時,想動態後台代碼中進行ListBoxItem的增刪,但遇到了"Operation not supperted on read-only collection"這個錯誤。
最後問題解決了,卻發現解決的過程中有不少值得注意的知識點,不單在Windows Phone開發,在WPF開發,Silverlight開發中也是同樣的處理。這裡用一個簡單的例子來說明問題的解決方案。
建立項目[ListBoxDemo],XAML 檔案中放置一個 ListBox 並進行資料繫結,我們通過背景代碼去設定ListBox的Itemsource。
<StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <ListBox x:Name="ListBox1" > <ListBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding}" Style="{StaticResource PhoneTextNormalStyle}"/> </DataTemplate> </ListBox.ItemTemplate> </ListBox> <Button x:Name="deleteBtn" Content="刪除資料" Click="deleteBtn_Click"/> <Button x:Name="addBtn" Content="增加資料" Click="addBtn_Click"/> <Button x:Name="clearBtn" Content="清空Listbox" Click="clearBtn_Click"/></StackPanel>
private void initializeListBox(){ List<string> source = new List<string> { "item1","item2","item3","item4","item5","item6" }; this.ListBox1.ItemsSource = source;}
當我們初始化好ListBox後,想通過三個按鈕去動態進行資料的更改,這時,如果我們想刪除第一個ListBoxItem的話,通過下面的代碼實現則會得到一個這樣的結果。
//刪除資料private void deleteBtn_Click(object sender, RoutedEventArgs e){ if (this.ListBox1.Items.Count > 0) { this.ListBox1.Items.RemoveAt(1); }}//添加資料private void addBtn_Click(object sender, RoutedEventArgs e){ this.ListBox1.Items.Add("item7");}//清空列表private void clearBtn_Click(object sender, RoutedEventArgs e){ this.ListBox1.Items.Clear();}
這裡我們遇到的問題是,如果通過後台綁定資料來源的話,這些Items都內在地被設定為readonly,這時如果我們想刪除,或者添加資料時,除非這些item集合實現了INotifyCollectionChanged介面,這時我們才可以動態地進行修改。
所以解決方案很簡單,只要讓item集合實現INotifyCollectionChanged介面,並實現它的方法。其實還有一種更簡單的方法是直接使用ObservableCollection這個類代替List,因為ObservableCollection已經實現INotifyCollectionChanged介面,關於ObservableCollection 更多的內容點擊這裡查看說明。並且同時將ListBox的Itemsource轉換為ObservableCollection,這樣我們就可以進行修改了。
這裡還要注意的是[清空listbox]的功能,前面使用了[clear]函數,這樣同理也會報錯的,正確的方法應該是把ListBox的Itemsource設定為null即可解決這個問題。
=》
ObservableCollection類值得多加研究,例如[List vs ObservableCollection vs INotifyPropertyChanged in Silverlight]和MSDN Blog上都有資料詳細的說明它的用法。