I have a DataGrid with ItemsSource bound to an ObservableCollection. I modify properties on objects in the ObservableCollection on another thread but I use Dispatcher.BeginInvoke to make those changes. Everything works beautifully until the user resizes the Window (which causes the DataGrid to resize). At that time I get an unhandled exception...
{"An ItemsControl is inconsistent with its items source.\n See the inner exception for more information."}
{"Information for developers (use Text Visualizer to read this):\r\nThis exception was thrown because the generator for control 'System.Windows.Controls.DataGrid Items.Count:20' with name '(unnamed)' has received sequence of CollectionChanged events that do not agree with the current state of the Items collection. The following differences were detected:\r\n Accumulated count 15 is different from actual count 20. [Accumulated count is (Count at last Reset + #Adds - #Removes since last Reset).]\r\n\r\nOne or more of the following sources may have raised the wrong events:\r\n System.Windows.Controls.ItemContainerGenerator\r\n System.Windows.Controls.ItemCollection\r\n System.Windows.Data.ListCollectionView\r\n System.Collections.ObjectModel.ObservableCollection`1[[NetworkManagement.Log, NetworkManagement, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]\r\n(The starred sources are considered more likely to be the cause of the problem.)\r\n\r\nThe most common causes are (a) changing the collection or its Count without raising a corresponding event, and (b) raising an event with an incorrect index or item parameter.\r\n\r\nThe exception's stack trace describes how the inconsistencies were detected, not how they occurred. To get a more timely exception, set the attached property 'PresentationTraceSources.TraceLevel' on the generator to value 'High' and rerun the scenario. One way to do this is to run a command similar to the following:\n System.Diagnostics.PresentationTraceSources.SetTraceLevel(myItemsControl.ItemContainerGenerator, System.Diagnostics.PresentationTraceLevel.High)\r\nfrom the Immediate window. This causes the detection logic to run after every CollectionChanged event, so it will slow down the application.\r\n"}
Here is the XAML for the DataGrid, I only included the column definition for the property that is changing on another Thread. As you can see there is a converter, this converter changes selects an image based on the enum value. This error does not occur uness this property gets changed so I'm sure this is the source of the issue.
<DataGrid Grid.Row="0" Name="dgvDevices" ItemsSource="{Binding Path=MainModel.Devices}" SelectedItem="{Binding Path=MainModel.SelectedDevice}" CanUserAddRows="False" CanUserDeleteRows="False" AutoGenerateColumns="False" SelectionChanged="dgvDevices_SelectionChanged_1" CellEditEnding="dgvDevices_CellEditEnding_1" SelectionMode="Extended"><DataGrid.Columns><DataGridTemplateColumn><DataGridTemplateColumn.CellTemplate><DataTemplate><Image Source="{Binding Path=MonitoringStatus, Converter={StaticResource msi}}" ToolTip="{Binding Path=MonitoringStatus}"/></DataTemplate></DataGridTemplateColumn.CellTemplate></DataGrid.Columns></DataGrid>
Here is how I am changing the Value of the property that belongs to objects in the ObservableCollection
Application.Current.Dispatcher.BeginInvoke(new Action(() => device.MonitoringStatus = NetworkManagement.Model.MonitorStatus.UP));