2011-03-07 41 views
7

Tengo un DataGrid en una aplicación WPF que se une a un ObservableCollection de objetos, y todo funciona bien. Ahora, si modifico una celda en la cuadrícula de datos durante el tiempo de ejecución y elimino el contenido, dejo la celda vacía. El valor correspondiente de observableCollection no se modificará, será el valor anterior. Pero cuando se cierre la ventana que contiene la cuadrícula de datos y reiniciar la ventana, se lanza una XamlParseException, dice: "set 'System.Windows.Controls.ItemsControl.ItemsSource' Propiedad inició una excepción"WPF DataGrid ItemsSource Binding Número

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: 

No lo hará lanzar la excepción siempre que cuando cerré la ventana, ninguna celda en la cuadrícula de datos esté vacía. También verifiqué la colección antes de que la ventana haga InitializeComponent Line y se ve perfectamente bien, todos los objetos tienen el valor correcto, ni vacíos ni nulos. No puedo entender por qué está lanzando esta excepción. ¿algunas ideas? Gracias de antemano.

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

¿Las propiedades de los elementos de la colección son nulables? Cuándo se actualiza su propiedad (por ejemplo, PropertyChanged, LoseFocus, etc.). – CodeWarrior

+0

las propiedades del objeto en la colección no pueden contener nulos, se actualizan en propertychanged. pero a partir de la experiencia pasada, cuando el campo se deja en blanco no significa que el objeto correspondiente en la colección sea nulo. y he verificado después de que el valor se haya dejado en blanco que el objeto en la colección sigue siendo el valor anterior.Antes de que la ventana se abra de nuevo, verifiqué los valores nuevamente y no hay propiedades vacías. Por alguna razón WPF lanza una excepción cuando llega a la propiedad set de ItemsSource Dependency Property del DataGrid –

+0

. Sugiero que busque cualquier otra parte de su UI que se una a la misma ObservableCollection y elimine todo el enlace a esa colección para probar usted encima del problema otra vez en el aislamiento. Si tienes suerte, esto es simplemente un problema con la colección CollectionView que utilizan otros controles. –

Respuesta

3

No parece que haya habido bastantes problemas con la cuadrícula de datos & DeferRefresh. Aquí hay dos relevantposts:

La recomendación genérica parece ser examinar vista asociada de la cuadrícula de datos como un IEditableCollectionView (que la suya sería por defecto como ObservableCollection consigue un ListCollectionView durante la unión la última vez que miré) y comprobar IsAddingNew & IsEditingItem a ver si es seguro modificar la vista. Tales modificaciones incluirían DeferRefresh, que es esencialmente un Desechable utilizado para combinar modificaciones en la vista.

Por lo que puedo ver, el problema que tiene es que DataGrid está a mitad de una transacción, o la vista está configurada para creerlo, mientras está cambiando ItemsSource (lo que cambiaría o reemplazaría completamente el límite asociado) ver). Que está borrando una celda pero todavía no está modificando los datos subyacentes implica que ha comenzado una edición (BeginEdit), pero aún no está comprometida (CommitEdit), que ocurre cuando se cambia la celda de forma predeterminada.

Lo que está sucediendo cuando se está cerrando & al volver a abrir la ventana implica que se mantiene un estado preservado que todavía cree que una transacción está en progreso. Tal vez todavía está utilizando el mismo ListCollectionView como antes, y que todavía tiene IsEditingItem establecido en true?

Es muy probable que la corrección asegure que todas y cada una de las ediciones se confirmen antes de cerrar la ventana.

+0

Eso es correcto. Y la mejor solución es usar este comportamiento: http://stackoverflow.com/a/6467171/724944 – surfen

0

si el campo que está quedarse en blanco no es de tipo cadena, entonces es posible que no se actualiza correctamente.

por ejemplo, si es un "int" y se vacía la celda, no se establecerá la propiedad "int" de su viewmodel.

La forma en que he solucionado este problema es con un convertidor que convierte los valores en blanco para las entradas en cero.

esperanza esto ayuda