Einzelnen Beitrag anzeigen

Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.538 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Drag&Drop mit zwei FMX ListView

  Alt 12. Nov 2015, 18:19
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).
Miniaturansicht angehängter Grafiken
move1.jpg   move2.jpg  
Angehängte Dateien
Dateityp: zip ListViewItemDrag.zip (58,8 KB, 53x aufgerufen)

Geändert von Harry Stahl (12. Nov 2015 um 18:34 Uhr)
  Mit Zitat antworten Zitat