Laden...

[gelöst] WPF DataGrid schluckt DataTable aus einem Dataset nicht und dann doch wieder

Erstellt von Der Leiharbeiter vor 11 Jahren Letzter Beitrag vor 11 Jahren 2.323 Views
D
Der Leiharbeiter Themenstarter:in
6 Beiträge seit 2013
vor 11 Jahren
[gelöst] WPF DataGrid schluckt DataTable aus einem Dataset nicht und dann doch wieder

Hallo Leute,

ich hab mich mal angemeldet, weil ich ein Problem habe, auf dessen Lösung ich nicht komme, trotz Googlen und Kollegen fragen.

Hier mal dazu der Stacktrace, der bei der NullReferenceException erscheint:

Fehlermeldung:
Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt!

bei System.Windows.Controls.ItemContainerGenerator.OnItemAdded(Object item, Int32 index)
bei System.Windows.Controls.ItemContainerGenerator.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)
bei System.Windows.Controls.ItemContainerGenerator.System.Windows.IWeakEventListener.ReceiveWeakEvent(Type managerType, Object sender, EventArgs e)
bei System.Windows.WeakEventManager.DeliverEventToList(Object sender, EventArgs args, ListenerList list)
bei System.Windows.WeakEventManager.DeliverEvent(Object sender, EventArgs args)
bei System.Collections.Specialized.CollectionChangedEventManager.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)
bei System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(Object sender, NotifyCollectionChangedEventArgs e)
bei System.Windows.Data.CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args)
bei System.Windows.Controls.ItemCollection.System.Windows.IWeakEventListener.ReceiveWeakEvent(Type managerType, Object sender, EventArgs e)
bei System.Windows.WeakEventManager.DeliverEventToList(Object sender, EventArgs args, ListenerList list)
bei System.Windows.WeakEventManager.DeliverEvent(Object sender, EventArgs args)
bei System.Collections.Specialized.CollectionChangedEventManager.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)
bei System.Windows.Data.CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args)
bei System.Windows.Data.BindingListCollectionView.ProcessCollectionChanged(NotifyCollectionChangedEventArgs args)
bei System.Windows.Data.CollectionView.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)
bei System.Windows.Data.BindingListCollectionView.set_NewItemPlaceholderPosition(NewItemPlaceholderPosition value)
bei System.Windows.Controls.ItemCollection.System.ComponentModel.IEditableCollectionView.set_NewItemPlaceholderPosition(NewItemPlaceholderPosition value)
bei System.Windows.Controls.DataGrid.UpdateNewItemPlaceholder(Boolean isAddingNewItem)
bei System.Windows.Controls.DataGrid.OnCanUserAddRowsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
bei System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
bei System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
bei System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
bei System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
bei System.Windows.DependencyObject.CoerceValue(DependencyProperty dp)
bei System.Windows.Controls.DataGrid.OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue)
bei System.Windows.Controls.ItemsControl.OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
bei System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
bei System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
bei System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
bei System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
bei System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
bei System.Windows.Controls.ItemsControl.set_ItemsSource(IEnumerable value)
bei Budgettool.wpfAdminArea.Window_Loaded(Object sender, RoutedEventArgs e) in C:\01_DATA\budgettoolblasmaschinen\Quellcode\budgettool\wpfAdminArea.xaml.cs:Zeile 52.

Den entsprechenden Codeausschnitt, wo der Fehler auftritt, hab ich als Bild angehängt. Es handelt sich gleich um die erste Anweisung in der Methode. Das Schlimme ist eigentlich, das er fast willkürlich auftritt. Beim ersten läuft die Logik ganz normal durch. Danach kommt dieser Fehler.

Ich programmiere mit Visual Studio 2010 Professional und dem .NET-Framework 4.0 . Vielleicht kann mir hier helfen. Auf jeden Fall schon mal danke und wenn ihr noch was braucht, schreien.

Viele Grüße
Christopher

D
Der Leiharbeiter Themenstarter:in
6 Beiträge seit 2013
vor 11 Jahren

Damit ist es vielleicht noch etwas klarer, im Anhang befindet sich gleich der nächste Schritt nach der Anweisung.

849 Beiträge seit 2006
vor 11 Jahren

Puh das wird nicht unbedingt leicht das zu analysieren.

in den Optionen von VS kannst Du einstellen das Du auch in die Sourcen von .net debuggen kannst. Wenn Du dann in Debugging -> exceptions noch die entsprechenden häckchen setzt, solltest Du genau an der Stelle rauskommen wo es wirklich knallt.

Dein Problem fängt beim Setter von ItemsSource an und hört in der OnItemAdded von itemcontainergenerator auf.

Leider sieht man nicht genau was Da nu schiefläuft.
Hast Du Templates in deiner DataGrid benutzt? Vllt liegt der Fehler darin, das er eins davon nicht erzeugen kann.

5.299 Beiträge seit 2008
vor 11 Jahren

naja, NullReferenceExceptions sind üblicherweise einfach.

Hier sehe ich nur folgende Möglichkeiten, welcher Ausdruck unzulässigerweise null ergeben kann:*dgFormtypes *_DBAccess *_DBAccess.DatasetBudget *_DBAccess.DatasetBudget.Formbauart

Das wird man doch nachgugge können.

Der frühe Apfel fängt den Wurm.

849 Beiträge seit 2006
vor 11 Jahren

Hallo ErfinderDesRades,

ich glaube Du hast Dir die angepinnten "Watches" und den Stacktrace nicht angeschaut. Die NullReference passiert im Setter von dgFormtypes.ItemSource.

D
Der Leiharbeiter Themenstarter:in
6 Beiträge seit 2013
vor 11 Jahren

Hallo unconnected,

Templates habe ich nicht benutzt, ich habe das Datagrid selber definiert.

                            
<DataGrid SelectionUnit="CellOrRowHeader"
        Name="dgProcesstypes"
        AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Path=Bezeichnung}"
                        Header="{x:Static r:AdminArea.DataGridColumnHeaderTitle}"
                        Width="100"/>
        <DataGridTextColumn Binding="{Binding Path=Obergrenze}"
                        Header="{x:Static r:AdminArea.DataGridColumnHeaderUpperLimit}"
                        Width="100"/>
        <DataGridTextColumn Binding="{Binding Path=Beschreibung}"
                        Header="{x:Static r:AdminArea.DataGridColumnHeaderDescription}"
                        Width="180"/>
    </DataGrid.Columns>
</DataGrid>

Die zwei anderen DataGrids haben einen ähnlichen Aufbau.

Was ich nicht verstehe, in der Anweisung, wo der Fehler auftritt, wird aber die Datenbindung gesetzt. Natürlich dann nicht mehr die restlichen, weil er dann in den catch-Block hüpft.

Und gerade habe ich noch was probiert. Wenn ich den gelben Pfeil wieder zu der Anweisung zurücksetze und diese nochmal ausführen lasse, geht er wieder einwandfrei durch. Eigentlich erwarte ich da, das der Fehler nochmal passiert.

Mal sehen, ich probiere mal die Sache mit den Haken aus, vielleicht ergibt sich da was.

Total verwirrte und ratlose Grüße
Christopher

D
Der Leiharbeiter Themenstarter:in
6 Beiträge seit 2013
vor 11 Jahren

Hallo Leute,

ich hab das Problem nun gefunden.

Dank dem Tipp von unconnected hat das Ding nun mir immer angezeigt, wenn es irgendwo einen Fehler schmeißt.

Ich hab für das Gegenstück des geposteten Codes (also praktisch das Speichern des DataSets in der Datenbank) einen Thread erstellt, damit die Oberfläche nicht einfriert, während die Daten zurückgespeichert werden.

Wenn die Daten im DataSet entgültig geschrieben werden (durch die Methode AcceptChanges), werden zwar die Änderungen alle übernommen, aber im Hintergrund schmeißt es einen Fehler, der auch gleich im Hintergrund wieder behandelt wird. Ohne die Haken wäre der gar nicht aufgefallen.

Durch den Haken unter Debuggen -> Ausnahmen hab ich aber nun den Fehler (sinnhaftig) "Prozess darf nicht auf Objekt eines andern Prozesses zugreifen" gesehen und die Folge daraus ist, das es dann den NullReference schmeißt, wenn das DataSet wieder an die Oberfläche gebunden wird. Aber dann nur das erste Mal.

Was habe ich daraus gelernt, unglaublich aufpassen mit Threads. Das kann manchmal echt fieselig werden.

Viele Grüße
Christopher

5.299 Beiträge seit 2008
vor 11 Jahren

Aha - das war das Problem.

Und wie sieht nun deine Lösung aus?

Der frühe Apfel fängt den Wurm.

D
Der Leiharbeiter Themenstarter:in
6 Beiträge seit 2013
vor 11 Jahren

Die Lösung war, mit Hilfe von Invoke() die Methode AcceptChanges() nicht im Speicherthread, sondern im Hauptthread aufzurufen. Das war alles.

5.299 Beiträge seit 2008
vor 11 Jahren

AFAIK sollteman .AcceptChanges niemals aufrufen, weil das ist ein tiefer Eingriff in die Änderungsverfolgung des Datasets.

Das wird doch intern durch die DataAdapter aufgerufen.

Annere Frage zum Eingangspost: Gabs da eiglich eine Inner-Exception, die dich vlt. schneller auf die Ursache gebracht hätte?

Der frühe Apfel fängt den Wurm.

D
Der Leiharbeiter Themenstarter:in
6 Beiträge seit 2013
vor 11 Jahren

Servus,

nein, es gab leider keine InnerException.

Mal sehen, vielleicht lass ich das mit den AcceptChanges. Da werde ich aber vorher nochmal drüber googlen, was es denn gibt.