Entwickler-Ecke
WinForms - Verbindung zwischen DataSet und DataGridView?
BlackMatrix - Do 22.09.11 22:13
Titel: Verbindung zwischen DataSet und DataGridView?
Hi.
Ich habe mir ein nicht typisiertes DataSet und ein DGV angelegt. DataSource des DGV ist das DataSet mit einer DataTable als Member.
Nun möchte ich gerne, dass sobald der User einen Button oder Ähnliches klickt mit meinen Objekten gearbeitet wird.
Ich gehe mal davon aus, dass nun z.B. das Objekte Erzeugen und die notwendigen Daten für die Objekte aus der DataTable entnommen werden müssen und nicht aus dem DGV, denn wenn sich im DGV z.B. die Anordnung durch den Benutzer ändert, kann z.B. das Durchlaufen aller Reihen zum Fehlverhalten führen.
Daher meine Frage, liege ich richtig, dass man immer mit der dahinterliegenden DataTable arbeiten sollte oder gibt es auch Ausnahmen, wo man mal direkt die Werte aus dem DGV ließt?
Wenn ich nun z.B. eine Zeile im DGV markiert habe, dann muss ich ja immer erst aus der Zeile im DGV (DataGridViewRow) die Zeile in der DataTable (DataRow) ausfindig machen (DataRow.Find()) um mit dieser zu arbeiten? Irgendwie ist das nervtötend :-/
Wenn man das wirklich mit dem Find machen sollte, dann hätte ich dazu eine Frage, wie kann man damit eine Reihe finden, wenn der Primärschlüssel aus 2 Werten besteht?
C#-Quelltext
1: 2: 3: 4: 5: 6: 7:
| private void toolStripMenuItemStart_Click(object sender, EventArgs e) { var muh = dataGridViewData.SelectedRows[0].Cells[0].Value; var maeh = dataGridViewData.SelectedRows[0].Cells[3].Value; var test = dataTableData.Rows.Find(new object[]{muh,maeh}); } |
MfG
mats74 - Fr 23.09.11 07:35
Hallo BlackMatrix
BlackMatrix hat folgendes geschrieben : |
Hi.
Daher meine Frage, liege ich richtig, dass man immer mit der dahinterliegenden DataTable arbeiten sollte oder gibt es auch Ausnahmen, wo man mal direkt die Werte aus dem DGV ließt?
|
Der User in meinen Projekten arbeitet ausschliesslich im Dgv direkt und kann dort beliebige Manipulationen der Daten, Zeilen und Spalten vornehmen. Die geänderten Daten des Dgv's werden dann bei einem beliebigen Prozess in das DataSet (oder SQL-DB Tabelle) gespeichert, indem ich die entsprechenden Zeilen ersetze (löschen / erzeugen anhand einer Kennung). Somit hast Du die maximale Funktionalität des Dgv's zur Verfügung und musst dich während der Bearbeitung nicht um die "gespeicherten Daten" kümmern. Wie Du schon erwähnt hast, wäre dies bei komplexeren Manipulationen ansonsten sehr schwierig umzusetzen.
Da gibt es sicherlich noch andere Meinungen :wink: .
Th69 - Fr 23.09.11 09:47
Hallo BlackMatrix,
über die Eigenschaft DataGridViewRow.DataBoundItem kommst du direkt zu der Row in der DataTable.
Du mußt dann nur entsprechend casten:
C#-Quelltext
1:
| DataRow row = dataGridViewRow.DataBoundItem as DataRow; |
BlackMatrix - Fr 23.09.11 13:31
Hatte schon beim Schreiben meines Beitrages vermutet, dass nicht so ganz ersichtlich ist, was ich möchte.
mats74 hat folgendes geschrieben : |
Hallo BlackMatrix
Der User in meinen Projekten arbeitet ausschliesslich im Dgv direkt und kann dort beliebige Manipulationen der Daten, Zeilen und Spalten vornehmen. |
Ja genau, das tut er bei mir auch, aber ich habe z.B. folgendes Szenario:
Also habe ich in meiner MainForm eine Liste der Daten angelegt:
C#-Quelltext
1:
| private List<Person> Data= new List<Person>(); |
Um dann über die Methoden Start, Stop, usw. mit den Objekten Arbeiten zu können.
Und mir stellt sich die Frage, wie ich denn möglichst effizient, die Datenbindung zwischen der geklickten ToolStripMenuItem (Start, Stop, ...) und dem Objekt mit dieser Methode ohne bei jedem Klick des ToolStripMenuItem erst herausfinden zu müssen, ob sich in der Liste bereits ein Objekt davon befindet, dann erzeugen, ansonsten das richtige Objekt nehmen und die Methode aufrufen.
Ich ahne schon, dass es auf die BindingList hinausläuft, aber irgendwie hat mir die beim letzten Mal nicht zugesagt.
Th69 hat folgendes geschrieben : |
Hallo BlackMatrix,
über die Eigenschaft DataGridViewRow.DataBoundItem kommst du direkt zu der Row in der DataTable.
Du mußt dann nur entsprechend casten:
C#-Quelltext 1:
| DataRow row = dataGridViewRow.DataBoundItem as DataRow; | |
Das ist gut zu wissen :) Danke
mats74 - Fr 23.09.11 14:39
Hallo BlackMatrix
Ich habe deine Ausgangslage nachgebaut und habe bis jetzt auch keine Lösung (Vielleicht habe ich auch dein Problem nicht ganz verstanden :gruebel: ).
Wenn ich dich richtig verstehe, willst Du eine direkte Zuweisung der selektierten Dgv-Zeile zum List-Eintrag oder DataTableRow, den Du dann anhand der Dgv-Einträge editieren willst (ohne irgendwelche Abfragen an die DataTable).
Dazu fällt mir eigentlich nur die Übergabe eines eindeutigen ID-Wertes ein (z.B. 2 Tabellen mit Beziehung), den jeder Eintrag beinhaltet.
Die Editierung der DataTable-Eintrages kannst Du dann mit einer eindeutigen ID bewerkstelligen.
Da entfällt lediglich die Abfrage für die List oder DataTableRow.
BlackMatrix - Fr 23.09.11 15:49
Ich will die verschiedenen Methoden der Objekte Person mit dem ToolStripMenuItemClick Ereignis aufrufen. Dabei will ich, je nachdem was für Zeilen markiert sind, genau diese Objekte verwenden. Bisher habe ich es so gemacht, dass über die SelectedRows Property des DGV die Zeilen in der DataTable gesucht und dann in der List<Person> geschaut habe, ob schon so ein Objekt vorhanden ist. Wenn nicht, habe ich ein Objekt erzeugt.
Scheint mir aber irgendwie sehr umständlich, denn das muss ich machen, wenn ich Start, Stop, oder eine der anderen 10 Methoden aufrufen möchte.
Schöne wäre es, wenn ich direkt nach dem Click das Objekt in der "Hand" haben würde.
Mir ist gerade die Idee gekommen, dass ich erstmal ein Ereignis des DataGridView verwende, welches beim hinzufügen einer neuen Row, erstmal ein Objekt erzeugt und in die Liste reinlegt.
Scheint mir aber irgendwie alles nicht ganz lehrbuchgetreu :-/
Liebe Grüße
Kha - Fr 23.09.11 15:52
BlackMatrix hat folgendes geschrieben : |
| Schöne wäre es, wenn ich direkt nach dem Click das Objekt in der "Hand" haben würde. |
Was der Code von Th69 doch genau erfüllt. In deinem Fall dann eben ein Cast nach Person statt DataRow.
Kha - Fr 23.09.11 17:07
Du hast eine List<Person> und eine DataTable? Warum nicht direkt die Liste binden?
BlackMatrix - Fr 23.09.11 17:30
Kha hat folgendes geschrieben : |
| Du hast eine List<Person> und eine DataTable? Warum nicht direkt die Liste binden? |
Eine normale Liste binden ist ja nicht möglich, oder geht das noch irgendwie anders?
Bei der BindingList habe ich wieder das Problem, dass meine Unterklassen in der Klasse Person mit angezeigt werden und auch Properties dann im DGV angezeigt werden, die ich gar nicht möchte.
Daher habe ich mir eine DataTable angelegt, die dann die Werte, die ich angegeben habe, dem Objekt zuweise. Sehr unschön, aber auch aufwendig.
Oder vielleicht die List<Person> gleich ganz weglassen und nur das Listarray der Row der Klasse Person übergeben?
Kha - Fr 23.09.11 19:14
BlackMatrix hat folgendes geschrieben : |
| Eine normale Liste binden ist ja nicht möglich, oder geht das noch irgendwie anders? |
Ich weiß ja nicht, was du unter "anders" verstehst, aber ist eigentlich
kein Problem [
http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.datasource.aspx].
Kha hat folgendes geschrieben : |
| Bei der BindingList habe ich wieder das Problem, dass meine Unterklassen in der Klasse Person mit angezeigt werden und auch Properties dann im DGV angezeigt werden, die ich gar nicht möchte. |
Was für Unterklassen? Und warum gibst du die gewollten Spalten nicht einfach selbst an?
BlackMatrix - Fr 23.09.11 20:31
Kha hat folgendes geschrieben : |
| Was für Unterklassen? Und warum gibst du die gewollten Spalten nicht einfach selbst an? |
Okay, ob ich nun eine BindingList nehme oder eine BindingSource mit einer Liste verknüpfe scheint wohl am Ende das selbe zu sein.
Was meinst du mit die gewollten Spalten nicht einfach selbst angeben? Wenn ich dem DGV die DateSource mitgebe, was in meinem Fall dann die BindingSource von meiner List<Person> ist, dann werden doch automatisch alle Properties, die public sind, als Spalten in meinem DGV angelegt. Ich habe aber nur einen kleinen Teil meiner Properties, die ich angezeigt bekommen möchte.
Desweiteren befinden sich in mein Klasse Person, eine weitere Klasse (Unterklasse), aus der ich auch 2 Properties im DGV anbinden möchte.
Kannst du mir das bitte nochmal genauer erklären?
Th69 - Sa 24.09.11 09:01
Hallo BlackMatrix,
du kannst beim DGV die Eigenschaft AutoGenerateColumns auf 'false' setzen und dann die einzelnen Spalten bei "Columns" definieren (und mit der Eigenschaft DataPropertyName die zu bindende Eigenschaft angeben).
Such mal im Internet nach "DataGridView FAQ" - es gibt eine DOC Datei, welche ausführlich die vielfältigen Anwendungsmöglichkeiten des DGV erklärt.
BlackMatrix - Sa 24.09.11 19:24
Th69 hat folgendes geschrieben : |
Hallo BlackMatrix,
du kannst beim DGV die Eigenschaft AutoGenerateColumns auf 'false' setzen und dann die einzelnen Spalten bei "Columns" definieren (und mit der Eigenschaft DataPropertyName die zu bindende Eigenschaft angeben).
Such mal im Internet nach "DataGridView FAQ" - es gibt eine DOC Datei, welche ausführlich die vielfältigen Anwendungsmöglichkeiten des DGV erklärt. |
Okay, ja das gefällt mir. Problem nur, dass man keine Datenbindung zu den Subklassen aufbauen kann.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 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!