title: DataGrid: An ItemsControl is inconsistent with its items source
body: <p>When I make a call to FillGPLocationAndPrint in the DataGridViewModel class, I get this exception.  Below is the inner exception.  What happens is a hard coded Dictionary is passed into FillGPLocationAndPrint where it takes the data from there and puts it into the GridData ObservableCollection which is bound to the ItemsSource property of the DataGrid.  This raises an event called CollectionChanged, which calls the method GridDataChanged which is responsible for increasing the DataGrid height property and the MainWindow height property.  Basically, as rows are added and subtracted, the grid and window height change dynamically.</p>
  
  <p><strong>Edit:</strong></p>
  
  <p>After looking a little further into this issue, the problem is actually caused by the </p>
  
  <pre><code>mainVm.WindowHeight += ROW_HEIGHT;
  </code></pre>
  
  <p>and</p>
  
  <pre><code>mainVm.WindowHeight -= ROW_HEIGHT;
  </code></pre>
  
  <p><strong>statements.  For some reason, it does not like changing the height of the window.  mainVm is an object that represents the ViewModel of the main window and WindowHeight is a double that is bound to the Height property in the main window.</strong></p>
  
  <p>Here is InnerException:</p>
  
  <p>Information for developers (use Text Visualizer to read this):
  This exception was thrown because the generator for control 'System.Windows.Controls.DataGrid Items.Count:3' with name 'grdData' has received sequence of CollectionChanged events that do not agree with the current state of the Items collection.  The following differences were detected:
    Accumulated count 2 is different from actual count 3.  [Accumulated count is (Count at last Reset + #Adds - #Removes since last Reset).]
    At index 1:  Generator's item '{NewItemPlaceholder}' is different from actual item 'MechQualTestDataEntry.MechTestData'.</p>
  
  <p>One or more of the following sources may have raised the wrong events:
       System.Windows.Controls.ItemContainerGenerator
        System.Windows.Controls.ItemCollection
         System.Windows.Data.ListCollectionView
          System.Collections.ObjectModel.ObservableCollection`1[[MechQualTestDataEntry.MechTestData, MechQualTestDataEntry, Version=2.0.5.25, Culture=neutral, PublicKeyToken=null]]
  (The starred sources are considered more likely to be the cause of the problem.)</p>
  
  <p>The 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.</p>
  
  <p>The 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:
     System.Diagnostics.PresentationTraceSources.SetTraceLevel(myItemsControl.ItemContainerGenerator, System.Diagnostics.PresentationTraceLevel.High)
  from the Immediate window.  This causes the detection logic to run after every CollectionChanged event, so it will slow down the application.</p>
  
  <p>Here is the DataGridViewModel class (shrunk down):</p>
  
  <pre><code>    private const int GRID_HEIGHT_MAX = 390;
      private const int GRID_HEIGHT_MIN = 60;
      private const int ROW_HEIGHT = 22;
      private int prevRowCount;
      private double gridHeight;
      private MainWindowViewModel mainVm;
      private ObservableCollection&lt;MechTestData&gt; gridData;
      public DataGridViewModel(MainWindowViewModel mainVm)
      {
          this.mainVm = mainVm;
          GridHeight = GRID_HEIGHT_MIN;
          gridData = new ObservableCollection&lt;MechTestData&gt;();
          gridData.CollectionChanged += GridDataChanged;
      }
      public double GridHeight
      {
          get
          {
              return gridHeight;
          }
          set
          {
              gridHeight = value;
              OnPropertyChanged("GridHeight");
          }
      }
      public ObservableCollection&lt;MechTestData&gt; GridData
      {
          get
          {
              return gridData;
          }
          set
          {
              gridData = value;
              OnPropertyChanged("GridData");
          }
      }
      private void GridDataChanged(object sender, NotifyCollectionChangedEventArgs e)
      {
          // If the grid height is less than or equal to
          // the maximum grid height
          if (gridHeight &lt;= GRID_HEIGHT_MAX + 1)
          {
              // If we added rows, increase the grid height
              if (gridData.Count &gt; prevRowCount)
              {
                  GridHeight += ROW_HEIGHT;
                  mainVm.WindowHeight += ROW_HEIGHT;
              }
          }
  
          // if the grid height is less than or equal to
          // the minimum grid height
          if (gridHeight &gt; GRID_HEIGHT_MIN)
          {
              // If we deleted rows, decrease the grid height
              if (gridData.Count &lt; prevRowCount)
              {
                  GridHeight -= ROW_HEIGHT;
                  mainVm.WindowHeight -= ROW_HEIGHT;
              }
          }
  
          // Cache the row count
          prevRowCount = gridData.Count;
      }
      public void FillGPLocationAndPrint(Dictionary&lt;string, string&gt; gpLocationToDiePrintMap)
      {
          foreach (KeyValuePair&lt;string, string&gt; map in gpLocationToDiePrintMap)
          {
              GridData.Add(new MechTestData(map.Key, map.Value));
          }
      }
  </code></pre>
  
  <p>ViewModelBase class:</p>
  
  <pre><code>public abstract class ViewModelBase : INotifyPropertyChanged
  {
      public event PropertyChangedEventHandler PropertyChanged;
      protected void OnPropertyChanged(string propertyName)
      {
          PropertyChangedEventHandler handler = PropertyChanged;
          if (handler != null)
          {
              handler(this, new PropertyChangedEventArgs(propertyName));
          }
      }
  }
  </code></pre>
  
  <p>XAML (minus all the other components):</p>
  
  <pre><code>&lt;Window 
  x:Class="MechQualTestDataEntry.MainWindow"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:p="clr-namespace:MechQualTestDataEntry.Properties"
  xmlns:wpftk="http://schemas.microsoft.com/wpf/2008/toolkit"
  xmlns:local="clr-namespace:MechQualTestDataEntry"
  Icon="/MechQualTestDataEntry;component/Resources/MechQualIcon.ico"
  Title="MainWindow" 
  Background="MidnightBlue"
  ResizeMode="CanMinimize"
  Height="{Binding WindowHeight}"
  MinHeight="{Binding WindowHeight}"
  MaxHeight="{Binding WindowHeight}"
  MinWidth="700"
  MaxWidth="1000"
  Width="820"&gt;
  &lt;Window.Resources&gt;
      &lt;local:DateTimeConverter x:Key="DateTimeFormatter"/&gt;
  &lt;/Window.Resources&gt;
  
      &lt;!-- Data Grid --&gt;
      &lt;DataGrid
          DockPanel.Dock="Bottom"
          x:Name="grdData"
          CellStyle="{StaticResource cellStyle}"
          FontFamily="Verdana"
          Height="{Binding GridHeight}"
          Foreground="MidnightBlue"
          AutoGenerateColumns="False"
          RowHeight="22"
          CanUserAddRows="True"
          CanUserDeleteRows="True"
          CanUserReorderColumns="False"
          CanUserResizeColumns="False"
          CanUserResizeRows="False"
          CanUserSortColumns="True"
          ItemsSource="{Binding GridData}"
          SelectionUnit="CellOrRowHeader"
          SelectionMode="Extended"&gt;
          &lt;DataGrid.Resources&gt;
              &lt;Style TargetType="{x:Type DataGridCell}"&gt;
                  &lt;EventSetter 
                      Event="PreviewMouseLeftButtonDown" 
                      Handler="DataGridCell_PreviewMouseLeftButtonDown"/&gt;
              &lt;/Style&gt;
              &lt;Style TargetType="{x:Type DataGridRowHeader}"&gt;
                  &lt;Style.Triggers&gt;
                      &lt;Trigger Property="IsMouseOver" Value="False"&gt;
                          &lt;Setter Property="Background" Value="DeepSkyBlue" /&gt;
                          &lt;Setter Property="BorderBrush" Value="MidnightBlue" /&gt;
                          &lt;Setter Property="BorderThickness" Value="1" /&gt;
                          &lt;Setter Property="Width" Value="15" /&gt;
                          &lt;Setter Property="HorizontalContentAlignment" Value="Right" /&gt;
                          &lt;Setter Property="VerticalContentAlignment" Value="Center" /&gt;
                      &lt;/Trigger&gt;
                      &lt;Trigger Property="IsMouseOver" Value="True"&gt;
                          &lt;Setter Property="Background" Value="MidnightBlue" /&gt;
                          &lt;Setter Property="BorderBrush" Value="DeepSkyBlue" /&gt;
                          &lt;Setter Property="BorderThickness" Value="1" /&gt;
                          &lt;Setter Property="Width" Value="15" /&gt;
                          &lt;Setter Property="HorizontalContentAlignment" Value="Right" /&gt;
                          &lt;Setter Property="VerticalContentAlignment" Value="Center" /&gt;
                      &lt;/Trigger&gt;
                  &lt;/Style.Triggers&gt;
              &lt;/Style&gt;
          &lt;/DataGrid.Resources&gt;
          &lt;DataGrid.Columns&gt;
  
              &lt;!-- TO Number --&gt;
              &lt;DataGridTextColumn 
                  Width="40"
                  Binding="{Binding TONumber}"&gt;
                  &lt;DataGridTextColumn.HeaderTemplate&gt;
                      &lt;DataTemplate&gt;
                          &lt;TextBlock
                              Style="{StaticResource tbkStyleGridHeader}"
                              TextWrapping="Wrap"
                              Text="TO #"/&gt;
                      &lt;/DataTemplate&gt;
                  &lt;/DataGridTextColumn.HeaderTemplate&gt;
              &lt;/DataGridTextColumn&gt;
  
              &lt;!-- GelPak Location --&gt;
              &lt;DataGridTextColumn 
                  Width="60"
                  Binding="{Binding GelPakLocation}"&gt;
                  &lt;DataGridTextColumn.HeaderTemplate&gt;
                      &lt;DataTemplate&gt;
                          &lt;TextBlock
                              Style="{StaticResource tbkStyleGridHeader}"
                              TextWrapping="Wrap"
                              Text="GelPak Location"/&gt;
                      &lt;/DataTemplate&gt;
                  &lt;/DataGridTextColumn.HeaderTemplate&gt;
              &lt;/DataGridTextColumn&gt;
  
              &lt;!-- Die Print --&gt;
              &lt;DataGridTextColumn 
                  Width="60"
                  Binding="{Binding DiePrint}"&gt;
                  &lt;DataGridTextColumn.HeaderTemplate&gt;
                      &lt;DataTemplate&gt;
                          &lt;TextBlock
                              Style="{StaticResource tbkStyleGridHeader}"
                              Text="Die Print"/&gt;
                      &lt;/DataTemplate&gt;
                  &lt;/DataGridTextColumn.HeaderTemplate&gt;
              &lt;/DataGridTextColumn&gt;
  
              &lt;!-- Wire Pull Test --&gt;
              &lt;DataGridTextColumn 
                  Width="70"
                  Binding="{Binding WirePullTestValue}"&gt;
                  &lt;DataGridTextColumn.HeaderTemplate&gt;
                      &lt;DataTemplate&gt;
                          &lt;TextBlock
                              Style="{StaticResource tbkStyleGridHeader}"
                              TextWrapping="Wrap"
                              Text="Wire Pull Test"/&gt;
                      &lt;/DataTemplate&gt;
                  &lt;/DataGridTextColumn.HeaderTemplate&gt;
              &lt;/DataGridTextColumn&gt;
  
              &lt;!-- Failure Mode --&gt;
              &lt;DataGridTextColumn 
                  Width="84"
                  Binding="{Binding FailureMode}"&gt;
                  &lt;DataGridTextColumn.HeaderTemplate&gt;
                      &lt;DataTemplate&gt;
                          &lt;TextBlock
                              Style="{StaticResource tbkStyleGridHeader}"
                              Text="Failure Mode"/&gt;
                      &lt;/DataTemplate&gt;
                  &lt;/DataGridTextColumn.HeaderTemplate&gt;
              &lt;/DataGridTextColumn&gt;
  
              &lt;!-- Ball Shear --&gt;
              &lt;DataGridTextColumn 
                  Width="70"
                  Binding="{Binding BallShearTestValue}"&gt;
                  &lt;DataGridTextColumn.HeaderTemplate&gt;
                      &lt;DataTemplate&gt;
                          &lt;TextBlock
                              Style="{StaticResource tbkStyleGridHeader}"
                              TextWrapping="Wrap"
                              Text="Ball Shear Test"/&gt;
                      &lt;/DataTemplate&gt;
                  &lt;/DataGridTextColumn.HeaderTemplate&gt;
              &lt;/DataGridTextColumn&gt;
  
              &lt;!-- Die Shear --&gt;
              &lt;DataGridTextColumn 
                  Width="70"
                  Binding="{Binding DieShearTestValue}"&gt;
                  &lt;DataGridTextColumn.HeaderTemplate&gt;
                      &lt;DataTemplate&gt;
                          &lt;TextBlock
                              Style="{StaticResource tbkStyleGridHeader}"
                              TextWrapping="Wrap"
                              Text="Die Shear Test"/&gt;
                      &lt;/DataTemplate&gt;
                  &lt;/DataGridTextColumn.HeaderTemplate&gt;
              &lt;/DataGridTextColumn&gt;
  
              &lt;!-- InP Remaining --&gt;
              &lt;DataGridTextColumn 
                  Width="70"
                  Binding="{Binding InPRemaining}"&gt;
                  &lt;DataGridTextColumn.HeaderTemplate&gt;
                      &lt;DataTemplate&gt;
                          &lt;TextBlock
                              Style="{StaticResource tbkStyleGridHeader}"
                              TextWrapping="Wrap"
                              Text="InP Remaining"/&gt;
                      &lt;/DataTemplate&gt;
                  &lt;/DataGridTextColumn.HeaderTemplate&gt;
              &lt;/DataGridTextColumn&gt;
  
              &lt;!-- Test Result --&gt;
              &lt;DataGridTextColumn 
                  Width="70"
                  Binding="{Binding TestResult}"&gt;
                  &lt;DataGridTextColumn.HeaderTemplate&gt;
                      &lt;DataTemplate&gt;
                          &lt;TextBlock
                              Style="{StaticResource tbkStyleGridHeader}"
                              TextWrapping="Wrap"
                              Text="Pass/Fail"/&gt;
                      &lt;/DataTemplate&gt;
                  &lt;/DataGridTextColumn.HeaderTemplate&gt;
              &lt;/DataGridTextColumn&gt;
  
              &lt;!-- Notes --&gt;
              &lt;DataGridTextColumn
                  Width="*"
                  Binding="{Binding Notes}"&gt;
                  &lt;DataGridTextColumn.HeaderTemplate&gt;
                      &lt;DataTemplate&gt;
                          &lt;TextBlock
                              Style="{StaticResource tbkStyleGridHeader}"
                              TextWrapping="Wrap"
                              Text="Notes"/&gt;
                      &lt;/DataTemplate&gt;
                  &lt;/DataGridTextColumn.HeaderTemplate&gt;
              &lt;/DataGridTextColumn&gt;
          &lt;/DataGrid.Columns&gt;
      &lt;/DataGrid&gt;
  </code></pre>
  
  <p>Any help in solving this problem will much appreciated.</p>
  
  <p>Regards,</p>
  
  <p>Kyle</p>