geänderte Zeilen im DataGridView bestimmen
-
Donnerstag, 26. Juli 2012 09:59
Guten Tag,
gibt es eine einfache Möglichkeit, geänderte Zeilen in einem DGV zu ermitteln ?
also etwa so:
Durchlaufe DGV --> if(Row[i] Hat sich geändert) --> i in eine List<> speichern.
Ich verwende vs2010 c# mit typisierten DataSets und Designer.
Ich lasse bei mir die geänderten Zeilen farbig markieren und auch bereits in eine list<> einfügen. denn die list<> brauche ich für das Logging und für den Fall, dass das Speichern nicht funktioniert hat (dabei soll der alte inhalt in die Zwischenablage kopiert , das DataSet aktualisiert, die Daten aus der Zwischenablage ins DGV und schließlich gespeichert werden).
theoretisch funktioniert das auch, aber sobald im DGV sortiert wird, verschwinden die markierten Zeilen und die Werte in der List<> sind logischerweise nicht mehr zu gebrauchen.
wenn es eine simple Möglichkeit gäbe, im Schnelldurchlauf einen Status abzufragen, welche Zeile sich geändert hat, so könnte ich die List<> nach einer Sortierung wieder brauchbar machen.
Ansonsten müsste ich die Primärschlüsselwerte aus der Tabelle in die List<> speichern , allerdings könnte ich mir vorstellen, dass der Aufwand, die geändeten Zeilen daraus zu bestimmen sehr groß sein wird.
Ich bitte um Hilfe oder Tipps
Vielen Dank im Voraus
gruß Felix
Alle Antworten
-
Donnerstag, 26. Juli 2012 15:16
Hallo Felix,
was speicherst du denn in deiner generischen Liste? Wenn du die DataGridViewCells selbst speichern würdest, könntest du mittels der Properties "ColumnIndex" bzw. "RowIndex" die Position der Zelle im DataGridView abfragen.
Ich hoffe das hilft dir weiter, ansonsten darfst du natürlich sehr gerne nachfragen... ;-)
Viele Grüße Holger M. Rößler
- Bearbeitet Holger M. Rößler Donnerstag, 26. Juli 2012 15:18
-
Donnerstag, 26. Juli 2012 15:51
Hallo Holger,
vielen dank für deine Antwort. Deinen Vorschlag werde ich morgen gleich mal testen. Ich versuchs mal, noch etwas deutlicher zu beschreiben.
ich habe auf meiner Form ein DataGridview mit den Spalten A,B,C,D - dabei ist A vom Typ Integer und entählt die Primärschlüssel.
Ein Benutzer ändert nun eine oder mehrere Zeilen. Diese müssen nicht einmal zusammenhängend sein, also z.B. Zeile 1,2,4,7.
Die geänderten Zeilen werden gelb markiert. Dies geschieht über das Event CEllEndEdit. Soweit sogut.
Wenn er nun speichert und es kommt z.B. zu einer Parallelitätsverletzung, kann der Benutzer aus 3 Aktionen auswählen:
1) Änderungen verwerfen und Datenbank neu laden
2) Änderungen in Zwischenablage kopieren und Datenbank neu laden
3) wie 2, nur dass zusätzlich die Daten aus der Zwischenablage in das DGV kopiert werden und ein weiterer Speicherversuch erfolgt.
Nach meinen Überlegungen brauche ich somit für 2) und 3) eine Auflistung, welche Zeilen geändert wurden. Dazu habe ich
private static List<Int32> ListeChangedRows = new List<Int32>(); welche mir die DVG.RowIndex (also die Zeilennummer im DGV) speichert
und dann habe ich noch
private static List<Int32> ListeChangedID= new List<Int32>(); welche mir die IDs (Primärschlüssel) der veränderten Zeilen speichert.
Die IDs brauche ich, da ich diese Werte in eine Logging-Tabelle speichern will, sobald der Benutzer auf Speichern klickt.
Ich habe noch nicht alles implementiert, aber bisher läufts nach meiner Vorstellung. Allerdings kann ich das Vorhaben vergessen, wenn der Benutzer im DGV die Daten sortiert. Denn dann verschwinden die gefärbten Zeilen und die Zeilennummern aus ListeChangedRows stimmen nicht mehr mit denen im DGV überein.
Meine Notlösung sieht bisher vor, dass ich bei dem Sort-Event eine Funktion aufrufe, die die ListeChangedRows aktualisiert. Dazu gehe ich die IDs in ListeChangedID durch und schaue in einer for-schleife, in welcher Zeile im DGV diese ist und speichere die betreffende Zeilennummer in ListeChangedRows.
Das ist mein Ansatz und ist noch nicht fertig geschweige getestet. Diese Lösung ist sicherlich nicht optimal, denn das DGV wird sooft durchgegangen , wie Elemente in der Liste sind. Daher dachte ich, es wäre doch wesentlich besser, wenn man das DGV nur einmal durchgeht und die geänderten Zeilen ausfindig macht.
gruß
Felix
-
Freitag, 27. Juli 2012 08:25
Hallo Holger,
ich habe deinen Tipp jetzt mal ausprobiert.
Dazu habe ich in einem Beispiel im Designer ein DGV mit Ihnalt erstellen lassen und habe eine generische Liste erstellt:
private static List<DataGridViewCell> ListeCell = new List<DataGridViewCell>();
ein Button1 ermittelt die markierte Zelle und fügt sie in die ListeCell ein:
DataGridViewCell Cell; Cell = myTabelleDataGridView[myTabelleDataGridView.CurrentCell.ColumnIndex, myTabelleDataGridView.CurrentCell.RowIndex]; ListeCell.Add(Cell);
ein weiterer Button gibt die ListeCell aus
string s = ""; foreach(DataGridViewCell C in ListeCell) { string b = "Zeile: " + C.RowIndex.toString() + " Spalte: " + C.ColumnIndex.toString() + "\n"; s = s + b; } MessageBOx.Show(s);
sobald ich aber hier sortiere und dann die ListeCell ausgebe, erhalte ich unbrauchbare werte wie "-1" , "1". (zumindest die Spalten stimmen)
Hat ein DataGridView vlt. nicht irgendwie eine interne zugeordnete ID für jede Zeile oder Zelle, die sich beim sortieren mitverändert ?
Gruß
Felix- Bearbeitet Felix86 Freitag, 27. Juli 2012 08:27
-
Freitag, 27. Juli 2012 19:07Beantworter
Hallo Felix,
wenn Du wie in der Frage geschrieben mit typisierten DataSets arbeitest, so ist der Aufwand überhaupt nicht notwendig.
Die DataTable verwaltet intern die originalen Zustände von veränderten Zeilen.
Und über eine DataView kannst Du mit der RowStateFilter-Eigenschaft veränderte, neue und/oder gelöschte Zeilen ermitteln.Um den Status zu sichern kannst Du den TableAdapterManager verwenden, der eine Sicherung vornehmen kann;
zudem gewährleistet er die richtige Aktualisierungsreihenfolge über mehrere Tabellen.Gruß Elmar
-
Montag, 30. Juli 2012 09:13
Hallo Elmar,
danke für den Tipp. Allerdings benutze ich DataGridViews, und bei denen gibst es nur Rowstatechanged.
-
Montag, 30. Juli 2012 09:13
Hallo Elmar,
danke für den Tipp. Allerdings benutze ich DataGridViews, und bei denen gibst es nur Rowstatechanged.
-
Montag, 30. Juli 2012 10:38Beantworter
Hallo Felix,
wenn Du mit Datenbindung arbeitest, ist es egal welches Steuerelement die Daten darstellt.
Und somit spielt es hier keine Rolle und jeder Zugriff über Steuerelemente ist dabei sogar zu meiden.Gruß Elmar
-
Montag, 30. Juli 2012 12:20
Hallo Elmar,
auf welches objekt soll ich dann zugreifen ? der bindingsource ? oder die datatable ?
tut mir leid, aber ich stehe gerade auf dem schlauch.
-
Montag, 30. Juli 2012 15:51Beantworter
Hallo,
wenn Dein DatagridView an eine BindingSource gebunden ist - die ihrerseits auf eine DataTable als Datenquelle hat,
so wäre der vorgesehene Weg der über die BindingSource.
Zunächst solltest Du Dir das Zusammenspiel verdeutlichen, beschrieben u. a. in Architektur der BindingSource-Komponente
(und das Durcharbeiten einiger der Beispiele dort kann auch nicht schaden).Über die List-Eigenschaft bekommst Du bei einer DataTable die gebundene DataView -
und kannst dann die Zeilen je nach Wunsch durchlaufen, überprüfen usw.
Was jetzt im einzelnen bei Dir passieren soll, wäre noch zu klären,
alles was oben angedeutet wurde, ist so zumindest nicht notwendig.Gruß Elmar
- Als Antwort markiert Robert BreitenhoferMicrosoft Contingent Staff, Moderator Montag, 20. August 2012 14:22
-
Montag, 20. August 2012 14:22Besitzer
Hallo Felix86,
Ich gehe davon aus, dass die Antwort Dir weitergeholfen hat.
Solltest Du noch "Rückfragen" dazu haben, so gib uns bitte Bescheid.Grüße,
RobertRobert Breitenhofer, MICROSOFT

Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „Entwickler helfen Entwickler“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

