VisualCollection выбрасывает исключение из диапазона, привязанное к коллекции Observable - PullRequest
8 голосов
/ 08 января 2011

Итак, у меня есть наблюдаемая коллекция, связанная с ItemsControl.

Когда я добавляю элементы в коллекцию, я получаю исключение индекса вне диапазона из коллекции 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, которую я добавляю с помощью метода, который имеет доступ к коллекции, на которой он основан.

Я в полной растерянности из-за того, почему это происходит (и только несколько раз).

редактирование: вот фактическая трассировка стека

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

Ответы [ 2 ]

3 голосов
/ 13 декабря 2014

У меня была такая же проблема и мое понимание этого
(кредиты 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;

0 голосов
/ 25 июля 2012

У меня была похожая проблема, мне потребовались месяцы, чтобы выяснить причину, но нашел ее ^^ Проверьте этот сайт , особенно если вы изменяете список из другой ветки.Кажется, у вас есть состояние гонки, возможно, это то же самое!

...