[英]WPF add item to datagrid bound to observablecollection exception
I have a simple application which shows a list of books. 我有一个简单的应用程序,显示了一个书籍列表。
BookViewModel.cs 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<BookModel>();
_allBooks.CollectionChanged += collectionChanged;
foreach (var book in books)
{
_allBooks.Add(new BookModel()
{
Title = book.Title,
Stock = book.Stock
});
}
}
private ObservableCollection<BookModel> _allBooks;
private BookModel _book;
public BookModel Book
{
get { return _book; }
set
{
_book = value;
OnPropertyChanged("Book");
}
}
public ObservableCollection<BookModel> 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 AllBookView.xaml
<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">
<Grid>
<DataGrid ItemsSource="{Binding AllBooks, Mode=TwoWay}" AutoGenerateColumns="true" Height="200" HorizontalAlignment="Left" Margin="0,72,0,0" VerticalAlignment="Top" Width="499" />
<Button Command="{Binding UpdateCommand}" Content="Update" Height="23" HorizontalAlignment="Left" Margin="412,43,0,0" VerticalAlignment="Top" Width="75" />
</Grid>
</Window>
I can view the list of books okay, I can also delete a row. 我可以查看书籍列表没关系,我也可以删除一行。
But when I try to add a new item in Datagrid, an exception occured : 但是当我尝试在Datagrid中添加新项时,发生了一个异常:
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.
Should I attach an event handler when the datagrid row added? 添加数据网格行时是否应附加事件处理程序?
I thought with two way binding, any changes in each sides will be reflected to the other side? 我想用双向绑定,每边的任何变化都会反映到另一边?
Remove the MessageBox.Show()
call from the CollectionChanged event. 从CollectionChanged事件中删除MessageBox.Show()
调用。
Actually, remove the CollectionChanged event handler alltogether. 实际上,完全删除CollectionChanged事件处理程序。
MessageBox.Show()
forces the Dispatcher to flush, and doing so while a CollectionChanged event is raised is not a good idea. MessageBox.Show()
强制Dispatcher刷新,并且在引发CollectionChanged事件时这样做不是一个好主意。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.