Autor |
Beitrag |
bamba
Hält's aus hier
Beiträge: 13
|
Verfasst: Di 25.03.14 21:27
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
C#-Quelltext
oder
C#-Quelltext
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
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: 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 
Hält's aus hier
Beiträge: 13
|
Verfasst: 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
      

Beiträge: 4798
Erhaltene Danke: 1059
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: 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 
Hält's aus hier
Beiträge: 13
|
Verfasst: 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
      

Beiträge: 4798
Erhaltene Danke: 1059
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: 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
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: 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 
Hält's aus hier
Beiträge: 13
|
Verfasst: 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.
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mo 07.04.14 10:00
Hole dir die eventuell geänderten Daten in eine weiter DataTable und merge die in die gebundene DataTable.
|
|
bamba 
Hält's aus hier
Beiträge: 13
|
Verfasst: 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
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: 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 
Hält's aus hier
Beiträge: 13
|
Verfasst: Mi 16.04.14 15:15
klar kann ich machen
also das ist die Oberflächenklasse:
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
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: 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 
Hält's aus hier
Beiträge: 13
|
Verfasst: 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
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: 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 
Hält's aus hier
Beiträge: 13
|
Verfasst: 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
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Fr 18.04.14 17:45
Ralf Jansen hat folgendes geschrieben : | Hole dir die eventuell geänderten Daten in eine weiter DataTable und merge die in die gebundene DataTable. |
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 
Hält's aus hier
Beiträge: 13
|
Verfasst: 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
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: 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 
Hält's aus hier
Beiträge: 13
|
Verfasst: 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
|
|