0
votes

I get a such exception:

'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"

I have a property in viewModel:

private ObservableCollection<TreeViewItem> fooStorage=new ObservableCollection<TreeViewItem>();
public ObservableCollection<TreeViewItem> FooStorage
{
   get { return facetStorage; }
   set { facetStorage = value; }
}

However, after I cleared FooStorage and trying to add new item:

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
    }
}

I've got an above exception.

When I call a method LoadData() at the first time, it all works okay. Then if I call a method LoadData() at the second time, then I get a such exception.

Have anybody met a such exception? The most interesting thing that I cannot reproduce this exception in a test project.

StackTrace:

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.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.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.ObservableCollection1.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.DelegateCommand1.<>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:

Update:

I am adding new TreeViewItem's from FooStorage to different TreeView placed inside of HeaderTemplate of DataGridTextBoxColumn. So when user clicks at Header1 of DataGridTextBoxColumn2, then TreeView of Header1 is populated by FooStorage from viewModel. OK. The when user clicks at Header2 of DataGridTextBoxColumn2, then TreeView of Header2 should be populated by FooStorage from viewModel, however when I Clear() and Add() new items to FooStorage, then I've got an above exception.

1
Post the call stack here as well.MoonKnight
Any event triggered on adding?Patrick Hofman
Please mention all subscribers to any event of the ObservableCollection. Obviously some other code is doing something wrong either on Clear() or Add(). Read How to Ask, provide minimal reproducible example.CodeCaster
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).Sinatr
There are plenty of examples of how to bind TreeView (using HierachialDataTemplate). You simply have to load data in the getter of one of properties. I don't think this question needs answer, better you ask another question regarding your initial problem (and not attempted solution with ListViewItem in ViewModel) in case you can't do it alone for whatever reasons. That would be much more useful to others. P.S.: cba is a bad term.Sinatr

1 Answers

0
votes

Just would like to say that passing UI Element TreeViewItem to ViewModel is a bad practice. So maybe adding new TreeViewItem which is then used in different places was my problem.

As @Sinatr said:

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).

Patrick Hofman gave me advice to disable that section in the UI and after I disabled it, then there was no problems.

So I've concluded that I've met consequences of using bad practice and was punished. Avoid bad practices. And ObservableCollection<T> is not guilty! Sorry, ObservableCollection<T>.

Now I am learning about TreeView by Josh Smith.