title: WPF add item to datagrid bound to observablecollection exception
body: <p>I have a simple application which shows a list of books.</p>
  
  <p>BookViewModel.cs</p>
  
  <pre><code>    public class BookViewModel : INotifyPropertyChanged
      {
          private readonly IBookRepository _bookRepository;
          private bool _isDirty = false;
  
          public ICommand UpdateCommand { get; set; }
          public bool IsDirty { get { return _isDirty; } }
  
          public BookViewModel(IBookRepository bookRepository)
          {
              _bookRepository = bookRepository;
              UpdateCommand = new UpdateAction(this);
  
              var books = _bookRepository.GetAll();
  
              _allBooks = new ObservableCollection&lt;BookModel&gt;();
              _allBooks.CollectionChanged += collectionChanged;
  
              foreach (var book in books)
              {
                  _allBooks.Add(new BookModel()
                  {
                      Title = book.Title,
                      Stock = book.Stock
                  });
              }
          }
  
          private ObservableCollection&lt;BookModel&gt; _allBooks;
          private BookModel _book;
  
          public BookModel Book
          {
              get { return _book; }
              set
              {
                  _book = value;
                  OnPropertyChanged("Book");
              }
          }
  
          public ObservableCollection&lt;BookModel&gt; AllBooks
          {
              get
              {
                  return _allBooks;
              }
              set 
              { 
                  _allBooks = value;
              }
          }
  
          void collectionChanged(object sender, NotifyCollectionChangedEventArgs e)
          {
              System.Windows.MessageBox.Show(e.Action.ToString());
          }
  
          public event PropertyChangedEventHandler PropertyChanged;
  
          protected void OnPropertyChanged(string name)
          {
              PropertyChangedEventHandler handler = PropertyChanged;
  
              _isDirty = true;
  
              if (handler != null)
              {
                  handler(this, new PropertyChangedEventArgs(name));
              }
          }
      }
  </code></pre>
  
  <p>AllBookView.xaml</p>
  
  <pre><code>&lt;Window x:Class="LibraryManagement.Presentation.WPF.Book.Views.AllBookView"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          Title="AllBookView" Height="311" Width="521"&gt;
      &lt;Grid&gt;
          &lt;DataGrid ItemsSource="{Binding AllBooks, Mode=TwoWay}" AutoGenerateColumns="true" Height="200" HorizontalAlignment="Left" Margin="0,72,0,0" VerticalAlignment="Top" Width="499" /&gt;
          &lt;Button Command="{Binding UpdateCommand}" Content="Update" Height="23" HorizontalAlignment="Left" Margin="412,43,0,0" VerticalAlignment="Top" Width="75" /&gt;
      &lt;/Grid&gt;
  &lt;/Window&gt;
  </code></pre>
  
  <p>I can view the list of books okay, I can also delete a row.</p>
  
  <p>But when I try to add a new item in Datagrid, an exception occured : </p>
  
  <pre><code>System.InvalidOperationException was unhandled
    HResult=-2146233079
    Message=An ItemsControl is inconsistent with its items source.
    See the inner exception for more information.
    Source=PresentationFramework
    StackTrace:
         at System.Windows.Controls.ItemContainerGenerator.Verify()
         at System.Windows.Controls.VirtualizingStackPanel.MeasureChild(IItemContainerGenerator&amp; generator, IContainItemStorage&amp; itemStorageProvider, Object&amp; parentItem, Boolean&amp; hasUniformOrAverageContainerSizeBeenSet, Double&amp; computedUniformOrAverageContainerSize, Boolean&amp; computedAreContainersUniformlySized, IList&amp; items, Object&amp; item, IList&amp; children, Int32&amp; childIndex, Boolean&amp; visualOrderChanged, Boolean&amp; isHorizontal, Size&amp; childConstraint, Rect&amp; viewport, VirtualizationCacheLength&amp; cacheSize, VirtualizationCacheLengthUnit&amp; cacheUnit, Boolean&amp; foundFirstItemInViewport, Double&amp; firstItemInViewportOffset, Size&amp; stackPixelSize, Size&amp; stackPixelSizeInViewport, Size&amp; stackPixelSizeInCacheBeforeViewport, Size&amp; stackPixelSizeInCacheAfterViewport, Size&amp; stackLogicalSize, Size&amp; stackLogicalSizeInViewport, Size&amp; stackLogicalSizeInCacheBeforeViewport, Size&amp; stackLogicalSizeInCacheAfterViewport, Boolean&amp; mustDisableVirtualization, Boolean isBeforeFirstItem, Boolean isAfterFirstItem, Boolean isAfterLastItem, Boolean 
  ...
    InnerException: 
         HResult=-2146233088
         Message=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 '(unnamed)' 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 'LibraryManagement.Presentation.WPF.Book.BookModel'.
  
  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[[LibraryManagement.Presentation.WPF.Book.BookModel, LibraryManagement.Presentation.WPF, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]
  (The starred sources are considered more likely to be the cause of the problem.)
  
  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.
  
  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.
  </code></pre>
  
  <p>Should I attach an event handler when the datagrid row added?</p>
  
  <p>I thought with two way binding, any changes in each sides will be reflected to the other side?</p>