WPF添加项数据网格绑定到的ObservableCollection异常 [英] WPF add item to datagrid bound to observablecollection exception

查看:1491
本文介绍了WPF添加项数据网格绑定到的ObservableCollection异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

但是,当我尝试添加在DataGrid中新的项目,一个异常发生:

But when I try to add a new item in Datagrid, an exception occured :

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行,当一个事件处理程序?

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?

推荐答案

从CollectionChanged事件删除的MessageBox.show()电话。

Remove the MessageBox.Show() call from the CollectionChanged event.

其实,产品总数取出CollectionChanged事件处理程序。

Actually, remove the CollectionChanged event handler alltogether.

的MessageBox.show()强制调度冲洗,并为此而CollectionChanged引发事件是不是一个好主意。

MessageBox.Show() forces the Dispatcher to flush, and doing so while a CollectionChanged event is raised is not a good idea.

这篇关于WPF添加项数据网格绑定到的ObservableCollection异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆