| Autor |
Beitrag |
alegria
      
Beiträge: 79
|
Verfasst: Mo 05.01.09 18:16
Tach allerseits!
Also ich hab datagridview1 mit paar Zeilen und die Eigenschaft SelectionMode auf FullRowSelect gestellt. Nun sollen (soweit klappts auch...) die markierte(n) Zeile(n) per DragAndDrop in datagridview2 verschoben werden. Da ich nicht genau weiss wie ich "selectedrows" als object übergebe, habe ich ein bissl gemogelt und übergebe beim eigentlichen DragAndDrop nur pseudokram und markiere in datagridview2 einfach das, was in datagridview1 selected ist. Der Code dafür sieht so aus (in datagidview1 müssen paar zeilen mit jeweils zwei werten schonmal stehen):
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:
| private void dataGridView1_MouseDown(object sender, MouseEventArgs e)
{
DoDragDrop("dummyDragDrop", DragDropEffects.All);
}
private void dataGridView2_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.All;
}
private void dataGridView2_DragDrop(object sender, DragEventArgs e)
{
dataGridView2.Rows.Clear();
if (dataGridView1.SelectedRows.Count > 1)
{
dataGridView2.Rows.Add(dataGridView1.SelectedRows.Count);
}
else { dataGridView2.Rows.Add();
}
for (int i = 0; i <= dataGridView1.SelectedRows.Count; i += 1)
{
dataGridView2.Rows[i].Cells[0].Value = dataGridView1.SelectedRows[i].Cells[0].Value;
dataGridView2.Rows[i].Cells[1].Value = dataGridView1.SelectedRows[i].Cells[1].Value;
}
} |
Nun hab ich drei Probleme welche der Schwierigkeit nach folgende sind:
1) Momentan ersetze ich in datagridview2 immer alles. Was wenn ich datagridview1 mit einer suche befülle und nur hin und wieder mal was zu datagridview2 hinzufüge? Was ist das Kriterium für "füge hinzu" bzw. "ist schon da, lass es sein" - Muss ich immer erst ne Probe zwecks Zellinhalt machen?
2) Nervige Sache ist dieses Mysterium: Wenn ich den Zellinhalt in datagridview2 "fallenlasse" und klicke dann unmittelbar in das datagridview1 passiert gar nix. Erst nochmal klicken markiert mir die entsprechende zeile - aber warum nicht gleich beim ersten mal???
3) Wie realisiere ich denn am besten löschen bzw. entfernen aus datagridview2??? Fein wäre naürlich wieder per DragAndDrop. Die Frage ist nur, ob sich das dann mit den events und so nicht gegenseitig "verschluckt"? Aber ich glaub das Problem ist noch am einfachsten... (notfalls macht man contextmenü mit "lösche die zeile" oder sowas...)
Ich danke Euch wie immer im Voraus für Eure Hilfe!
|
|
UGrohne
      

Beiträge: 5502
Erhaltene Danke: 220
Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
|
Verfasst: Mo 05.01.09 20:20
So, dann versuche ich mich mal daran:
alegria hat folgendes geschrieben : | Nun hab ich drei Probleme welche der Schwierigkeit nach folgende sind:
1) Momentan ersetze ich in datagridview2 immer alles. Was wenn ich datagridview1 mit einer suche befülle und nur hin und wieder mal was zu datagridview2 hinzufüge? Was ist das Kriterium für "füge hinzu" bzw. "ist schon da, lass es sein" - Muss ich immer erst ne Probe zwecks Zellinhalt machen? |
Ja, die Probe musst Du immer selbst machen, schließlich kennt das Grid ja die Bedingungen für Gleichheit nicht. In der Methode DoDragDrop übergibst Du übrigens die Daten, die nachher in e.Data liegen, das ist ne praktische Sache, vor allem da Du mittels e.Data.GetData(typeof(IrgendeinTyp)) genau das rausholen kannst, was Du brauchst.
alegria hat folgendes geschrieben : | | 2) Nervige Sache ist dieses Mysterium: Wenn ich den Zellinhalt in datagridview2 "fallenlasse" und klicke dann unmittelbar in das datagridview1 passiert gar nix. Erst nochmal klicken markiert mir die entsprechende zeile - aber warum nicht gleich beim ersten mal??? |
Problem wird hier sein, dass Du DoDragDrop immer beim MouseDown ausführst, Du solltest hier mit einem Grenzwert beim Ziehen arbeiten, z.B. mit:
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:
| private void productDataGridView_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { mouseDown = true; dragStartPoint = new Point(e.X, e.Y); } }
private void productDataGridView_MouseMove(object sender, MouseEventArgs e) { if ((mouseDown) && (!dragStarted)) { int xDiff = (dragStartPoint.X - e.X); int yDiff = (dragStartPoint.Y - e.Y); xDiff = xDiff * xDiff; yDiff = yDiff * yDiff; if (xDiff < 25 && yDiff < 25) return; else { dragStarted = true; productDataGridView.DoDragDrop(GetSelectedProduct(), DragDropEffects.Link); } } }
private void productDataGridView_MouseUp(object sender, MouseEventArgs e) { mouseDown = false; if (dragStarted) { dragStarted = false; } } |
alegria hat folgendes geschrieben : | | 3) Wie realisiere ich denn am besten löschen bzw. entfernen aus datagridview2??? Fein wäre naürlich wieder per DragAndDrop. Die Frage ist nur, ob sich das dann mit den events und so nicht gegenseitig "verschluckt"? Aber ich glaub das Problem ist noch am einfachsten... (notfalls macht man contextmenü mit "lösche die zeile" oder sowas...) |
Entfernen-Taste, Button sind das Einfachste. Der Rest ist komplizierter, weil Du das irgendwo abfangen musst, z.B. wenn Du ein zentrales Papierkorb-Symbol irgendwo hast. Da kannst Du das über die in 1. angesprochene Datenübergabe fein realisieren. Aber User-Interface-Mäßig ist das nicht sehr einleuchtend, deswegen eher davon Abstand nehmen.
|
|
alegria 
      
Beiträge: 79
|
Verfasst: Di 06.01.09 00:08
Puh! Ganz schön complicated teilweise - aber erstmal großen Dank für Deine Mühe!
zu 1)
| Zitat: | | Du übrigens die Daten, die nachher in e.Data liegen, das ist ne praktische Sache, vor allem da Du mittels e.Data.GetData(typeof(IrgendeinTyp)) genau das rausholen kannst, was Du brauchst. |
Ja soweit war ich schon. Bei 2 Textboxen bekomm ich es auch schön hin (is ja nur einfacher string und zwar alles...). Hier ist nur das Problem "typeof" (datagridrow? row? cell?) und v.a. ja auch nur die selectedrows!!!
zu 2)
| Zitat: | | Problem wird hier sein, dass Du DoDragDrop immer beim MouseDown ausführst, Du solltest hier mit einem Grenzwert beim Ziehen arbeiten, z.B. mit: |
Also da hats mich echt weggehauen. Das geht nicht einfacher? Ich mein Dein Code in allen Ehren aber das is ja mordsmäßig viel... Wenn ich statt mousedown ein einfaches click event nehme?
zu 3)
| Zitat: | | Entfernen-Taste, Button sind das Einfachste |
Tja manchmal bedarf es solcher Threads hier um mal wieder auf das wirklich einfache/wichtige gestoßen zu werden. Die Button-geschichte (schicker Papierkorb...) verwende ich ja bereits in anderen datagridviews und das mit der taste bekomm ich sicher auch noch irgendwie hin. Key-Event und dann ENTF noch irgendwie abfangen, oder?
Erstmal großen Dank. Ich versuch mich morgen mal in der praktischen anwendung...
P.S. Bei der Prüfung ob in datagridview2 nicht schon die row drinne ist hapert es bei mir noch bissl an nem vernünftigen algorithmus (so sind sie halt die nichtinformatiker...):
Angenommen ich habe in 2 bereits 15 zeilen und will nun zusätzlich noch 3 aus 1 hinzufügen. Ich würde jetzt prüfen:
ForEach Neue row aus 1 vergleiche zeile für zeile alte rows in 2
Nur das scheint mir extrem laufzeitintensiv/performancelastig. In meinem Bsp. (sofern die drei zeilen noch nicht existieren) wären das ja 45 cell prüfungen - ist das der weisheit letzter schluss???
|
|
alegria 
      
Beiträge: 79
|
Verfasst: Di 06.01.09 21:23
Also 3) ist gelöst und 1) lass ich so wie es ist da es ja zufrieden stellend funktioniert.
Bleibt die Problematik mit Punkt 2)
Wenn ich den Code so anschaue, fällt mit z.B. auf, dass die Methode
GetSelectedProduct()
nicht angegeben ist. Diese macht was genau?
Überhaupt: Was wird denn genau gemacht? Die Entfernung von den Startkoordinaten wird berechnet und wenn diese größer einen Schwellwert ist passiert was genau? Was wird „zurückgesetzt“ bzw. welches „event“ tritt ein/nicht ein?
Sorry, aber so richtig raff ich das leider noch nicht…
|
|
UGrohne
      

Beiträge: 5502
Erhaltene Danke: 220
Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
|
Verfasst: Di 06.01.09 22:46
alegria hat folgendes geschrieben : | Wenn ich den Code so anschaue, fällt mit z.B. auf, dass die Methode
GetSelectedProduct() nicht angegeben ist. Diese macht was genau? |
Stimmt, das ist meine eigene Methode. Ich habe hier eine Datenbankbindung mit dem Grid und hole mir dort über SelectedRows das dahinter liegende Entitäten-Objekt, im Endeffekt übergibst Du hier einfach einen Wert, eine ID, oder ein Objekt.
alegria hat folgendes geschrieben : |
Überhaupt: Was wird denn genau gemacht? Die Entfernung von den Startkoordinaten wird berechnet und wenn diese größer einen Schwellwert ist passiert was genau? Was wird „zurückgesetzt“ bzw. welches „event“ tritt ein/nicht ein?
Sorry, aber so richtig raff ich das leider noch nicht… |
Also: In MouseDown wird, wenn der linke Mouse-Button gedrückt wurde, die aktuelle Position des Mauszeigers gespeichert und ein Boolean gesetzt, dass der Mausbutton gerade gedrückt wird. Wenn danach die Mouse bewegt wird (MouseMove) wird die Differenz vom Startpunkt aus MouseDown und dem aktuellen Punkt ausgerechnet, und wenn diese (der Einfachheit halber) entweder in x oder in y größer als 5 Pixel ist, wird der Drag-Vorgang gestartet. Ich merke gerade, dass meine Berechnung hier nicht ganz fertig ist. Ich wollte hier mit dem Satz des Pythagoras die korrekte Entfernung berechnen, das hab ich aber nicht mehr gemacht. Du kannst also Zeile 17 und 18 auch weglassen und auf < 5 testen, hat den gleichen Effekt.
An jeder Stelle jedoch werden beim Loslassen des Mausbuttons (MouseUp) die Variablen mouseDown und dragStarted zurückgesetzt, damit im MouseMove kein Drag-Vorgang mehr gestartet wird.
Da sehe ich gerade, dass man das if-Statement auch weglassen könnte  .
alegria hat folgendes geschrieben : |
zu 1)
Ja soweit war ich schon. Bei 2 Textboxen bekomm ich es auch schön hin (is ja nur einfacher string und zwar alles...). Hier ist nur das Problem "typeof" (datagridrow? row? cell?) und v.a. ja auch nur die selectedrows!!! |
Hängt davon ab, was Du bei DoDragDrop im ersten Parameter übergibst!
|
|
|