"Specified argument was out of the range of valid values.Parameter name: index" 向 ObservableCollection 添加新项目时<T>
"Specified argument was out of the range of valid values.Parameter name: index" when adding new item to ObservableCollection<T>
我遇到这样的异常:
'FooStorageStorage.Add(new TreeViewItem() { Header=i.ToString()})'
threw an exception of type 'System.ArgumentOutOfRangeException':
"Specified argument was out of the range of valid values.\r\nParameter
name: index"
我在 viewModel 中有一个 属性:
private ObservableCollection<TreeViewItem> fooStorage=new ObservableCollection<TreeViewItem>();
public ObservableCollection<TreeViewItem> FooStorage
{
get { return facetStorage; }
set { facetStorage = value; }
}
但是,在我清除 FooStorage
并尝试添加新项目后:
private void LoadData()
{
if (FooStorage.Count > 0)
{
FooStorage.Clear();
}
for (int k = 0; k < lengthOfColl; k++)
{
FooStorage.Add(new TreeViewItem() { Header=k.ToString()});//here is exception
}
}
我遇到了上述异常。
当我第一次调用 LoadData() 方法时,一切正常。然后如果我第二次调用 LoadData() 方法,就会得到这样的异常。
有人遇到过这样的异常吗?最有趣的是我在测试项目中无法重现这个异常。
堆栈跟踪:
System.ArgumentOutOfRangeException was unhandled HResult=-2146233086
Message=Specified argument was out of the range of valid values.
Parameter name: index ParamName=index Source=PresentationCore
StackTrace:
at System.Windows.Media.VisualCollection.Insert(Int32 index, Visual visual)
at System.Windows.Controls.UIElementCollection.InsertInternal(Int32
index, UIElement element)
at System.Windows.Controls.Panel.AddChildren(GeneratorPosition pos, Int32 itemCount)
at System.Windows.Controls.Panel.OnItemsChangedInternal(Object sender, ItemsChangedEventArgs args)
at System.Windows.Controls.Panel.OnItemsChanged(Object sender, ItemsChangedEventArgs args)
at System.Windows.Controls.ItemContainerGenerator.OnItemAdded(Object
item, Int32 index)
at System.Windows.Controls.ItemContainerGenerator.OnCollectionChanged(Object
sender, NotifyCollectionChangedEventArgs args)
at System.Windows.WeakEventManager.ListenerList1.DeliverEvent(Object
sender, EventArgs e, Type managerType)
at System.Windows.WeakEventManager.DeliverEvent(Object sender, EventArgs args)
at System.Collections.Specialized.CollectionChangedEventManager.OnCollectionChanged(Object
sender, NotifyCollectionChangedEventArgs args)
at System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(Object
sender, NotifyCollectionChangedEventArgs e)
at System.Windows.Data.CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs
args)
at System.Windows.Controls.ItemCollection.OnViewCollectionChanged(Object
sender, NotifyCollectionChangedEventArgs e)
at System.Windows.WeakEventManager.ListenerList
1.DeliverEvent(Object
sender, EventArgs e, Type managerType)
at System.Windows.WeakEventManager.DeliverEvent(Object sender, EventArgs args)
at System.Collections.Specialized.CollectionChangedEventManager.OnCollectionChanged(Object
sender, NotifyCollectionChangedEventArgs args)
at System.Windows.Data.CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs
args)
at System.Windows.Data.ListCollectionView.ProcessCollectionChangedWithAdjustedIndex(NotifyCollectionChangedEventArgs
args, Int32 adjustedOldIndex, Int32 adjustedNewIndex)
at System.Windows.Data.ListCollectionView.ProcessCollectionChanged(NotifyCollectionChangedEventArgs
args)
at System.Windows.Data.CollectionView.OnCollectionChanged(Object sender,
NotifyCollectionChangedEventArgs args)
at System.Collections.ObjectModel.ObservableCollection1.OnCollectionChanged(NotifyCollectionChangedEventArgs
e)
at System.Collections.ObjectModel.ObservableCollection
1.InsertItem(Int32
index, T item)
at System.Collections.ObjectModel.Collection1.Add(T item)
at ModuleA.ViewModel.PersonControlViewModel.LoadData(IPerson person) in D:\WPF\...\ViewModel\PersonControlViewModel.cs:line 110
at Prism.Commands.DelegateCommand
1.<>c__DisplayClass1_0.<.ctor>b__0(Object
o)
at Prism.Commands.DelegateCommandBase.<>c__DisplayClass5_0.<.ctor>b__0(Object
arg)
at Prism.Commands.DelegateCommandBase.d__14.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task)
at Prism.Commands.DelegateCommandBase.d__12.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<>c.b__6_0(Object
state)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate
callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source,
Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.DispatcherOperation.InvokeImpl()
at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object
state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext
executionContext, ContextCallback callback, Object state, Boolean
preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean
preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext
executionContext, ContextCallback callback, Object state)
at System.Windows.Threading.DispatcherOperation.Invoke()
at System.Windows.Threading.Dispatcher.ProcessQueue()
at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate
callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source,
Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority
priority, TimeSpan timeout, Delegate method, Object args, Int32
numArgs)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame
frame)
at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
at System.Windows.Application.RunDispatcher(Object ignore)
at System.Windows.Application.RunInternal(Window window)
at System.Windows.Application.Run(Window window)
at System.Windows.Application.Run()
at PrototypeBootstrapper.App.Main() in D:\WPF...\Src\PrototypeBootstrapper\obj\Debug\App.g.cs:line 0
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext
executionContext, ContextCallback callback, Object state, Boolean
preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean
preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart() InnerException:
更新:
我正在将 FooStorage
中的新 TreeViewItem's
添加到位于 DataGridTextBoxColumn
的 HeaderTemplate 内的不同 TreeView
。因此,当用户单击 DataGridTextBoxColumn2
的 Header1
时,Header1
的 TreeView
将由来自 viewModel 的 FooStorage
填充。好的。当用户单击 DataGridTextBoxColumn2
的 Header2
时,Header2
的 TreeView
应该由 viewModel 中的 FooStorage
填充,但是当我 Clear()
和Add()
新项目到 FooStorage
,然后我遇到了上述异常。
只是想说将 UI 元素 TreeViewItem
传递给 ViewModel
是一种不好的做法。所以也许添加新的 TreeViewItem
然后在不同的地方使用是我的问题。
正如@Sinatr 所说:
You should not use TreeViewItem directly in ViewModel. Moreover
framework elements (including TreeViewItem) can have only one parent
at a time. Maybe adding new TreeViewItem which is then used in
different places is your problem (cba to check sources if it's the
case, simply don't do it). Rather use TreeViewItemViewModel (call it
shorter, e.g. ItemViewModel).
帕特里克霍夫曼建议我禁用 UI 中的那个部分,在我禁用它之后,就没有问题了。
所以我得出结论,我遇到了使用不良做法的后果并受到了惩罚。 避免不良做法。而ObservableCollection<T>
无罪!抱歉,ObservableCollection<T>
.
我遇到这样的异常:
'FooStorageStorage.Add(new TreeViewItem() { Header=i.ToString()})' threw an exception of type 'System.ArgumentOutOfRangeException': "Specified argument was out of the range of valid values.\r\nParameter name: index"
我在 viewModel 中有一个 属性:
private ObservableCollection<TreeViewItem> fooStorage=new ObservableCollection<TreeViewItem>();
public ObservableCollection<TreeViewItem> FooStorage
{
get { return facetStorage; }
set { facetStorage = value; }
}
但是,在我清除 FooStorage
并尝试添加新项目后:
private void LoadData()
{
if (FooStorage.Count > 0)
{
FooStorage.Clear();
}
for (int k = 0; k < lengthOfColl; k++)
{
FooStorage.Add(new TreeViewItem() { Header=k.ToString()});//here is exception
}
}
我遇到了上述异常。
当我第一次调用 LoadData() 方法时,一切正常。然后如果我第二次调用 LoadData() 方法,就会得到这样的异常。
有人遇到过这样的异常吗?最有趣的是我在测试项目中无法重现这个异常。
堆栈跟踪:
System.ArgumentOutOfRangeException was unhandled HResult=-2146233086 Message=Specified argument was out of the range of valid values. Parameter name: index ParamName=index Source=PresentationCore
StackTrace: at System.Windows.Media.VisualCollection.Insert(Int32 index, Visual visual) at System.Windows.Controls.UIElementCollection.InsertInternal(Int32 index, UIElement element) at System.Windows.Controls.Panel.AddChildren(GeneratorPosition pos, Int32 itemCount) at System.Windows.Controls.Panel.OnItemsChangedInternal(Object sender, ItemsChangedEventArgs args) at System.Windows.Controls.Panel.OnItemsChanged(Object sender, ItemsChangedEventArgs args) at System.Windows.Controls.ItemContainerGenerator.OnItemAdded(Object item, Int32 index) at System.Windows.Controls.ItemContainerGenerator.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args) at System.Windows.WeakEventManager.ListenerList1.DeliverEvent(Object sender, EventArgs e, Type managerType) at System.Windows.WeakEventManager.DeliverEvent(Object sender, EventArgs args) at System.Collections.Specialized.CollectionChangedEventManager.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args) at System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(Object sender, NotifyCollectionChangedEventArgs e) at System.Windows.Data.CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args) at System.Windows.Controls.ItemCollection.OnViewCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e) at System.Windows.WeakEventManager.ListenerList
1.DeliverEvent(Object sender, EventArgs e, Type managerType) at System.Windows.WeakEventManager.DeliverEvent(Object sender, EventArgs args) at System.Collections.Specialized.CollectionChangedEventManager.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args) at System.Windows.Data.CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args) at System.Windows.Data.ListCollectionView.ProcessCollectionChangedWithAdjustedIndex(NotifyCollectionChangedEventArgs args, Int32 adjustedOldIndex, Int32 adjustedNewIndex) at System.Windows.Data.ListCollectionView.ProcessCollectionChanged(NotifyCollectionChangedEventArgs args) at System.Windows.Data.CollectionView.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args) at System.Collections.ObjectModel.ObservableCollection1.OnCollectionChanged(NotifyCollectionChangedEventArgs e) at System.Collections.ObjectModel.ObservableCollection
1.InsertItem(Int32 index, T item) at System.Collections.ObjectModel.Collection1.Add(T item) at ModuleA.ViewModel.PersonControlViewModel.LoadData(IPerson person) in D:\WPF\...\ViewModel\PersonControlViewModel.cs:line 110 at Prism.Commands.DelegateCommand
1.<>c__DisplayClass1_0.<.ctor>b__0(Object o) at Prism.Commands.DelegateCommandBase.<>c__DisplayClass5_0.<.ctor>b__0(Object arg) at Prism.Commands.DelegateCommandBase.d__14.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Prism.Commands.DelegateCommandBase.d__12.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<>c.b__6_0(Object state) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler) at System.Windows.Threading.DispatcherOperation.InvokeImpl() at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state) at System.Windows.Threading.DispatcherOperation.Invoke() at System.Windows.Threading.Dispatcher.ProcessQueue() at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler) at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs) at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam) at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg) at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame) at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame) at System.Windows.Application.RunDispatcher(Object ignore) at System.Windows.Application.RunInternal(Window window) at System.Windows.Application.Run(Window window) at System.Windows.Application.Run() at PrototypeBootstrapper.App.Main() in D:\WPF...\Src\PrototypeBootstrapper\obj\Debug\App.g.cs:line 0 at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() InnerException:
更新:
我正在将 FooStorage
中的新 TreeViewItem's
添加到位于 DataGridTextBoxColumn
的 HeaderTemplate 内的不同 TreeView
。因此,当用户单击 DataGridTextBoxColumn2
的 Header1
时,Header1
的 TreeView
将由来自 viewModel 的 FooStorage
填充。好的。当用户单击 DataGridTextBoxColumn2
的 Header2
时,Header2
的 TreeView
应该由 viewModel 中的 FooStorage
填充,但是当我 Clear()
和Add()
新项目到 FooStorage
,然后我遇到了上述异常。
只是想说将 UI 元素 TreeViewItem
传递给 ViewModel
是一种不好的做法。所以也许添加新的 TreeViewItem
然后在不同的地方使用是我的问题。
正如@Sinatr 所说:
You should not use TreeViewItem directly in ViewModel. Moreover framework elements (including TreeViewItem) can have only one parent at a time. Maybe adding new TreeViewItem which is then used in different places is your problem (cba to check sources if it's the case, simply don't do it). Rather use TreeViewItemViewModel (call it shorter, e.g. ItemViewModel).
帕特里克霍夫曼建议我禁用 UI 中的那个部分,在我禁用它之后,就没有问题了。
所以我得出结论,我遇到了使用不良做法的后果并受到了惩罚。 避免不良做法。而ObservableCollection<T>
无罪!抱歉,ObservableCollection<T>
.