2011-01-08 78 views
7

所以我有一个可观察集合绑定到ItemsControl。VisualCollection抛出范围异常,绑定到Observable集合

当我将项目添加到集合中时,我从Visual集合中得到一个索引超出范围的异常。

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

内部的ChildWindows是我添加项目的集合。一个需要注意的是ChildWindows是一个ReadOnlyObservableCollection,我通过一个可以访问它所基于的Collection的方法添加。

我完全丧失了为什么会发生这种情况(只有一些时候)。

编辑: 这里是实际的堆栈跟踪

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 
+0

集合中有多少项目? – 2011-01-08 02:07:33

+0

得到了同样的事情发生在我身上。如果我找到解决方案,我会尽力在此发布。 – SergioL 2011-08-05 16:27:06

回答

-1

我有一个类似的问题,我花了几个月来找出病因,但发现它^^ 检查this site,特别是如果你修改列表来自另一个线程。你似乎有一个竞争条件,可能是同一个!

2

我有同样的问题,我也
的理解(学分https://stackoverflow.com/users/249723/vivien-ruiz的链接)
很简单,就是你是“绑定”如果修改一个ObservableCollection这需要参与的的ItemSource绑定有问题。我发现插入索引0“解决”我的问题,但它仍然可能崩溃。
它不应该被修改,因为它不是线程安全的类。
更好的解决方案是在操作完成后,对列表的副本进行操作并将副本分配给有界的集合。
例如: ObservableCollection<ListViewItem> newList = new ObservableCollection<ListViewItem>(mCurrentList); ... ListViewItem item = new ListViewItem(); item.Content = image; newList.Add(item); ... mPictures = newList;