Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Fehler beim Schreiben ins ToolStripStastusLabel
MoaByter
myCSharp.de - Member



Dabei seit:
Beiträge: 29
Herkunft: Berlin

Themenstarter:

Fehler beim Schreiben ins ToolStripStastusLabel

beantworten | zitieren | melden

Hallo,

ich habe in meiner Anwendung - erstellt mit VS2017 - ein ToolStripStatusLabel, das mit einem Text vorbelegt ist: "-". In dieses Label werden im Verlauf die Koordinaten der CurrentCell einer Tabelle eingetragen, das ging über 7 Jahre auch ohne Probleme. Ich habe jetzt einige Variablennamen global geändert ... und schon gibt's Ärger.



		/// <summary>
		/// Setzt System-Variablen und Statusanzeige auf die Adresse der aktiven Zelle
		/// </summary>
		/// <date>210406-2330</date>
		void SetStatusLabel()                                               // Anzeige der Statusleiste setzen
		{
			DataGridView dgv = a_Dgv[aSTab];							    // a_Dgv: DGV-Array
			DataGridViewCell dgvc = dgv.CurrentCell;						// dgvc: DGV-Zelle CurrentCell

			actCol[aSTab] = actC = dgvc.ColumnIndex;						// aktuelle CurrentColumn
			tsslColValue.Text = actC + 1 + "/" + dgv.ColumnCount;			// ToolStripStatusLabel: Text eintragen -> FEHLER!

			actRow[aSTab] = actR = dgvc.RowIndex;						    // aktuelle CurrentRow
			tsslRowValue.Text = actR + 1 + "/" + dgv.RowCount;				// ToolStripStatusLabel: Text eintragen -> FEHLER!

			if (dgvc != null && dgvc.Value != null)							// wenn CurrentCell und CC-Value != null...
				tsslWertValue.Text = (dgvc.Value + "").Replace("&", "&&");  // Ampersand im Text ersetzen
			ststMid.Refresh();											    // Aktualisieren
		}

Die Variablen stimmen alle, die Werte sind: dgvc != null, aSTab = 4, dgv.ColumnCount = 6, .RowCount = 1. Die Struktur, der Aufbau, ist über all die Jahre gleich geblieben - was sollte ich auch ändern? Das Verrückte: Manchmal funktioniert's, allerdings nur beim Debugging.

Folgende Fehlermerldung:
Fehler
StackTrace:
System.Reflection.TargetInvocationException: Ein Aufrufziel hat einen Ausnahmefehler verursacht. ---> System.NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
bei trotto.Trotto.SetStatusLabel() in ...\Trotto.cs:Zeile 769. (Das ist die erste tssl-Zeile, 11)

Nur ist da nix null. Das einzige, das null sein könnte, ist dgv.ColCount und .RowCount, die sind aber klar definiert != null: Wert = 6 bzw. 1.
In Zeile 11 bzw. 14 (tssl) springt der Debugger dann in den Disassembler. Siehe Anhang.

Was also ist da los? Was übersehe ich? Es hatte doch funktioniert, warum jetzt nicht mehr?

Ich habe die Screenshots vom Disassembler und der Aufrufliste angehängt.
Dieser Beitrag wurde 4 mal editiert, zum letzten Mal von MoaByter am .
Attachments
private Nachricht | Beiträge des Benutzers
hypersurf
myCSharp.de - Member



Dabei seit:
Beiträge: 509
Herkunft: Münster

beantworten | zitieren | melden

Irgendwas wird wohl null sein, sonst würd's keine NullReferenceException geben.
Wenn die Exception erst in Zeile 11 geworfen wird, würde ich schätzen, dass tsslColValue null ist.
private Nachricht | Beiträge des Benutzers
Stefan.Haegele
myCSharp.de - Member

Avatar #avatar-3068.jpg


Dabei seit:
Beiträge: 436
Herkunft: Untermeitingen

beantworten | zitieren | melden

Wo wird das Control tsslColValue denn erzeugt? Bist du wirklich sicher, dass es nicht null ist?
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15618
Herkunft: BW

beantworten | zitieren | melden

Du holst Dir Controls


	DataGridView dgv = a_Dgv[aSTab];
	DataGridViewCell dgvc = dgv.CurrentCell;

Greifst dann auf die Controls zu -> Du gehst also davon aus, dass sie existieren und nicht null sind.


actCol[aSTab] = actC = dgvc.ColumnIndex;

5 Zeilen später denkst Dir: oh, sie können evtl. doch null sein, und prüfst es


if (dgvc != null && dgvc.Value != null)	

Du musst immer im Endeffekt, um sicher zu gehen, jedes Element auf null prüfen, bevor Du drauf zugreifst; ansonsten bekommst Du genau die Fehlermeldung, die Du erhälst, wenn es nicht so ist:
Fehler
System.NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
Es macht jedoch niemals sinn blind auf ein Element zuzugreifen, und es danach auf Null zu prüfen.
Entsprechende Warnings bekommst Du bei solchen Strukturen auch von Visual Studio, wenn Du es nicht deaktiviert hast.

Siehe auch [FAQ] NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt

Seit C# 9 gibts aber die Nullable Reference Types, sodass Du von der IDE bzw. genauer gesagt vom Compiler eine Unterstützung erhälst, was Du auf Null prüfen musst, und was nicht.
Nullable reference types - specification - C# 9.0 specification proposals



private Nachricht | Beiträge des Benutzers
MoaByter
myCSharp.de - Member



Dabei seit:
Beiträge: 29
Herkunft: Berlin

Themenstarter:

beantworten | zitieren | melden

Danke für eure Antworten!

Also: Ich habe geschlampt, ich hab' 'nen Fehler gemacht - wobei das Schlampen auch schon 'n Fehler ist - und eine Frage ist noch offen.

@hypersurf: Das irritierte mich eben an der Sache.
@Stefan.Haegele: Deswegen schrieb ich 'VS2017':. Alle Controls werden im Designer erzeugt, sind also != null. War zu knapp erklärt, Scusi.
@Abt - und auch die beiden anderen:
ich sollte einfach nicht mehr um 2 Uhr morgens programmieren...

Die Elemente im DGV[] a_dgv können nicht null sein, es wird als erstes im Form_Load-Event erstellt.
Beim Debuggen war CurrentCell nicht null und trotzdem wurde der Disassambler in Zeile 11 aufgerufen, auch wenn ich statt dgvc.CulumnIndex eine Integer eingesetzte. Warum das? Das ist die offene Frage.
Mein Fehler lag allerdings in der - neuen - Klasse, die die DGVs mit Daten füllt. Es gibt 5 DGVs, das sechste hatte ich per Code ausgeklammert, wg. eines Tippfehlers wurde das aber doch wieder bearbeitet (for-Schleife). Das habe ich übersehen.
Und die Schlampigkeit, dgvc nicht auf null zu prüfen ... Früher war's nicht nötig, es war nie null. Der Code stammt aus meinen Anfangszeiten, als ich gerade C# lernte. Ein schlechte Entschuldigung.
Jetzt - mit Null-Prüfung - nötig, da die Zeilen der DGVs mit dgv.Rows.Clear() gelöscht werden, funktioniert's tadellos.
Die Prüfung am Schluss bezieht sich eigentlich nur auf 'Value', das 'dgvc != null' stand nur zur Vervollständigung drin. Der 'Value != null'-Test war entscheidend.

Ich hab's jetzt also geändert:

actCol[aSTab] = actC = dgvc == null ? -1 : dgvc.ColumnIndex;	// aktuelle CurrentColumn oder -1
tsslColValue.Text = actC + 1 + "/" + dgv.ColumnCount;			// ToolStripStatusLabel: Text eintragen
(dto. für .RowIndex), alles andere bleibt so. Ich brauche in actCol[]/actRow[] einen verwertbaren Wert, deswegen so.

Fehler
Also bleibt nur noch die Frage, warum beim Debuggen der Disassembler aufgerufen wird, das verstehe ich nicht.

Wie gesagt, beim Normalbetrieb stört's nicht, mich hat's gestern/heute-morgen nur völlig iriitiert, weswegen ich den Ablauf gar nicht erst getestet hatte.

Mit dem nullable-System beschäftige ich mich gerade, hatte es bisher nur teilweise verwendet (string s = dgv[x,y].Value? "abc"; )

Danke nochmals, viele Grüße, bleibt gesund - ...lypô

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von MoaByter am .
private Nachricht | Beiträge des Benutzers