Entwickler-Ecke
WinForms - IsCurrentRowDirty wieder auf false setzen
bamba - Di 25.03.14 21:27
Titel: IsCurrentRowDirty wieder auf false setzen
Hallo zusammen :)
ich versuche von meinem Datagridview die Eigenschaft "IsCurrentRowDirty" auf false zu setzen.
Soweit ich das verstehe, ist es true, solange der Stift im RowHeader bei diese Zeile navigiert ist.
Ich habe es schon versucht mit
oder
Hintergrund:
1. Ich schreibe was in eine Zelle rein
Dann nach bestimmten Eingaben:
2. Ich möchte meinen vorhandenen Grid löschen und neu erstellen:
C#-Quelltext
1:
| this.gp.Controls.RemoveAt(0); |
Zitat: |
InvalidOperationException
{"Der Vorgang kann in diesem Ereignishandler nicht durchgeführt werden."}
|
Weiss jemand einen Rat???
Danke
Moderiert von
Th69: C#-Tags hinzugefügt
Moderiert von
Th69: B- durch C#-Tags ersetzt
Moderiert von
Th69: U- durch Quote-Tags ersetzt
Ralf Jansen - Di 25.03.14 23:43
Zitat: |
ich versuche von meinem Datagridview die Eigenschaft "IsCurrentRowDirty" auf false zu setzen. |
Das ist eine reine Leseproperty die du von außen nicht ändern kannst. Warum würde man das auch tun wollen?
Zitat: |
Soweit ich das verstehe, ist es true, solange der Stift im RowHeader bei diese Zeile navigiert ist. |
Klingt grauenhaft. Du solltest lieber die englisch Hilfe lesen und nicht die maschinell ins deutsche übersetzte ;)
Zitat: |
this.gp.Controls.RemoveAt(0); //Hier wirft er mir die Exception:
InvalidOperationException |
Von wo rufst du den Code auf? Aus einem Event des Grids? Das ist ist vermutlich keine Gute Idee und erinnert mich an die Münchhausen Geschichte vom am eigene Schopf aus dem Sumpf ziehen.
Prinzipiell ist das löschen und neuerstellen von Controls kritisch und sollte man nicht ohne wirklich guten Grund machen. Was wäre dein Grund?
bamba - Mi 02.04.14 00:06
Ralf Jansen hat folgendes geschrieben: |
Von wo rufst du den Code auf? Aus einem Event des Grids? Das ist ist vermutlich keine Gute Idee und erinnert mich an die Münchhausen Geschichte vom am eigene Schopf aus dem Sumpf ziehen. |
Also der Aufrufstack ist:
3. PrivateMethode
wo der Fehler passiert
2.weitere PrivateMethode
1.RowLeave-Ereignis vom Grid
Wenn ich in der 3 sage, lösche mir das vorhandene Grid von der Oberfläche und generiere das neu, weil sich die Daten zwischenzeitlich geändert haben:
C#-Quelltext
1:
| this.gpContentLicence.Controls.RemoveAt(0); |
dann geht er anschließend wieder ins RowLeave und sieht, dass "IsCurrentRowDirty" true ist und ruft wieder die 3 auf^^ also eine undliche Schleife....
Deswegen meine ich....ich muss
IsCurrentRowDirty irgendwie auf "false" bekommen....
oder welche Ansätze gibts da noch???
Vielen Dank.
Moderiert von
Th69: Quote-Tag hinzugefügt.
Moderiert von
Th69: C#-Tags hinzugefügt
Th69 - Mi 02.04.14 09:50
Hallo bamba,
du solltest nicht das Grid neu erstellen, sondern nur die Daten aktualisieren (d.h. am besten gleich per DataBinding).
bamba - Mi 02.04.14 10:11
Ich mache Databinding über nen DataTable, ist das ok??
Soll ich dann einfach dem vorhandenen Grid neue Datensource zuweisen?
Th69 - Mi 02.04.14 10:28
Hallo,
bei DataBinding braucht man eigentlich gar nichts mehr selber tun, da die Controls sich dann automatisch selber aktualisieren, sobald sich die DataSource (in deinem Fall DataTable) ändert.
Ralf Jansen - Mi 02.04.14 10:32
Ja. Das ist definitiv besser.
Klingt aber immer nochmerkwürdig aus einem Grid Event insbesondere sowas wie RowLeave gleich die Datenmenge auszutauschen und ich würde immer noch mit Problemen rechnen.
Datenmenge austauschen ist ein eventauslösendes Ereignis und du bist gerade in einem Event. Nebenbei änderst du die Grundlage die dieses Ereignis ausgelöst hat. Nach dem RowLeave will das Grid selbst möglicherweise noch irgendwas an der Row oder der vor dem Event ermittelten neuen ZielRow anstellen die existieren aber nicht mehr.
Wenn du uns erklärst was du tatsächlich erreichen willst fällt uns vermutlich was geeigneteres ein.
bamba - Mo 07.04.14 09:51
Danke schön :)
Das konkrete Problem ist:
1. Ich klicke in die Zelle
2. Ändere was
3. Programm sagt mir, dass die Daten inkonsistent sind.
4. Ich will dann mir die aktuellsten Daten holen.
Die Speicherroutine wird von dem RowLeave-Ereignis aufgerufen, weil ich jeweils speichere, wenn ich in einer andere Zeile gehe.
bamba - Mi 16.04.14 00:24
also beim Erstellen des Grids benutze ich globales DataTable, welches ich zuerst befülle und dann das dem Grid zuweise.
Nun führe ich einfach die Abfrage erneut aus und speichere es in dem globalen DataTable, in diesem Moment hab ich erwartet, dass
das Grid das sofort mitbekommt, sobald ich das Ergebnis dem DataTable zuweise...leider ändern sich die Daten nicht an der Oberfläche....
muss ich da erneut das geupdatete DataTable dem der Grid.DataSource zuweisen?
Moderiert von
Th69: Beiträge zusammengefasst
weil das Grid wird temporär erzeugt und ich kann nicht so einfach auf die "DataSource" zugreifen:
C#-Quelltext
1:
| grupBox1.Controls[0].DataBindings[0].DataSource = updatedTable; |
geht nicht, denn die Eigenschaft "DataSource" ist aufeinmal schreibgeschützt....was muss man da machen??
Danke für jeden Tipp.
Moderiert von
Th69: Quote- durch C#-Tags ersetzt
Ralf Jansen - Mi 16.04.14 09:31
Wenn du dem DataTable etwas hinzufügst bekommt das Grid das sofort mit. Eigentlich muß man da also nix extra machen.
Zitat: |
Nun führe ich einfach die Abfrage erneut aus und speichere es in dem globalen DataTable, |
Zeig uns das doch mal den speichern in globale DataTable Teil. So wie du das wiedergibst wäre eine Vermutung das du die DataTable nicht weiterverwendest sondern durch eine neue ersetzt und somit das Grid weiterhin auf die vorhergehende schaut.
bamba - Mi 16.04.14 15:15
klar kann ich machen :)
also das ist die Oberflächenklasse:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41:
| namespace meinProgramm { public partial class frmForm: Form { private DataTable meinDataTable; public DataGridView createGrid(string GridName) {
meinGrid= new System.Windows.Forms.DataGridView(); meinDataTable= controller.retrieve(seriennr); meinGrid.DataSource = tableSourceForLicencemenu; return meinGrid; }
private void grid_KeyDown(object sender, KeyEventArgs e) {
updateDataTable() }
private void grid_CellClick(object sender, DataGridViewCellEventArgs e) { meinGroupBox.Controls.Add(createGrid("test"));
}
updateDataTable(){ meinDataTable= controller.retrieve(seriennr); } } |
Ist das so korrekt??? also mit der Absicht, dass auf eine Benutzeriteration das Grid sich selbst aktualisiert.
Ralf Jansen - Mi 16.04.14 16:15
updateDataTable ändert die Variable meinDataTable mit einer neuen DataTable die er von deiner Controller Klasse geholt hat.
Wenn du zu einem früheren Zeitpunkt dem Grid eine andere DataTable über diese Variable zugeordnet hast zeigt ab dann die Variable und das Grid auf die selbe DataTable.
Wenn du nun denn Verweis der Variablen änderst wieso sollte sich das Grid mit ändern? Grid.DataSource weiß nichts davon das es mal über diese Variable an die DataTable Instanz gebunden wurde und wird weiter auf die DataTable schauen die du im mal früher zugewiesen hast.
Oder in Code vielleicht einfacher zu verstehen. Wenn dt2 ein neue DataTable zugewiesen bekommt bekommt das dt1 natürlich nicht mit. Sie wird weiter auf die auf sie einmal zugewiesene DataTable schauen.
C#-Quelltext
1: 2: 3:
| DataTable dt2 = new DataTable(); DataTable dt1 = dt2; DataTable dt2 = new DataTable(); |
Wenn du eine neue Instanz hast mußt du die auch neu ans Grid binden.
Und wenn du nicht gerade beliebig viele Grids auf deiner Form stapeln willst dann erzeuge nicht das Grid neu!
bamba - Fr 18.04.14 12:00
Danke für die Antwort.
ich hoffe, ich habe dich verstanden....
Also ich hab mir einfach gedacht, dass ich ein globales DataTable habe.
Und aus verschiedenen Methoden aktuallisiere ich ihn, in dem ich was von der ControllerKlasse hole...
Zitat: |
Wenn du eine neue Instanz hast mußt du die auch neu ans Grid binden. |
Ja...und das habe ich versucht zu tun:
C#-Quelltext
1:
| GroupBox.Controls[0].DataBindings[0].DataSource = meinDataTable |
Aber die "DataSource" ist nun aufeinmal schreibgeschützt..... :(
C#-Quelltext
1: 2: 3: 4:
| private void updateDataTable(){ meinDataTable= controller.retrieve(seriennr); } |
die "meinDataTable" ist ja eine globale Variable...
Am Anfang setze ich sie in der Methode A.
Dann später möchte ich sie aus der Methode B eben erneuern, und das Grid sollte das ja eigentlich sofort mitbekommen.
Oder verstehe ich da was falsch.....
Ralf Jansen - Fr 18.04.14 14:52
Zitat: |
die "meinDataTable" ist ja eine globale Variable... |
Es ist eine private Klassenvariable. Der Begriff global macht in einem objektorientierten System wenig Sinn.
Zitat: |
GroupBox.Controls[0].DataBindings[0].DataSource = meinDataTable |
Du willst scheinbar das Binding ändern und die DataSource eines Binding war und ist immer einer reine Leseproperty. Binding ändern hieße üblicherweise ein neues Binding erzeugen.
Aber das macht man eigentlich nicht. Genauso wenig wie Controls neu erzeugen.
Zitat: |
Dann später möchte ich sie aus der Methode B eben erneuern, und das Grid sollte das ja eigentlich sofort mitbekommen. |
Mitbekommen kann das Grid nur Dinge die an dem Object passieren auf das Grid.DataSource schaut. Wenn zu irgendeinem Zeitpunkt meinDataTable und Grid.DataSource auf die gleich DataTable schauen kannst du den Inhalt der DataTable über meinDataTable ändern und das Grid wird diese Änderungen anzeigen. Das hier
C#-Quelltext
1:
| meinDataTable= controller.retrieve(seriennr); |
ändert aber nicht den Inhalt des Objects das an meinDataTable hängt sondern läßt meinDataTable auf eine andere DataTable schauen. Wenn du jetzt was an der DataTable in meinDataTable änderst wird das keine Auswirkungen auf das Grid haben denn das Grid arbeitet ja mit einer anderen DataTable eben das von dem du zu einen früherem Zeitpunkt gesagt hast "Bitte liebes Grid arbeite mit dieser DataTable".
bamba - Fr 18.04.14 16:32
Zitat: |
Das hier
C#-Quelltext 1:
| meinDataTable= controller.retrieve(seriennr); |
ändert aber nicht den Inhalt des Objects das an meinDataTable hängt sondern läßt meinDataTable auf eine andere DataTable schauen. Wenn du jetzt was an der DataTable in meinDataTable änderst wird das keine Auswirkungen auf das Grid haben denn das Grid arbeitet ja mit einer anderen DataTable eben das von dem du zu einen früherem Zeitpunkt gesagt hast "Bitte liebes Grid arbeite mit dieser DataTable". |
Und das ist eben das Problem, dass ich einfach ein anderes DataTable erzeuge mit der obigen Zeile code und überschreibe somit nicht das ursprüngliche DataTable.
Aber wie kann ich den das ursprüngliche DataTable mit dem neuen Inhalt aus der Datenbank überschreiben bzw. füllen bzw. aktuallisieren?
Ralf Jansen - Fr 18.04.14 17:45
Folge dem Link. Ich sehe aber auch kein Problem darin wenn du eine neue DataTable holst die neu ans Grid zu binden. Warum willst du das nicht?
bamba - Fr 18.04.14 17:58
Zitat: |
Ich sehe aber auch kein Problem darin wenn du eine neue DataTable holst die neu ans Grid zu binden. Warum willst du das nicht? |
hehe^^
Das Grid ich ja nicht hin....
ich habe ein anonymes DataGridview, welches ich am Anfang beim Laden auf ein Groupbox binde.....
Nun versuche ich über die Index von "Controls" der Groupbox das angefügte Grid irgendwie anzusprechen:
C#-Quelltext
1: 2:
| meinDataTable = controller.retrive(seriennr); GroupBox.Controls[0].DataBindings[0].DataSource = meinDataTable; |
und das geht eben nicht, weil "DataSource" schreibgeschützt ist.
Wie kann ich das sonst machen??
Ralf Jansen - Fr 18.04.14 18:10
Gib dem Grid einen Namen(jedes Control hat eine Name Property) und suche dann das Grid über den Namen.
C#-Quelltext
1: 2: 3:
| var controls = GroupBox.Controls.Find(meinLieberGridName, true); if ((controls.count > 0) && (controls[0] is DataGridview)) (controls[0] as DataGridview).DataSource = meinDataTable; |
Aber da sind wir dann am nächsten Punkt wovon wir hier die ganze Zeit abraten. Erstell das Grid nicht neu bzw. dynamisch. Wirf es im Designer einfach auf die Form. Dann hast du etwas das du passend einstellen kannst und eine Variable für das Grid über das du einfach die DataSource zuweisen kannst.
bamba - So 20.04.14 18:30
heey, vielen Dank.
Ich hab das implementiert und es auch an anderen Stellen verwendet, was super funtioniert, wofür ich mich herzlich bedanken möchte, nur an dieser Stelle funktioniert es nicht.
Und zwar tritt ein RowLeave-Event auf, worin ich die Speichermethode aufrufe, die mir dann später nen Fehler verursacht.
Diese Speichermethode rufe ich nur auf wenn die Eigenschaft
grid.IsCurrentRowDirty mir true zurück gibt.
Ich möchte sie aber vor dem "RowLeave" auf false setzen.
Dafür hab ich schon "CancelEdit" ausprobiert usw....das bringt alles nichts.
Irgendwie muss der "Stift" auf der linken Seite des Grids verschwinden, sodass diese Zeile nicht im Editiermodus ist...
Wie kriege ich es hin diese Eigenschaft
dgvCurrentDongel.IsCurrentRowDirty wieder auf false zu setzen`????
Danke
Moderiert von
Th69: C#-Tags hinzugefügt
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!