.NET:在集合上调用 .Add 时出现 ArgumentOutOfRangeException(Pivot 控件出现问题)
我收到异常,但我不明白为什么:
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}
Stacktrace:
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
.)
我尝试了两种重新索引列表的方法,但它们都会导致相同的错误。
我不确定我在这里所做的事情导致了这些问题。
I'm getting an exception, but I don't understand why:
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);
}
}
The exception is:
$exception {"\r\nParameter name: index"} System.Exception {System.ArgumentOutOfRangeException}
Stacktrace:
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
is an ObservableCollection, that currently contains t
.
source
is a List, that contains 7 members.
t
is the first member of source
.
Why could this be happening?
Update: dest
is the ItemsSource
for a Pivot
. That Pivot
is listening for dest.CollectionChanged
, which I believe is causing the problem.
<controls:Pivot Title="SECTIONS" x:Name="pivotControl" ItemsSource="{Binding SectionViewModels}"> <!-- ... --> <controls:Pivot />
Here is the property that the pivot control is binding to:
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;
}
}
The key part in the code above is the re-indexing the source part. If I comment that out, I don't get this issue, nor a host of other bugs (like the content for a PivotItem
being empty, or the wrong PivotItem
being selected.)
I've tried two methods of reindexing the list, but they both lead to the same bugs.
I'm not sure what I'm doing here that's causing these issues.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我在问题中找到了解决方案:
导航时参数无效异常
i found the solution to this in my problem:
Argument invalid exception while navigating
啊哈,我明白了。这对于您的 2 个集合或您上面显示的代码都不是问题。问题是您通过更改事件观察这些集合,并且那里的事件处理代码有问题。
希望这些信息足以帮助您发现问题。如果没有,那么如果您发布事件处理代码,我们也许可以提供进一步的帮助。
Aha, I see it. This is not a problem with either of your 2 collections or the code you've shown above. The problem is you have something Observing these collections via change events, and there is something wrong with the event handling code there.
Hopefully, that is enough info you help you spot the problem. If not, then if you post the event handling code, we might be able to help further.