Operation not supported on read-only collection 的解决方法 - [Windows Phone开发技巧系列1]
现在起将新开一个系列记录自己在学习与开发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上都有资料详细的说明它的用法。
@:卿之 → http://www.cnblogs.com/wpdev
©:博文是本人当时的学习笔记及知识整理,由于自身局限错误在所难免,敬请斧正.
©:本文版权属于博客园和本人,版权基于署名 2.5 中国大陆许可协议发布,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接和署名卿之(包含链接),不得删节,否则保留追究法律责任的权利。