Hallo Harry,
genau das habe ich gesucht. Besten Dank dafür.
Noch eine Kleinigkeit, bei Drug&Drop wird die komplette Tabelle animiert und nicht die Row.
Gibt es eine Möglichkeit das zu ändern?
Gruß Kostas
Gerne. Man muss den Dragvorgang dann selber einleiten (also DragMode für die beiden Listen auf Manual stellen) und hier beim Ziehen über die Listview das benötigte Objekt angeben:
Delphi-Quellcode:
procedure TForm33.ListView1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Single);
begin
if (SsLeft in Shift) and (ListView1.Selected <> NIL) then begin
BeginInternalDrag(Listview1.Selected, Image1.Bitmap);
end;
end;
Hier wird als 2. Parameter immer eine Bitmap erwartet, die muss gültig, kann aber auch leer sein.
Beim ziehen über die 2. Listview setzt Du dann die gewünschte Operation (für das optische Feedback):
Delphi-Quellcode:
procedure TForm33.ListView2DragOver(Sender: TObject;
const [Ref] Data: TDragObject; const [Ref] Point: TPointF;
var Operation: TDragOperation);
begin
Operation := TDragOperation.Move;
end;
Ich habe jetzt hier keine Verschieben implementiert, das kriegst Du auch selber hin, gefragt war ja nur, wie man das Item ermitteln kann, über dem die Maustaste losgelassen wird. Im Demo habe ich das Item zuvor gesetzt, damit man ein Feedback hat:
Delphi-Quellcode:
procedure TForm33.ListView2DragDrop(Sender: TObject;
const [Ref] Data: TDragObject; const [Ref] Point: TPointF);
var
obj: IControl;
Index: Integer;
begin
obj := ObjectAtPoint (Screen.MousePos);
if obj <> NIL then begin
Index := GetIndexATPos (ListView2, Point);
if Index <> -1 then begin
// Aktuelle Zeile setzen
Listview2.ItemIndex := Index;
ShowMessage ('Gezogen: ' + TListViewItem (Data.Source).Text + 'auf Zeile ' + TListView (obj).ItemIndex.ToString + ' = ' + TListViewItem (ListView2.Selected).text);
end;
end;
end;
In Aktion sieht es dann wie auf den beiden Screenshots aus, das "Demo-Projekt" habe ich angehängt. In einer zuverlässigen App musst Du natürlich noch ein paar Prüfungen einbauen (z.B. ist das gezogene Objekt auch vom Typ ListViewItem usw).
Zum besseren Verständnis habe ich hier mit "Listview2" gearbeitet (was im echten Leben eine kleine Todsünde wäre). Um es allgemeingültig zu machen, verwendest Du statt dessen z.B "(Sender as TListView)" oder nimmst eine lokale Variable TL: TListview, die Du am Anfang einmal zuweist (TL:= TListView(Sender)") und fortan damit arbeitest. So kannst Du ein und die gleiche Ereignisprozedur für mehrere Listviews verwenden (z.B. wenn Du die Elemente zwischen beiden Listviews hin und her schieben willst).