简体   繁体   English

WPF DataGrid ItemsSource绑定问题

[英]WPF DataGrid ItemsSource Binding Issue

I have a DataGrid in a WPF application that binds itself to an ObservableCollection of objects, and everything works fine. 我在WPF应用程序中有一个DataGrid,它将自己绑定到一个ObservableCollection对象,一切正常。 Now if I modify a cell in the datagrid during runtime, and delete the content, leave the cell empty. 现在,如果我在运行时修改数据网格中的单元格并删除内容,请将单元格留空。 The observableCollection's corresponding value will not be modified, it will be the old value. observableCollection的对应值不会被修改,它将是旧值。 But when I exit the window containing the datagrid and restart the window, it throws a XamlParseException, says:"Set Property 'System.Windows.Controls.ItemsControl.ItemsSource' threw an exception" 但是当我退出包含datagrid的窗口并重新启动窗口时,它会抛出一个XamlParseException,说:“设置属性'System.Windows.Controls.ItemsControl.ItemsSource'引发异常”

  StackTrace:
       at System.Windows.Markup.XamlReader.RewrapException(Exception e, IXamlLineInfo lineInfo, Uri baseUri)
       at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
       at System.Windows.Markup.WpfXamlLoader.LoadBaml(XamlReader xamlReader, Boolean skipJournaledProperties, Object rootObject, XamlAccessLevel accessLevel, Uri baseUri)
       at System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream)
       at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator)
       at VO3.Start.InitializeComponent() in c:\VO\Trunk\VO3\Start.xaml:line 1
       at VO3.Start..ctor() in C:\VO\Trunk\VO3\Start.xaml.cs:line 103
  InnerException: System.InvalidOperationException
       Message='DeferRefresh' is not allowed during an AddNew or EditItem transaction.
       Source=PresentationFramework
       StackTrace:
            at System.Windows.Data.CollectionView.DeferRefresh()
            at System.Windows.Controls.ItemCollection.SetCollectionView(CollectionView view)
            at System.Windows.Controls.ItemCollection.SetItemsSource(IEnumerable value)
            at System.Windows.Controls.ItemsControl.OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
            at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
            at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
            at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
            at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
            at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
            at System.Windows.Baml2006.WpfKnownMemberInvoker.SetValue(Object instance, Object value)
            at MS.Internal.Xaml.Runtime.ClrObjectRuntime.SetValue(XamlMember member, Object obj, Object value)
            at MS.Internal.Xaml.Runtime.ClrObjectRuntime.SetValue(Object inst, XamlMember property, Object value)
       InnerException: 

It won't throw the exception as long as when I closed the window, no cell in the datagrid is empty. 只要关闭窗口时,它就不会抛出异常,数据网格中的任何单元格都不为空。 I also checked the Collection before the Window does InitializeComponent Line and it looks perfectly fine, all the objects have the correct value, no empty or nulls. 我还在Window执行InitializeComponent Line之前检查了Collection,它看起来很完美,所有对象都有正确的值,没有空或空。 I cannot figure out why it's throwing this exception. 我无法弄清楚为什么它会抛出这个异常。 any ideas? 有任何想法吗? Thanks in advance. 提前致谢。

XAML: XAML:

<DataGrid HeadersVisibility="All" RowHeight="19" AutoGenerateColumns="False" Grid.Row="1" CanUserResizeColumns="False"
                              CanUserAddRows="False" CanUserDeleteRows="False" Block.TextAlignment="Right" Grid.RowSpan="2" CanUserReorderColumns="False"
                              ItemsSource="{Binding Collection}" Width="132" HorizontalAlignment="Right" Margin="10,0,10,0" CanUserSortColumns="False"
                              IsEnabled="{Binding ElementName=CheckBox, Path=SelectedIndex, Converter={StaticResource startEnabledConverter}}">

There appear to have been quite a few issues with the DataGrid & DeferRefresh. DataGrid和DeferRefresh似乎存在很多问题。 Here are two relevant posts : 这是两个相关的 帖子

The generic recommendation seems to be to examine the DataGrid's associated view as an IEditableCollectionView (which yours would be by default as ObservableCollection gets a ListCollectionView during binding when last I looked) and check IsAddingNew & IsEditingItem to see if it's safe to modify the view. 通用建议似乎是将DataGrid的关联视图检查为IEditableCollectionView(默认情况下是你的,因为ObservableCollection在最后一次查看时在绑定期间获取了ListCollectionView)并检查IsAddingNew和IsEditingItem以查看修改视图是否安全。 Such modifications would include DeferRefresh, which is essentially a Disposable used to batch up modifications to the view. 这些修改将包括DeferRefresh,它本质上是一个用于批量修改视图的Disposable。

As far as I can see, the problem you have is that the DataGrid is midway through a transaction, or the view is set to believe it is, whilst you are changing ItemsSource (which would change or entirely replace the associated bound view). 据我所知,您遇到的问题是DataGrid位于事务的中间,或者视图设置为相信它,而您正在更改ItemsSource(这将更改或完全替换关联的绑定视图)。 That you are clearing out a cell but it is not yet modifying the underlying data implies it's begun an edit (BeginEdit), but not yet committed (CommitEdit), which occurs when you change cell by default. 您正在清除单元格但尚未修改基础数据意味着它已开始编辑(BeginEdit),但尚未提交(CommitEdit),这在默认情况下更改单元格时会发生。

That it is happening when you are closing & reopening the window implies that some preserved state is kept around that still thinks a transaction is in progress. 当你关闭并重新打开窗口时发生这种情况意味着保留了一些保留状态仍然认为事务正在进行中。 Perhaps it is still using the same ListCollectionView as before, and that still has IsEditingItem set to true? 也许它仍然使用与以前相同的ListCollectionView,并且仍然将IsEditingItem设置为true?

The fix is most likely to ensure that any and all edits are committed before you close the window. 该修复最有可能确保在关闭窗口之前提交任何和所有编辑。

if the field that you are blanking out is not of type string, then it may not be updating correctly. 如果您正在消隐的字段不是字符串类型,则可能无法正确更新。

for example, if it is an "int" and you blank out the cell the "int" property of your viewmodel will not get set. 例如,如果它是一个“int”并且您将单元格空白,则视图模型的“int”属性将不会被设置。

The way i have fixed this problem is with a converter that converts blank values for ints into zero. 解决这个问题的方法是使用转换器将int的空白值转换为零。

hope this helps 希望这可以帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM