Laden...

[erledigt] NullReferenceException beim Zugriff auf (datengebundene) Data Table

Erstellt von Kelmoir vor 11 Jahren Letzter Beitrag vor 11 Jahren 3.989 Views
K
Kelmoir Themenstarter:in
6 Beiträge seit 2011
vor 11 Jahren
[erledigt] NullReferenceException beim Zugriff auf (datengebundene) Data Table

Hallo,

In einem Programm verwende ich DataGridViews zum benutzerdefinierten Anzeigen von Daten.
Diese befülle ich mittels DataTables, welche als in den DataGridViews als BindingSource eingetragen sind.
Die TataTables werden nicht Automatisch, sondern "händisch" befüllt, und wiederbefüllt.
Das klappt alles auch sehr gut, nur leider bekomme ich eine NullReference Exception, wenn die DataTable nach umsortieren durch den Nutzer neu mit Werten befüllt werden soll.
Diese tritt auch auch, wenn ich statisch auf das Element [0][0] zugreife, und vordefiniertes dort Eintragen will.
die Colums und Rows wurden nachweislich vorher erzeugt (auch wenn die Exception auftritt).
Eine Sortierung kann gerne über den Haufen geworfen werden, sie ist mir nicht wichtig.

Die eigene suche nach Lösungen war nicht von Erfolg gekrönt.

Der Code: (die DataGridView, sowie die DataTable sind Membervariablen, bereits Instanziert, und auch als Binding source zugewiesen)


        void dgGefunden_WerteEintragen()
        {
            m_GefundeneBauteile.Rows.Clear();
            m_GefundeneBauteile.Columns.Clear();
            m_GefundeneBauteile.Columns.Add("Index", typeof(int));
            m_GefundeneBauteile.Columns.Add("Bezeichnung", typeof(string));
            m_GefundeneBauteile.Columns.Add("Bauform", typeof(string));
            m_GefundeneBauteile.Columns.Add("Zusatzinformationen", typeof(string));
            m_GefundeneBauteile.Columns.Add("Lagerbestand", typeof(int));
            m_GefundeneBauteile.Columns.Add("Reservierter Bestand", typeof(int));

            //nun eintragen der gefundenen Bauteile
            for (int i = 0; i < m_BauteilListe.Count; i++)
            {
                m_GefundeneBauteile.Rows.Add();
                m_GefundeneBauteile.Rows[m_GefundeneBauteile.Rows.Count - 1]["Index"] = i;  //Hier gibt es nach dem Sortieren die NullReferenceException
                m_GefundeneBauteile.Rows[m_GefundeneBauteile.Rows.Count - 1]["Bezeichnung"] = m_BauteilListe[i].Bezeichnung;
                m_GefundeneBauteile.Rows[m_GefundeneBauteile.Rows.Count - 1]["Bauform"] = m_BauteilListe[i].Bauform.Bezeichnung;
                m_GefundeneBauteile.Rows[m_GefundeneBauteile.Rows.Count - 1]["zusatzinformationen"] = m_BauteilListe[i].Zusatzinformationen;
                m_GefundeneBauteile.Rows[m_GefundeneBauteile.Rows.Count - 1]["Lagerbestand"] = m_BauteilListe[i].GetGesamtLagerMenge();
                m_GefundeneBauteile.Rows[m_GefundeneBauteile.Rows.Count - 1]["Reservierter Bestand"] = m_BauteilListe[i].GetGesamtSperrmenge();
            }
        }

B
357 Beiträge seit 2010
vor 11 Jahren

Ich glaube, die NullReferenceException tritt dort auf, weil du keine wirkliche Zeile an das DataTable hängst. Schon mal probiert via DataRow row = DataTable.NewRow() zu arbeiten? Diese Row befüllst du dann mit deinen Werten und hängst sie mit DataTable.Rows.Add(DataRow) an die Table an. So versuchst du auf ein Objet zuzugreifen, das nicht erzeugt wurde.

K
Kelmoir Themenstarter:in
6 Beiträge seit 2011
vor 11 Jahren

Mit m_GefundeneBauteile.Rows.Add(); wird automatisch eine neue Zeile generiert, und angehängt.

Habe dennoch mal den Code entsprechend umgestaltet, sieht auch besser aus.
Brachte nur leider keine Besserung, nach sortieren des anzeigenden DataGridViews gibt es wieder eine Exception, nur an anderer Stelle.
Wenn der Nutzer nicht neu sortiert, gibt es keine Fehler. Auch das Wiederbefüllen funktioniert noch immer problemlos.
Es würde mir daher auch bereits reichen, die Sortierung komplett zu verbieten/rückgängig zu machen.
Wobei ich dem Rückgängig machen/einfach zum Funktionieren bringen hier den Vorzug geben würde.


        void dgGefunden_WerteEintragen()
        {
            m_GefundeneBauteile.Rows.Clear();
            m_GefundeneBauteile.Columns.Clear();
            m_GefundeneBauteile.Columns.Add("Index", typeof(int));
            m_GefundeneBauteile.Columns.Add("Bezeichnung", typeof(string));
            m_GefundeneBauteile.Columns.Add("Bauform", typeof(string));
            m_GefundeneBauteile.Columns.Add("Zusatzinformationen", typeof(string));
            m_GefundeneBauteile.Columns.Add("Lagerbestand", typeof(int));
            m_GefundeneBauteile.Columns.Add("Reservierter Bestand", typeof(int));

            //nun eintragen der gefundenen Bauteile
            for (int i = 0; i < m_BauteilListe.Count; i++)
            {
                DataRow NeueZeile = m_GefundeneBauteile.NewRow();
                NeueZeile["Index"] = i;
                NeueZeile["Bezeichnung"] = m_BauteilListe[i].Bezeichnung;
                NeueZeile["Bauform"] = m_BauteilListe[i].Bauform.Bezeichnung;
                NeueZeile["zusatzinformationen"] = m_BauteilListe[i].Zusatzinformationen;
                NeueZeile["Lagerbestand"] = m_BauteilListe[i].GetGesamtLagerMenge();
                NeueZeile["Reservierter Bestand"] = m_BauteilListe[i].GetGesamtSperrmenge();
                m_GefundeneBauteile.Rows.Add(NeueZeile);   //Nun tritt die NullReferenceException hier auf
            }
        }

B
357 Beiträge seit 2010
vor 11 Jahren

Verstehe ich das richtig, dass du das Table neu füllst, sobald ein Benutzer im GridView sortiert? Das kann ich nicht ganz nachvollziehen.

K
Kelmoir Themenstarter:in
6 Beiträge seit 2011
vor 11 Jahren

Nein, wenn der Nutzer das DataGridView sortiert, wird die DataTable nicht neu gefüllt.
Mit dem Sortieren habe ich auch nichts zu tun, muss bloss die richtige Zeile finden, was aber kein Problem mehr ist.

Erst wenn eine neue Suche ausgeführt wurde, so dass der alter Inhalt nicht mehr aktuell ist, und daher Aktualisiert werden muss.
Der Fehler tritt nur auf, wenn der Nutzer zwischenzeitlich durch klick auf den Spaltenkopf sortiert hatte. Daher der Verweis auf das Sortieren.

49.485 Beiträge seit 2005
vor 11 Jahren

Hallo Kelmoir,

grundsätzlich sollte sich eine NullReferenceException mit [FAQ] NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt leicht finden und beheben lassen. Du hast zwar die Zeile genannt, aber nicht welche Variable oder Property denn nun tatsächlich null ist. Wenn du das erstmal weiß, sollte eine Fehlerbehebung nicht schwer sein.

Sind Threads im Spiel? Auf gebundene Daten darf nur aus dem GUI-Thread zugegriffen werden, siehe [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke).

herbivore

K
Kelmoir Themenstarter:in
6 Beiträge seit 2011
vor 11 Jahren

Hallo Herbivore,

Den Stacktrace hatte ich mir auch schon angeschaut, aber es wird nicht unmittelbar in meinem Code die Exception geworfen, sondern im Code des Frameworks (.NET 3.5).
Mehrere Threads sind auch nicht involviert.
Der Code funktioniert, wenn der Nutzer vorher das DataGridView nicht selber sortiert hat.
Wenn ich mir den Stacktrace (der Interressante Teil ist angehängt) so anschaue, scheint die Exception zu kommen, weil er versucht, den neuen Eintrag mit einem weiteren (nicht existenten) Eintrag zu vergleichen zwecks Sortieren.
Tritt aber auch auf, wenn ich testweise mittels m_Gefunden.Rows.Add() eine neue, leere Zeile anlege.

Lösung:
ich musste die DataTable neu Instanziieren (Zeilen und Spalten löschen war offenbar nicht gut genug) und diese den DataGridView neu als DataSource (nicht bindingSource, mein Fehler) zuweisen.
Offenbar wurde etwas des Sortiervorganges in die DataTable übernommen.

Danke für die Hilfe,
Kelmoir

Fehlermeldung:
Source="System.Data"
StackTrace:
bei System.Data.Index.CompareRecords(Int32 record1, Int32 record2)
bei System.Data.Index.IndexTree.CompareNode(Int32 record1, Int32 record2)
bei System.Data.RBTree1.RBInsert(Int32 root_id, Int32 x_id, Int32 mainTreeNodeID, Int32 position, Boolean append) bei System.Data.RBTree1.InsertAt(Int32 position, K item, Boolean append)
bei System.Data.Index.InsertRecord(Int32 record, Boolean fireEvent)
bei System.Data.Index.ApplyChangeAction(Int32 record, Int32 action, Int32 changeRecord)
bei System.Data.DataTable.RecordStateChanged(Int32 record1, DataViewRowState oldState1, DataViewRowState newState1, Int32 record2, DataViewRowState oldState2, DataViewRowState newState2)
bei System.Data.DataTable.SetNewRecordWorker(DataRow row, Int32 proposedRecord, DataRowAction action, Boolean isInMerge, Int32 position, Boolean fireEvent, Exception& deferredException)
bei System.Data.DataTable.InsertRow(DataRow row, Int64 proposedID, Int32 pos, Boolean fireEvent)
bei System.Data.DataRowCollection.Add(DataRow row)
bei Bauteil_Datenbank_Frontend.Form1.dgGefunden_WerteEintragen()....

49.485 Beiträge seit 2005
vor 11 Jahren

Hallo Kelmoir,

an sich fällt eine NullReferenceException immer unter [Hinweis] Wie poste ich richtig? Punkt 1.1.1 und 1.1. So wie es aussieht, scheint mir das aber hier ein spezielles Problem der DataTable zu sein. Deine Lösung scheint mir noch nicht an die Wurzel zu gehen, sondern eher ein Workaround zu sein. Ich habe den Thread nach Datentechnologie verschoben.

herbivore