title: How to correctly handle the CollectionChanged event of datagrid?
body: <p>I initially asked a question related to dataGrid insert/delete/save operations with Entity Framework <a href="https://stackoverflow.com/questions/35722363/duplicate-entry-on-the-database-while-using-datagrid-and-utilizing-triggered-eve">here</a> However I was not able to totally get the suggested approach to work. Here's my approach so far:</p>
  
  <p><strong>ViewModel constructor</strong></p>
  
  <pre><code>public DeviceDatabaseViewModel()
  {
      LoadData();
  }
  </code></pre>
  
  <p><strong>LoadData</strong></p>
  
  <pre><code>private void LoadData()
  {
      _context.Devices.Load();
      _devices = _context.Devices.GetLocal();
  
      _devices.CollectionChanged += Device_CollectionChanged;
  
      DeviceCollectionView = (CollectionView)new CollectionViewSource { Source = _devices }.View;
  }
  </code></pre>
  
  <p><strong>Event</strong></p>
  
  <pre><code>private bool _isAddedbyApp = false;
  
  private void Device_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
  {
      var device = new Device();
      switch (e.Action)
      {
          case NotifyCollectionChangedAction.Add:
              foreach (var item in e.NewItems)
              {
                  var entity = item as Device;
                  if (entity == null) continue;
                  if (_isAddedbyApp) continue;
  
                  _isAddedbyApp = true;
                  _context.Devices.Add(entity);
                  _isAddedbyApp = false;
              }
              break;
          case NotifyCollectionChangedAction.Remove:
              foreach (var item in e.OldItems)
              {
                  var entity = item as Device;
                  if (entity == null) continue;
                  if (_isAddedbyApp) continue;
  
                  _isAddedbyApp = true;
                  _context.Devices.Remove(entity);
                  _isAddedbyApp = false;
              }
              break;
          //Reset = Clear
          case NotifyCollectionChangedAction.Reset:
  
              break;
      }
  }
  </code></pre>
  
  <p><strong>xaml</strong></p>
  
  <pre><code>&lt;DataGrid 
            x:Name="DeviceListDataGrid" 
            Margin="0,25,0,0"
            Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="6"
            AutoGenerateColumns="False" 
            EnableRowVirtualization="True" 
            AlternatingRowBackground="LightBlue" 
            AlternationCount="2" 
            RowDetailsVisibilityMode="VisibleWhenSelected"
            ItemsSource="{Binding DeviceDatabaseViewModel.DeviceCollectionView}" 
            SelectedItem="{Binding DeviceDatabaseViewModel.SelectedDevice}"&gt;
      &lt;DataGrid.Resources&gt;
          &lt;SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="DarkCyan"/&gt;
          &lt;SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="DarkCyan"/&gt;
      &lt;/DataGrid.Resources&gt;
      &lt;DataGrid.Columns&gt;
          &lt;DataGridTextColumn x:Name="DeviceIdentification" Header="Id" Width="200*" Binding="{Binding DeviceId, UpdateSourceTrigger=PropertyChanged}"  /&gt;
          &lt;DataGridTextColumn x:Name="DeviceName" Header="Name" Width="200*" Binding="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"  /&gt;
          &lt;DataGridTextColumn x:Name="DeviceDescriptionColumn" Header="Description" Width="200*" Binding="{Binding Description, UpdateSourceTrigger=PropertyChanged}"/&gt;
          &lt;DataGridTextColumn x:Name="DeviceSupplier" Header="Supplier" Width="150*" Binding="{Binding Supplier, UpdateSourceTrigger=PropertyChanged}"/&gt;
          &lt;DataGridTextColumn x:Name="DeviceCategory" Header="Category" Width="150*" Binding="{Binding Category, UpdateSourceTrigger=PropertyChanged}"/&gt;
      &lt;/DataGrid.Columns&gt;
  &lt;/DataGrid&gt;
  </code></pre>
  
  <p>The <code>GetLocal</code>returns <code>ObservableCollection</code> from the Entity Framework database which also is implementing the <code>INotifyPropertyChanged</code>.</p>
  
  <p>However I'm unable to find the correct place for the <code>SaveChanges</code> method of Entity Framework, and additionally the structure seems to be a bit off?</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>If I have placed the <code>SaveChanges</code> at the end of the event <code>CollectionChanged</code> my program hangs. Actually I had for some Debug reasons a MessageBox inside the <code>SaveChanges()</code> method, after disabling it things seems to be more or less in the right direction..</p>
  
  <p><strong>EDIT 2</strong>
  Adding the Device entity definitions. 
  <a href="https://github.com/ajr85/FxTesting/blob/master/FxEditorDatabaseStructure/Core/Domain/Device.cs" rel="nofollow noreferrer">Link to the file</a>, because its rather long..</p>
  
  <p>MessageBox is resulting with this <strong>exception</strong>:</p>
  
  <blockquote>
    <p>{"An ItemsControl is inconsistent with its items source.\n  See the
    inner exception for more information."}</p>
    
    <p>{"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:28' with name
    'DeviceListDataGrid' 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 27 is
    different from actual count 28.  [Accumulated count is (Count at last
    Reset + #Adds - #Removes since last Reset).]\r\n  At index 26: 
    Generator's item '{NewItemPlaceholder}' is different from actual item
    'FxEditorDatabaseStructure.Core.Domain.Device'.\r\n\r\nOne or more of
    the following sources may have raised the wrong events:\r\n<br>
    System.Windows.Controls.ItemContainerGenerator\r\n<br>
    System.Windows.Controls.ItemCollection\r\n<br>
    System.Windows.Data.ListCollectionView\r\n<br>
    System.Collections.ObjectModel.ObservableCollection`1[[FxEditorDatabaseStructure.Core.Domain.Device,
    FxEditorDatabaseStructure, 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<br>
    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"}</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:28' with name
    'DeviceListDataGrid' 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 27 is
    different from actual count 28.  [Accumulated count is (Count at last
    Reset + #Adds - #Removes since last Reset).]   At index 26: 
    Generator's item '{NewItemPlaceholder}' is different from actual item
    'FxEditorDatabaseStructure.Core.Domain.Device'.</p>
  </blockquote>