现在的位置: 首页 > 综合 > 正文

Operation not supported on read-only collection 的解决方法 – [Windows Phone开发技巧系列1]

2012年08月15日 ⁄ 综合 ⁄ 共 2033字 ⁄ 字号 评论关闭

现在起将新开一个系列记录自己在学习与开发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上都有资料详细的说明它的用法。

 

抱歉!评论已关闭.