Проблема с привязкой источника элементов данных WPF DataGrid

У меня есть DataGrid в приложении WPF, которое связывает себя с ObservableCollection объектов, и все работает нормально. Теперь, если я изменяю ячейку в сетке данных во время выполнения и удаляю содержимое, оставьте ячейку пустой. Соответствующее значение observableCollection не будет изменено, это будет старое значение. Но когда я выхожу из окна, содержащего сетку данных, и перезапускаю окно, оно генерирует исключение XamlParseException со словами: «Set Property '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: 

Это не вызовет исключения, если, когда я закрою окно, ни одна ячейка в сетке данных не будет пустой. Я также проверил коллекцию до того, как Window выполнит InitializeComponent Line, и она выглядит отлично, все объекты имеют правильное значение, без пустых или нулевых значений. Я не могу понять, почему он выбрасывает это исключение. Любые идеи? Заранее спасибо.

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}}">

person Ling Xing    schedule 07.03.2011    source источник
comment
Допускают ли свойства элементов в коллекции значение NULL? Когда обновляется ваше имущество (например, PropertyChanged, LoseFocus и т. Д.).   -  person CodeWarrior    schedule 08.03.2011
comment
свойства объекта в коллекции не допускают значения NULL, они обновляются при изменении свойства. но из прошлого опыта оставление поля пустым не означает, что соответствующий объект в коллекции имеет значение NULL. и я проверил после того, как значение было оставлено пустым, что объект в коллекции все еще является старым значением. Прежде чем окно снова откроется, я снова проверил значения, и пустых свойств нет. По какой-то причине WPF выдает исключение, когда попадает в заданное свойство ItemsSource DependencyProperty DataGrid   -  person Ling Xing    schedule 08.03.2011
comment
Я предлагаю вам найти любую другую часть вашего пользовательского интерфейса, которая привязана к той же ObservableCollection, и удалить все привязки к этой коллекции, чтобы снова протестировать проблему выше изолированно. Если вам повезет, это просто проблема, связанная с тем, что соответствующий CollectionView используется другими элементами управления.   -  person Alex Maker    schedule 29.11.2011


Ответы (2)


Похоже, было довольно много проблем с DataGrid и DeferRefresh. Вот два актуальных сообщения:

Общая рекомендация, по-видимому, состоит в том, чтобы изучить представление, связанное с DataGrid, как IEditableCollectionView (которое будет вашим по умолчанию, поскольку ObservableCollection получает ListCollectionView во время привязки, когда я последний раз смотрел) и проверьте IsAddingNew и IsEditingItem, чтобы узнать, безопасно ли изменять представление. Такие модификации будут включать DeferRefresh, который, по сути, является Disposable, используемым для пакетирования модификаций представления.

Насколько я понимаю, у вас есть проблема в том, что DataGrid находится на полпути через транзакцию или представление настроено так, чтобы это было так, пока вы меняете ItemsSource (что изменит или полностью заменит связанный связанный вид). То, что вы очищаете ячейку, но еще не изменяете базовые данные, означает, что началось редактирование (BeginEdit), но еще не зафиксировано (CommitEdit), что происходит, когда вы изменяете ячейку по умолчанию.

То, что это происходит, когда вы закрываете и снова открываете окно, подразумевает, что сохраняется некоторое сохраненное состояние, которое все еще считает, что транзакция выполняется. Возможно, он по-прежнему использует тот же ListCollectionView, что и раньше, и для IsEditingItem по-прежнему установлено значение true?

Исправление, скорее всего, гарантирует, что все изменения будут внесены до того, как вы закроете окно.

person naviwhack    schedule 28.10.2011
comment
Это правильно. И лучшее решение - использовать это поведение: stackoverflow.com/a/6467171/724944 - person surfen; 18.12.2011

Если поле, которое вы закрываете, не относится к строке типа, возможно, оно обновляется некорректно.

например, если это "int", и вы очистите ячейку, свойство "int" вашей модели просмотра не будет установлено.

Я решил эту проблему с помощью конвертера, который преобразует пустые значения для целых чисел в ноль.

надеюсь это поможет

person Anton    schedule 15.08.2011