【发布时间】:2011-01-08 00:24:53
【问题描述】:
我遇到了异常,但我不明白为什么:
public static void AddAll<T>(this ICollection<T> dest, ICollection<T> source)
{
if (dest == null)
{
throw new ArgumentNullException("dest");
}
foreach (T t in source)
{
// Argument out of range exception
// Message: "\r\nParameter name: index"
dest.Add(t);
}
}
例外是:
$exception {"\r\nParameter name: index"} System.Exception {System.ArgumentOutOfRangeException}
堆栈跟踪:
at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource)
at System.ThrowHelper.ThrowArgumentOutOfRangeException()
at System.Collections.Generic.List`1.get_Item(Int32 index)
at System.Collections.Generic.List`1.System.Collections.IList.get_Item(Int32 index)
at System.Windows.Controls.ItemCollection.GetItemImpl(Int32 index)
at System.Windows.Controls.ItemCollection.GetItemImplSkipMethodPack(Int32 index)
at System.Windows.PresentationFrameworkCollection`1.get_Item(Int32 index)
at Microsoft.Phone.Controls.Primitives.PivotHeadersControl.FadeInItemIfNeeded(Int32 index, Int32 visualFirstIndex, Int32 previousVisualFirstIndex, Int32 itemCount)
at Microsoft.Phone.Controls.Primitives.PivotHeadersControl.UpdateItemsLayout()
at Microsoft.Phone.Controls.Primitives.PivotHeadersControl.OnItemsChanged(NotifyCollectionChangedEventArgs e)
at System.Windows.Controls.ItemsControl.OnItemCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
at System.Windows.Controls.ItemCollection.NotifyCollectionChanged(NotifyCollectionChangedEventArgs e)
at System.Windows.Controls.ItemCollection.UpdateItemsSourceList(IEnumerable newItemsSource)
at System.Windows.Controls.ItemsControl.ItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.RaisePropertyChangeNotifications(DependencyProperty dp, Object newValue, Object oldValue)
at System.Windows.DependencyObject.SetValueInternal(DependencyProperty dp, Object value, Boolean allowReadOnlySet, Boolean isSetByStyle, Boolean isSetByBuiltInStyle, PropertyInvalidationReason reason)
at System.Windows.DependencyObject.SetValueInternal(DependencyProperty dp, Object value)
at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
at System.Windows.Controls.ItemsControl.set_ItemsSource(IEnumerable value)
at Microsoft.Phone.Controls.Pivot.UpdateHeaders()
at Microsoft.Phone.Controls.Pivot.OnItemsChanged(NotifyCollectionChangedEventArgs e)
at System.Windows.Controls.ItemsControl.OnItemCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
at System.Windows.Controls.ItemCollection.NotifyCollectionChanged(NotifyCollectionChangedEventArgs e)
at System.Windows.Controls.ItemCollection.System.Windows.Controls.ICollectionChangedListener.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
at System.Windows.Controls.WeakCollectionChangedListener.SourceCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
at System.Collections.ObjectModel.ObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
at System.Collections.ObjectModel.ObservableCollection`1.InsertItem(Int32 index, SectionViewModel item)
at System.Collections.ObjectModel.Collection`1.Add(SectionViewModel item)
at MyApp.ExtensionMethods.AddAll[T](ICollection`1 dest, ICollection`1 source)
at MyApp.Sections.get_SectionViewModels()
at System.Reflection.RuntimeMethodInfo.InternalInvoke(RuntimeMethodInfo rtmi, Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark)
at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark)
at System.Reflection.RuntimePropertyInfo.InternalGetValue(PropertyInfo thisProperty, Object obj, Object[] index, StackCrawlMark& stackMark)
at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index)
at System.Windows.CLRPropertyListener.get_Value()
at System.Windows.PropertyAccessPathStep.get_Value()
at System.Windows.PropertyPathListener.RaisePropertyPathStepChanged(PropertyPathStep source)
at System.Windows.PropertyAccessPathStep.RaisePropertyPathStepChanged(PropertyListener source)
at System.Windows.CLRPropertyListener.SourcePropertyChanged(Object sender, PropertyChangedEventArgs args)
at System.Windows.Data.WeakPropertyChangedListener.PropertyChangedCallback(Object sender, PropertyChangedEventArgs args)
at MyApp.Sections.onPropChanged(String name)
at MyApp.Sections.Sections_Loaded(Object sender, RoutedEventArgs e)
at System.Windows.CoreInvokeHandler.InvokeEventHandler(Int32 typeIndex, Delegate handlerDelegate, Object sender, Object args)
at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, String eventName)
dest 是一个 ObservableCollection,当前包含 t。
source 是一个列表,包含 7 个成员。
t 是source 的第一个成员。
为什么会发生这种情况?
更新:dest 是Pivot 的ItemsSource。 Pivot 正在监听 dest.CollectionChanged,我认为这是导致问题的原因。
<controls:Pivot Title="SECTIONS" x:Name="pivotControl" ItemsSource="{Binding SectionViewModels}"> <!-- ... --> <controls:Pivot />
这是枢轴控件绑定到的属性:
private ObservableCollection<SectionViewModel> _sectionViewModels;
public ObservableCollection<SectionViewModel> SectionViewModels
{
get
{
// don't do anything if we haven't loaded yet
if (NavigationContext == null)
{
return null;
}
if (_sectionViewModels == null)
{
_sectionViewModels = new ObservableCollection<SectionViewModel>();
_sectionViewModels.AddAll(SunData.GetSections().Select(section => new SectionViewModel(section)).ToList());
foreach (SectionViewModel sectionViewModel in _sectionViewModels)
{
SunData.GetStories(sectionViewModel.Section, () =>
{
onPropChanged("LoadingBarVisibility");
});
}
}
// re-index the source so we don't get an annoying transition animation
// http://stackoverflow.com/questions/4541020/
int activeVID = int.Parse(NavigationContext.QueryString[Section.SectionsKey]);
SectionViewModel selectedItem = _sectionViewModels.Where(sectionVM => sectionVM.Section.Vid == activeVID).Single();
int selectedIndex = _sectionViewModels.IndexOf(selectedItem);
// one way to reindex
for (int i = 0; i < selectedIndex; i++)
{
SectionViewModel sectionVM = _sectionViewModels[0];
_sectionViewModels.Remove(sectionVM);
_sectionViewModels.Add(sectionVM);
}
// another way to reindex
/*
IList<SectionViewModel> reindexedSectionVMs = new List<SectionViewModel>();
for (int i = 0; reindexedSectionVMs.Count != _sectionViewModels.Count; i++)
{
reindexedSectionVMs.Add(_sectionViewModels[(selectedIndex + i) % _sectionViewModels.Count]);
}
_sectionViewModels.Clear();
_sectionViewModels.AddAll(reindexedSectionVMs);
*/
return _sectionViewModels;
}
}
上面代码中的关键部分是重新索引源部分。如果我将其注释掉,我不会遇到此问题,也不会遇到许多其他错误(例如 PivotItem 的内容为空,或者选择了错误的 PivotItem。)
我尝试了两种重新索引列表的方法,但它们都导致相同的错误。
我不确定我在这里做什么会导致这些问题。
【问题讨论】:
标签: .net silverlight exception collections windows-phone-7