我有一个奇怪的问题,我不明白。这是在Silverlight / WP7中。
我正在用项目填充ObservableCollection,后来我想更新每个项目。
我已成功删除代码以重现错误。我的XAML只是一个ListBox和一个Button。
private ObservableCollection<int> Words = new ObservableCollection<int>();
public MainPage()
{
InitializeComponent();
listBox1.ItemsSource = Words;
}
private void button1_Click(object sender, RoutedEventArgs e)
{
List<int> numbers = new List<int>()
{
1,2,3
};
foreach (var number in numbers)
{
var index = Words.IndexOf(number);
if (index > -1)
Words[index] = number;
else
Words.Add(number);
}
}
第一次运行代码时,它使用数字1,2和3填充ObservableCollection,它们显示在ListBox中。
第二次运行时,所有代码都被执行,但随后会抛出一条带有“参数不正确”消息的未处理异常。
奇怪的是,如果我在构造函数中删除了我的行,那是我设置ItemsSource的行,则不会抛出错误。可观察的集合会按原样更新。
另外,如果我注释掉“Words [index] = number”行,它也可以。所以出于某种原因,当我的ObservableCollection被设置为ListBox的数据源时,我无法替换该项。
有人可以解释原因吗? (或建议解决方法?)
我的解决方案; 我从
改变了我的代码隐藏if (index > -1)
Words[index] = number;
到
if (index > -1)
{
Words.RemoveAt(index);
Words.Add(number);
}
这使问题消失了。
答案 0 :(得分:3)
如果启用CLR Exceptons在抛出时中断(在Debug | Exceptions下),您将看到此堆栈跟踪:
mscorlib.dll!System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument argument, System.ExceptionResource resource) + 0x10 bytes
mscorlib.dll!System.ThrowHelper.ThrowArgumentOutOfRangeException() + 0x9 bytes
mscorlib.dll!System.Collections.Generic.List<object>.this[int].get(int index) + 0xe bytes
mscorlib.dll!System.Collections.ObjectModel.Collection<object>.System.Collections.IList.get_Item(int index) + 0x7 bytes
System.Windows.dll!System.Windows.Controls.ItemCollection.GetItemImpl(int index) + 0x17 bytes
System.Windows.dll!System.Windows.Controls.ItemCollection.GetItemImplSkipMethodPack(int index) + 0x2 bytes
System.Windows.dll!System.Windows.PresentationFrameworkCollection<object>.this[int].get(int index) + 0x2 bytes
System.Windows.dll!System.Windows.Controls.VirtualizingStackPanel.CleanupContainers(System.Windows.Controls.ItemsControl itemsControl) + 0xa3 bytes
System.Windows.dll!System.Windows.Controls.VirtualizingStackPanel.MeasureOverride(System.Windows.Size constraint) + 0x56a bytes
System.Windows.dll!System.Windows.FrameworkElement.MeasureOverride(System.IntPtr nativeTarget, float inWidth, float inHeight, out float outWidth, out float outHeight) + 0x45 bytes
[External Code]
由于某种原因,虚拟化堆栈面板正在尝试清理索引为-1的元素(您可以在堆栈框架中看到该值的索引)。
ObservableCollection的内容类型没有区别。你得到了与字符串相同的错误...它只发生在两个元素上。
对我而言,它看起来像VirtualizingStackPanel中的bug。您可以通过在ListBox上将VirtualizationMode设置为Standard而不是Recycling来解决它(如果您不需要虚拟化功能):
<ListBox VirtualizingStackPanel.VirtualizationMode="Standard"
...
</ListBox>
答案 1 :(得分:2)
作为替代方案,为什么不使用数据绑定,而不是从代码后面设置itemSource?