VisualCollection throwing out of range exception, bound to Observable collection
So I've got an observable collection bound into an ItemsControl.
When I add items to the collection I get an exception of index out of range from the Visual collection.
<ItemsControl x:Name="ReportPages" ItemsSource="{Binding History}" DockPanel.Dock="Top">
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<ItemsPresenter HorizontalAlignment="Center"/>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding ChildWindows}">
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<Grid Margin="0,10,0,10" >
<ItemsPresenter />
<Border x:Name="ResizeFrame" BorderThickness="4" BorderBrush="LightBlue" Visibility="{Binding Active, Converter={StaticResource BooleanToVisibilityConverter}}"/>
</Grid>
</ControlTemplate>
</ItemsControl.Template>
开发者_StackOverflow社区 <ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas x:Name="LayoutCanvas" Background="white" ClipToBounds="true"
MouseDown="History_MouseLeftButtonDown" PreviewMouseDown="ClosePanels"
Width="{Binding PageSizeProp.PageWidth}" Height="{Binding PageSizeProp.PageHeight}"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
The inner ChildWindows is the collection I'm adding items to. One think of note is that ChildWindows is a ReadOnlyObservableCollection, I'm adding via a method that has access to the Collection it is based on.
I'm at a total loss for why this is happening (and only some times).
edit: here is the actual stack trace
at System.Windows.Media.VisualCollection.Insert(Int32 index, Visual visual)
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.Controls.ItemContainerGenerator.System.Windows.IWeakEventListener.ReceiveWeakEvent(Type managerType, Object sender, EventArgs e)
at System.Windows.WeakEventManager.DeliverEventToList(Object sender, EventArgs args, ListenerList list)
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.System.Windows.IWeakEventListener.ReceiveWeakEvent(Type managerType, Object sender, EventArgs e)
at System.Windows.WeakEventManager.DeliverEventToList(Object sender, EventArgs args, ListenerList list)
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.ReadOnlyObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs args)
at System.Collections.ObjectModel.ReadOnlyObservableCollection`1.HandleCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
at System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(Object sender, NotifyCollectionChangedEventArgs e)
at System.Collections.ObjectModel.ObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
at System.Collections.ObjectModel.ObservableCollection`1.InsertItem(Int32 index, T item)
at System.Collections.ObjectModel.Collection`1.Add(T item)
at CalManv4UI.DataHistoryReportPageBase.AddNewChart(ChildWindowSaved cws, Boolean activate) in C:\Users\Joel Barsotti\Documents\Visual Studio 2010\Projects\CalMAN V4\CalMANv4-WPF\CalManv4UI\Workflow\DataHistoryReportPageBase.cs:line 72
I had the same problem and my understanding of it
(credits to https://stackoverflow.com/users/249723/vivien-ruiz for the link)
is simply that you are "bound" to have problems if you modify an ObservableCollection which takes part in an ItemSource binding. I found that inserting at index 0 "solves" my problem, but it could still crash.
It shouldn't be modified because it isn't a thread-safe class.
A better solution is to act on a copy of the list and assign the copy to the bounded collecion once the operation is completed.
For example:
ObservableCollection<ListViewItem> newList = new ObservableCollection<ListViewItem>(mCurrentList);
...
ListViewItem item = new ListViewItem();
item.Content = image;
newList.Add(item);
...
mPictures = newList;
I had a similar problem, took me months to find out the cause, but found it ^^ Check this site, especially if you modify the list from another thread. You seem to have a race condition, may be this is the same one !
精彩评论