Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Drag&Drop mit TStringGrid und TTreeView


Delete - Di 22.08.06 00:25
Titel: Drag&Drop mit TStringGrid und TTreeView
Drag&Drop von TStringGrid auf TTreeView funktioniert so weit, aber leider nicht sauber. Teilweise bringt er dabei den falschen Schlüssel. Vielleicht erkennt Ihr ja den Fehler... wäre toll.

a) tStringGrid: Beim MouseDown ereignis wird das BeginDrag initialisiert, die Koordinaten der aktuellen Zelle ermittelt und in Col/Row gesichtert, damit später darauf zurückgegriffen werden kann.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure TfMain.sgPfgModMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
 c, r: integer;
begin
 (sender as tstringgrid).BeginDrag(false);
 (sender as tstringgrid).MouseToCell(x, y, c, r);

 (sender as tstringgrid).col := c;
 (sender as tstringgrid).row := r;
end;


b) tTreeView: hier wird dann beim DragDrop die Zeile aus dem StringGrid ausgelesen, somit stehen die Koordinaten des Stringgrids in tStringgrid(source).col und tStringgrid(source).row.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure TfMain.tvPfgModDragDrop(Sender, Source: TObject; X, Y: Integer);
var
 r, c: integer;
 node: ttreeNode;
 i: integer;
 s: string;
begin
 if (source is tstringgrid) then
 begin
  r := (source as tstringgrid).Row;
  c := 0;
  node := (sender as tTreeView).GetNodeAt(x, y);


Das Funktioniert so weit, aber teilweise wird der falsche Schlüssel zurückgegeben. An was könnte dies liegen? :nixweiss:


Martok - Di 22.08.06 01:22

Da hab ich in Verständnisproblem: was verstehst du unter einem Schlüssel? Einen TTreeview-Knoten?
Davon gehe ich jetzt erstmal aus.

Also, ich hab das mal nachgebaut, bei mir funktioniert es immer, außer wenn man unterhalb der Knoten fallen lässt. Dann gibt GetNodeAt korrekterweise nil zurück.

Beim DragDrop wird ja immer ein Knoten bein Drüberfliegen markiert, wäre vielleicht besser den zu nehmen. Dazu gibt es DropTarget:

Delphi-Quelltext
1:
node := (sender as tTreeView).DropTarget;                    


Delete - Mi 23.08.06 20:42

hallo Martok,

nein, das tTreeView funktioniert einwandfrei. aber mit dem referenzieren des TStringGrids hat er probleme, da schmeist er teilweise die zeilen durcheinander... die konsequenz davon ist, dass dann im TTreeview ein anderer Wert oder auch einfach ein leerer knoten auftaucht. den muss man wieder löschen... dann noch mal probieren, bis es denn klappt. teilweise funktionierts auch gleich beim ersten mal...

aber mögliche fehler sollte man halt vermeiden. kennst du da einen trick, wie die richtige zeile aus dem tStringGrid gewählt werden kann? das wäre schon alles

grüsse und noch einen schönen abend.


Martok - Mi 23.08.06 23:36

Tja, ich hab nochmal ein Projekt gebaut, es geht immer noch.
Allerdings nicht, wenn ich eine der fixierten Zellen dragge.

Man könnte dann die Zeile/Spalte des StringGrids in zwei Variablen der Formulars speichern, statt Stringgrid.Col/Row zu nehmen.
Hier mal mein Beispielcode, ist das jetzt das was du meinst?


Delete - So 27.08.06 19:19

hallo martok,

hab dein beispiel mal angeschaut, auch mit der "getXY" variante, kommt alles aufs gleiche raus.

im übrigen, habe ich auch kein problem mit einer fixierten zeile oder spalte.

das problem war, dass es wohl nicht die richtige koordinate des tStringGrids abspeichert und somit eine "falsche" zeile beim DragDrop übergibt.

aber wie gesagt, in dem beispiel von dir (auch mit der GetXY variante) funktioniert dies alles einwandfrei.