Konuyu Oyla:
  • Derecelendirme: 0/5 - 0 oy
  • 1
  • 2
  • 3
  • 4
  • 5
listView drag and dpor
#1
Merhaba,

Firemonkey tarafında (kendi içinde ve faklı listViewler arasında)  listView drag and dpor yapabileceğim, forumda ve nette elle tutulur bir kod bulamadım.


Elinde kod olan arkadaşlar paylaşımda bulunursa sevinirim.
Cevapla
#2
KernowSoftware'in KsTableView Componentini incelemenizi öneririm.

https://bitbucket.org/gmurt/kscomponents/src
// Bilgi paylaştıkça çoğalır.. 

Cevapla
#3
FMX derken Windows altında yapıyorsunuz değil mi ? 

Bu size hazırladığım örnek sadece kaynak item ve index numarası ile taşıdığınız hedef item ve index numarasını verecektir. Kaynak ve hedefi biliyorum, araya nasıl yerleştireceğim, çoklu / multidrag nasıl yaparım vb. gibi bir soru gelecek gibi ama hadi kayırlısı  Smile

İşlem çok teknik olduğundan direkt örnek kod ile cevap verdim, bundan sonrası küçük / basit bir insert Item ve swap Item işlemidir. Idea  
Boş bir MultiDevice (Win) proje açın, içinde ListView1 ve ListView2 adında iki TListView koyun.
Bir de TImage koyun Image1 olsun içinde de listview Item'ini taşırken görmek istediğiniz icon tipinde bir resim koyun. Bu da size bonus özellik.

Dilerseniz ileride de bunu bir CLASS yapıp iki ListView'i bu class'a nesne olarak insert eder otomatik özellik kazandırabilirsiniz. Ben bu şekilde CLASS halinde kullanıyorum ama sizin için şu aşamada bu kısım yeterli.

procedure TForm1.FormCreate(Sender: TObject);
Var
 i : Integer;
begin
 With ListView1.ItemAppearanceObjects.ItemObjects.Accessory do begin
   AccessoryType := TAccessoryType.Checkmark;
   Visible       := False;
 end;

 With ListView2.ItemAppearanceObjects.ItemObjects.Accessory do begin
   AccessoryType := TAccessoryType.Checkmark;
   Visible       := False;
 end;

 ListView1.OnDragDrop  := ListView1DragDrop;
 ListView1.OnDragOver  := ListView1DragOver;
 ListView1.OnMouseMove := ListView1MouseMove;
 ListView1.OnDblClick  := ListView1DblClick;

 ListView2.OnDragDrop  := ListView1DragDrop;
 ListView2.OnDragOver  := ListView1DragOver;
 ListView2.OnMouseMove := ListView1MouseMove;
 ListView2.OnDblClick  := ListView1DblClick;

 for i := 0 to 20 do begin
   With ListView1.Items.Add do
   begin
     Text := Format('ListView1Item_%.2d', [i]);
     // diğer atamalar vs.
   end;

   With ListView2.Items.Add do
   begin
     Text := Format('ListView2Item_%.2d', [i]);
     // diğer atamalar vs.
   end;
 end;
end;


function GetIndexAtPos(LV: TListView; TP: TPointF): Integer;
var
 I : Integer;
 TR: TRectF;
begin
 Result := -1;
 for I := 0 to LV.Items.Count-1 do begin
   TR := LV.GetItemRect(I);
   if TR.Contains(TP) then begin
     Result := I;
     Break;
   end;
 end;
end;

procedure TForm1.ListView1DblClick(Sender: TObject);
begin
 if TListView(Sender).Selected = nil then Exit;
 With TListViewItem( TListView(Sender).Selected ).Objects.AccessoryObject
   do Visible := NOT Visible;
end;

procedure TForm1.ListView1DragDrop(Sender: TObject; const Data: TDragObject;
 const Point: TPointF);
var
 obj  : IControl;
 Index: Integer;
begin
 obj := ObjectAtPoint(Screen.MousePos);
 if obj <> nil then begin
   Index := GetIndexATPos ( TListView(Sender), Point);
   if Index <> -1 then begin
     TListView(Sender).ItemIndex := Index;
     ShowMessage ('Kaynak: ' + TListViewItem(Data.Source).Text + ' Idx: ' + TListViewItem(Data.Source).Index.ToString + ' Hedef : ' + TListViewItem(TListView(Sender).Selected).text + ' Idx: ' + TListView(obj).ItemIndex.ToString );
   end;
 end;
end;

procedure TForm1.ListView1DragOver(Sender: TObject; const Data: TDragObject;
 const Point: TPointF; var Operation: TDragOperation);
begin
 Operation := TDragOperation.Move;
end;

procedure TForm1.ListView1MouseMove(Sender: TObject; Shift: TShiftState; X,
 Y: Single);
begin
 if (ssLeft in Shift) and (TListView(Sender).Selected <> NIL) then
 begin
   BeginInternalDrag(TListView(Sender).Selected, Image1.Bitmap);
 end;
end;


xffeh4t37fmo8z1ixydd.gif



Bu daha başlangıç, sınıf haline gelince hedefiniz bu aşağıdaki gibi style, item üzerinde butonlar, multidrag/drop, taşıma vb. olacaktır.

FMX içinde ListView zorunluluğunuz da yok bir süre sonra yerine ListBox kullanmak isteyebilirsiniz.  Idea

ce4jnvh26dfrdsf9r3k1.gif
Saygılarımla
Muharrem ARMAN

guplouajuixjzfm15eqb.gif


Cevapla
#4
@mrmarman Allah razı olsun, Tecrübenize sonsun saygı duyuyorum. Hakkınızı ödeyemem.


Kendimce forumdaki bazı paylaşılan bazı kodları ve sizin kodlarınızı bir araya getirerek çözmeye çalışıyorum. Kısmen güzel yol aldım fakat 2 konuda sıkıntı yaşıyorum.

1. Faklı listviewde taşıma sırasında aldığım adres hatası:
First chance exception at $0096FABD. Exception class $C0000005 with message 'access violation at 0x0096fabd: read of address 0x00000000'

2. ise aynı listviewde içinde taşıma sırasında eski satırı silmeyi beceremedim.



procedure TForm1.ListView1DragDrop(Sender: TObject; const Data: TDragObject; const Point: TPointF);
var
  Obj: IControl;
  AItem: TListViewItem;
  I, ImgIndex, Index: Integer;
  ObjImgName, ObjName, ObjData: String;
begin
  Obj := ObjectAtPoint(Screen.MousePos);
  if Obj <> Nil then
  begin
    Index := GetIndexAtPos(TListView(Sender), Point);
    if Index <> -1 then
    begin
      // showmessage(TListView(Sender).Name);
      AItem := TListViewItem(TListView(Sender).Selected); // Seçilen satırın bilgilerini alıyorum
      TListView(Sender).Items.Insert(Index); // Insert yapılacak satır no
      for I := 0 to Pred(AItem.Objects.Count) - 1 do
      begin
        if AItem.Objects[I] is TListItemImage then // Image ise bilgileri integer olarak alıyorum
        begin
          ObjImgName := AItem.Objects[I].Name;
          ImgIndex := TListItemImage(AItem.Objects[I]).ImageIndex;
          TListView(Sender).Items[Index].Data[ObjImgName] := ImgIndex;
        end
        else
        begin
          ObjName := AItem.Objects[I].Name;
          ObjData := AItem.Objects[I].Data.ToString;
          TListView(Sender).Items[Index].Data[ObjName] := ObjData;
        end;
      end;
    end;
  end;
end;



Aramızda kalsın, Nedense lisxbosı sevemedim
Cevapla
#5
Aynı işlemi orangeui listbox ile yapmaya çalışıyorum. Ama bir türlü mantığını kavrayamadım.
Yapmak istediğim şey bir liste içindeki elemanın yerini değiştirmek. Bu işlem için item in Move diye bir özelliği var. Kod ile istediğim item tek satırda yer değiştirebiliyorum. 
mesela şunun gibi
lstPersonel.Prop.Items.Move(0, 3);
Fakat aynı işlemi sürükle bırak ile yapmak istiyorum. Bunu bir türlü başaramadım. 
Üzerinde çalıştığım örnek uygulama aşağıda. yardımcı olabilir misiniz.


Ek Dosyalar
.zip   List.zip (Dosya Boyutu: 41,09 KB / İndirme Sayısı: 2)
Cevapla


Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  OrangeUI ListView.Pic.Url authentication ile bağlanma elixir84 1 411 10-06-2020, Saat: 11:29
Son Yorum: Fesih ARSLAN
  JSON to OrangeUI Listview ikurt07 6 2.071 08-04-2020, Saat: 15:54
Son Yorum: Fesih ARSLAN
  Listview nesnesi ile birden fazla alan oluşturma Fesih ARSLAN 12 7.871 09-03-2020, Saat: 10:47
Son Yorum: Fesih ARSLAN
  ListView Checkbox select all seydigozegir@gmail.com 1 669 13-11-2019, Saat: 11:54
Son Yorum: Fesih ARSLAN
  ListView Multi Seçim hk. seydigozegir@gmail.com 2 1.003 08-11-2019, Saat: 15:36
Son Yorum: seydigozegir@gmail.com



Konuyu Okuyanlar: 1 Ziyaretçi