WPF将项添加到绑定到observablecollectionexception的datagrid

我有一个简单的应用程序,显示了一个书籍列表。

BookViewModel.cs

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(); _allBooks.CollectionChanged += collectionChanged; foreach (var book in books) { _allBooks.Add(new BookModel() { Title = book.Title, Stock = book.Stock }); } } private ObservableCollection _allBooks; private BookModel _book; public BookModel Book { get { return _book; } set { _book = value; OnPropertyChanged("Book"); } } public ObservableCollection 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)); } } } 

AllBookView.xaml

    

我可以查看书籍列表没关系,我也可以删除一行。

但是当我尝试在Datagrid中添加新项时,发生了一个exception:

 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& generator, IContainItemStorage& itemStorageProvider, Object& parentItem, Boolean& hasUniformOrAverageContainerSizeBeenSet, Double& computedUniformOrAverageContainerSize, Boolean& computedAreContainersUniformlySized, IList& items, Object& item, IList& children, Int32& childIndex, Boolean& visualOrderChanged, Boolean& isHorizontal, Size& childConstraint, Rect& viewport, VirtualizationCacheLength& cacheSize, VirtualizationCacheLengthUnit& cacheUnit, Boolean& foundFirstItemInViewport, Double& firstItemInViewportOffset, Size& stackPixelSize, Size& stackPixelSizeInViewport, Size& stackPixelSizeInCacheBeforeViewport, Size& stackPixelSizeInCacheAfterViewport, Size& stackLogicalSize, Size& stackLogicalSizeInViewport, Size& stackLogicalSizeInCacheBeforeViewport, Size& stackLogicalSizeInCacheAfterViewport, Boolean& 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. 

我应该在添加datagrid行时附加事件处理程序吗?

我想用双向绑定,每边的任何变化都会反映到另一边?

从CollectionChanged事件中删除MessageBox.Show()调用。

实际上,完全删除CollectionChanged事件处理程序。

MessageBox.Show()强制Dispatcher刷新,并且在引发CollectionChanged事件时这样做不是一个好主意。