Autor |
Beitrag |
pycak
Hält's aus hier
Beiträge: 12
|
Verfasst: Di 17.03.09 00:08
Hallo zusammen,
ich versuche in einer DataGridView Zellen zu verschieben/kopieren. Der Benutzer soll einfach Zellen selektieren können und Inhalt in die andere Zelle ziehen/einfügen.
Kann mir vieleicht jemand erklären wie ich vorgehen soll?
Welche Events sind da notwendig?
Danke im Voraus
Gruß Pycak
|
|
pycak 
Hält's aus hier
Beiträge: 12
|
Verfasst: Mi 18.03.09 15:32
Ich komme leider immer noch nicht weiter, habe mitlerweile rausgefunden welche Events ich dafür brauche.
Mit zwei Listboxen klappt es wunderbar Items zu kopieren, aber wie kann man in einem DataGridView Values einzelner Zellen kopieren???
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| private void dataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e) { dataGridView1.DoDragDrop(dataGridView1[e.ColumnIndex, e.RowIndex].Value, DragDropEffects.Move); }
private void dataGridView1_DragEnter(object sender, DragEventArgs e) { e.Effect = DragDropEffects.Move; } |
Der Zeiger ändert sich aber wie kann ich jetzt DragDrop-Event implementieren?
|
|
Christoph1972
      
Beiträge: 690
Erhaltene Danke: 16
VS2015 Pro / C# & VB.Net
|
Verfasst: Sa 21.03.09 00:23
Hi,
ich mache das ungefähr so:
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: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55:
| private Rectangle mdrRect; private Int32 mdrIndex = 0;
void DGV_DragEnter(object sender, DragEventArgs e) { e.Effect = DragDropEffects.Move; }
void DGV_MouseMove(object sender, MouseEventArgs e) { if (Convert.ToBoolean(Convert.ToInt32(e.Button) == Convert.ToInt32(System.Windows.Forms.MouseButtons.Left))) { if (mdrRect != Rectangle.Empty && !mdrRect.Contains(e.X, e.Y)) { DataGridViewRow DGVR = DGV.Rows[mdrIndex]; DragDropEffects DDF = DGV.DoDragDrop(DGVR, DragDropEffects.Move); } } }
void DGV_MouseDown(object sender, MouseEventArgs e) { mdrIndex = DGV.HitTest(e.X, e.Y).RowIndex;
if (mdrIndex != -1) { Size ds = SystemInformation.DragSize; mdrRect = new Rectangle(new Point(e.X - Convert.ToInt16((ds.Width / 2)), e.Y - Convert.ToInt16((ds.Height / 2))), ds); } else { mdrRect = Rectangle.Empty; } }
void DGV_DragDrop(object sender, DragEventArgs e) { Point ptc = DGV.PointToClient(new Point(e.X, e.Y)); Int32 index = DGV.HitTest(ptc.X, ptc.Y).RowIndex; if (e.Effect == DragDropEffects.Move) { DataGridViewRow RowToMove = e.Data.GetData(typeof(DataGridViewRow)) as DataGridViewRow; DGV.Rows.RemoveAt(mdrIndex); DGV.Rows.Insert(index, RowToMove); DGV.Rows[index].Selected = true;
for (int i = 0; i < DGV.Rows.Count; i++) { if (i != index) { DGV.Rows[i].Selected = false; } } } } |
Wenn das DGV Datengebunden ist, darf das Insert natürlich nicht ins DGV erfolgen, sondern in das Dataset z.B.. Ob es der Beste Weg ist kann ich nicht sagen, aber es funktioniert Tip Top!
Gruß
Christoph
|
|
rubooo
      
Beiträge: 52
WIN XP
Delphi 2005 Prof
|
Verfasst: Do 10.03.11 16:58
ich kriege immer den Fehler:
Zeilen können nicht automatisch zur Zeilenauflistung der DataGridView hinzugefügt werden, wenn das Steuerelement datengebunden ist.
Jetzt frage ich mich was ein DataSet ist... und wie ich es richtig machen kann.
Meine DataGridView kommuniziert mit einer Datenbank... ist es deswegen ein Problem?
|
|
Th69
      

Beiträge: 4739
Erhaltene Danke: 1045
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Do 10.03.11 18:26
Hallo rubooo,
du hast sicherlich die Daten in einem DataSet oder einer DataTable abgelegt und diese dann per "dataGridView.DataSource" zur Anzeige gebracht?
Anstatt nun in einem datengebundenen DataGridView die Zeilen von Hand zu verschieben, mußt du eben die Zeilen in der DataTable verschieben (DataRow).
Evtl. wäre es jedoch besser, du würdest die DataTable.DefaultView verwenden und dort dann die Sortierung einstellen (z.B. über eine unsichtbare Spalte, welche die Reihenfolge (Index) beinhaltet).
|
|
rubooo
      
Beiträge: 52
WIN XP
Delphi 2005 Prof
|
Verfasst: Do 10.03.11 22:30
Im moment experimentiere ich mit diesem Beispiel dzaebel.net/DataGridViewDragDrop.htm
Wenn ich eine Row per Drag&Drop verschiebe springt der Debugger nun in die Zeile:
C#-Quelltext 1:
| dgvListenansicht.Rows.Insert(rowIndexOfItemUnderMouseToDrop, rowToMove); |
Und spuckt folgende Meldung aus:
Zeilen können nicht automatisch zur Zeilenauflistung der DataGridView hinzugefügt werden, wenn das Steuerelement datengebunden ist.
Wenn ich das Programm weiter laufen lasse, wird die gedraggde, gezogene Row einfach gelöscht...
Das Programm ruft per MySQL Daten ab und schreibt sie in das DataGridView...
Bitte echt um Hilfe, da ich im Moment garnicht weiter komme
Hier nocht die SQL-Connection:
C#-Quelltext 1: 2: 3: 4:
| MySqlDataAdapter da = new MySqlDataAdapter(mySelectQuery, con); DataTable tbl = new DataTable(); da.Fill(tbl); Form1._Instanz.dgvListenansicht.DataSource = tbl; |
|
|
Th69
      

Beiträge: 4739
Erhaltene Danke: 1045
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Fr 11.03.11 10:14
Hallo rubooo,
du hast zwar meine Frage nicht direkt beantwortet, aber aus deinem Code sehe ich ja, daß du DataBinding (dgv.DataSource) benutzt.
Und wie ich schon geschrieben habe, mußt du eben die Zeilen dann in der DataTable ändern (anstatt direkt im DataGridView), also in etwa so:
C#-Quelltext 1: 2: 3: 4:
| DataTable tb = dgvListenansicht.DataSource as DataTable;
Row row = tb.Rows.RemoveAt(rowIndexFrom); tb.Rows.InsertAt(row, rowIndexOfItemUnderMouseToDrop); |
Durch das DataBinding wird sich dann das DataGridView automatisch wieder aktualisieren.
P.S: "Form1._Instanz" sieht nach einem sehr unsauberen Design aus (die Datenbank-Klasse (DataLayer) sollte die Form überhaupt nicht kennen!).
Gib einfach die DataTable als Rückgabewert in der Methode an und binde von deiner Form-Klasse aus die Daten an das DGV:
C#-Quelltext 1: 2:
| dgvListenansicht.DataSource = dataClass.GetData(); |
|
|
rubooo
      
Beiträge: 52
WIN XP
Delphi 2005 Prof
|
Verfasst: Fr 11.03.11 14:17
erstmal vielen Dank für deine guten Antworten und Erklärungen.
Th69 hat folgendes geschrieben : |
Und wie ich schon geschrieben habe, mußt du eben die Zeilen dann in der DataTable ändern (anstatt direkt im DataGridView), also in etwa so:
C#-Quelltext 1: 2: 3:
| DataTable tb = dgvListenansicht.DataSource as DataTable; Row row = tb.Rows.RemoveAt(rowIndexFrom); tb.Rows.InsertAt(row, rowIndexOfItemUnderMouseToDrop); |
|
Ich habe es nun so angepasst:
C#-Quelltext 1: 2: 3: 4:
| DataTable tb = dgvListenansicht.DataSource as DataTable; DataRow row = tb.Rows[rowIndexFromMouseDown]; tb.Rows.RemoveAt(rowIndexFromMouseDown); tb.Rows.InsertAt(row, rowIndexOfItemUnderMouseToDrop); |
Mein Problem ist allerdings, dass bei tb.Rows.RemoveAt(rowIndexFromMouseDown); auch DataRow row gelöscht wird und somit der Insert eine leere Zeile einfügt...
wie kann ich das beheben?
Entschuldigung für die Fragen, aber dies ist mein erstes Projekt in C#
|
|
Th69
      

Beiträge: 4739
Erhaltene Danke: 1045
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Fr 11.03.11 15:35
Hallo,
sorry ersteinmal, daß mein Code so natürlich nicht funktionierte, aber du hast es ja richtig hinbekommen.
Unter social.msdn.microsof...7-b955-f1a2d9cf0202/ gab es eine ähnliche Anfrage (wenn auch VB.NET).
Probiere mal am Ende noch
C#-Quelltext
aufzurufen.
Wenn das auch noch nicht klappt, dann mal die Remove (anstatt der RemoveAt)-Methode (auch wenn ich selber keinen Unterschied darin erkennen mag).
|
|
rubooo
      
Beiträge: 52
WIN XP
Delphi 2005 Prof
|
Verfasst: Fr 11.03.11 15:57
danke für die schnelle Antwort.
Quelltext 1: 2: 3: 4: 5:
| DataTable tb = dgvListenansicht.DataSource as DataTable; DataRow row = tb.Rows[rowIndexFromMouseDown]; tb.Rows.Remove(row);//RemoveAt(rowIndexFromMouseDown); tb.Rows.InsertAt(row, rowIndexOfItemUnderMouseToDrop); tb.AcceptChanges(); |
bringt allerdings keine Änderung.
Ich hab mit dem Debugger nachgeschaut.. Bei tb.Rows.Remove(row) wird auch der Inhalt von row gelöscht. Kann ich die Daten nicht gesondert speichern  ?
|
|
rubooo
      
Beiträge: 52
WIN XP
Delphi 2005 Prof
|
Verfasst: Fr 11.03.11 16:42
sry wegen Doppelpost aber ich hab das Problem gelöst und will nur Bescheid sagen:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7:
| DataTable tb = dgvListenansicht.DataSource as DataTable; DataRow row = tb.Rows[rowIndexFromMouseDown]; object[] rowArray = new object[row.ItemArray.Count()]; rowArray = row.ItemArray; tb.Rows.RemoveAt(rowIndexFromMouseDown); row.ItemArray = rowArray; tb.Rows.InsertAt(row, rowIndexOfItemUnderMouseToDrop); |
|
|
Th69
      

Beiträge: 4739
Erhaltene Danke: 1045
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Fr 11.03.11 16:45
Das scheint doch etwas komplizierter zu sein.
Ich habe noch www.devx.com/tips/Tip/32233 gefunden.
Evtl. würde auch DataTable.ImportRow helfen, d.h. du legst mittels DataTable.Clone() eine neue Tabelle an und fügst dort dann mittels ImportRow die Row hinzu, danach löschst du sie aus der Original-Tabelle und anschließend fügst du sie wieder aus der geklonten Tabelle der richtigen Tabelle hinzu.
Aber wie schon mal geschrieben, wäre evtl. das Ändern der Reihenfolge innerhalb der DataView der bessere (und evtl. einfachere) Weg. Füge einfach eine neue Spalte zu der Tabelle hinzu und trage dort dann die Werte von 1 - N ein. Beim Drag'n Drop änderst du dann einfach den Index der Spalte (und alle folgenden um 1 erhöhen bzw. alle vorherigen um 1 erniedrigen).
Und dann einfach im DataView die Sortierreihenfolge festlegen:
C#-Quelltext 1:
| dataTable.DefaultView.Sort = "SortColumn"; |
|
|