Delphi Can

Orjinalini görmek için tıklayınız: Listview verilerin anlık kaybolması
Şu anda (Arşiv) modunu görüntülemektesiniz. Orjinal Sürümü Görüntüle internal link
Merhaba;

Çok soru soruyorum farkındayım, lütfen kusura bakmayın.
Databasedeki verileri listviewe listeliyorum. Drag and drop ile satırları yer değişikliği yapıyorum buraya kadar soru yok.
Fakat satırın yerini değiştirdikten sonra video da olduğu gibi listview sanki temizlenip yeniden yüklenmiş gibi oluyor.
Sizce bu durum normal midir? yoksa ben mi takıntı yapıyorum?









procedure TForm4.ListViewxDragDrop(Sender, Source: TObject; X, Y: Integer);
var
  DragItem, DropItem, CurrentItem, NextItem: TListItem;
begin
  if Sender = Source then
    with TListView(Sender) do
    begin
      DropItem := GetItemAt(X, Y);
      CurrentItem := Selected;
      while CurrentItem <> nil do
      begin
        NextItem := GetNextItem(CurrentItem, SdAll, [IsSelected]);
        if DropItem = nil then
          DragItem := Items.Add
        else
          DragItem := Items.Insert(DropItem.Index);
        DragItem.Assign(CurrentItem);
        CurrentItem.Free;
        CurrentItem := NextItem;
      end;
    end;
end;


procedure TForm4.ListViewxDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
begin
  Accept := Sender = ListViewx;
end;
Merhaba.

- ListView'in DoubleBuffered özelliğini TRUE yaparak bir deneyin kırpışma azalacaktır.

- Bu ListView'in boyama işlemini bizzat devralarak kendi yapmasını sonra da ürünü bitmap resim olarak devrederek görüntü performansını arttırmasını sağlar. Sıfırlamaz ama kabul edilebilir miktarda azaltır.
(03-02-2019, Saat: 12:04)mrmarman Adlı Kullanıcıdan Alıntı: [ -> ]Merhaba.

- ListView'in DoubleBuffered özelliğini TRUE yaparak bir deneyin kırpışma azalacaktır.

- Bu ListView'in boyama işlemini bizzat devralarak kendi yapmasını sonra da ürünü bitmap resim olarak devrederek görüntü performansını arttırmasını sağlar. Sıfırlamaz ama kabul edilebilir miktarda azaltır.

Daha önce doublebuffered özelliğini true yapmıştım sizden sonra tekrar test ettim.
Az bir miktarda da olsa kırpma azaldı, boyama işlemini kendim yaptım kırpma halen kırpma var.
Videoda bakıldığında siz ne düşünüyorsunuz? yoksa ben mi takıntı yaptım?  Huh
Merhaba.

- Şöyle bir durum var, SKIN kullanınca da bir de onun boyaması devreye giriyor.

- Şöyle içerik düzenleme sırasında kullandınız mı bilmiyorum ama kullanmadıysanız, içerik doldurma işlemini ListView Items için BeginUpdate / EndUpdate arasına alırsanız en azından içerik doldurma aşamasında her satır için boyama değil de sadece ürün ekrana yansıtma için tek boyama yapacağından biraz daha dilediğiniz şekilde performans artacaktır.

-
  listview1.items.beginupdate; 
 try 
   // sıralama – yer değiştirme işlemleri
 finally 
   listview1.items.endupdate; 
 end; 

şeklinde

Sizin koddaki karşılığı

procedure TForm1.ListView1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
 DragItem, DropItem, CurrentItem, NextItem: TListItem;
begin
 if Sender = Source then
   with TListView(Sender) do
   begin
     Items.BeginUpdate; // Burada ekledim.
     try // Burada ekledim.
       DropItem := GetItemAt(X, Y);
       CurrentItem := Selected;
       while CurrentItem <> nil do
       begin
         NextItem := GetNextItem(CurrentItem, SdAll, [IsSelected]);
         if DropItem = nil then
           DragItem := Items.Add
         else
           DragItem := Items.Insert(DropItem.Index);
         DragItem.Assign(CurrentItem);
         CurrentItem.Free;
         CurrentItem := NextItem;
       end;
     finally // Burada ekledim.
       Items.EndUpdate; // Burada ekledim.
     end; // Burada ekledim.
   end;
end;
(03-02-2019, Saat: 13:14)mrmarman Adlı Kullanıcıdan Alıntı: [ -> ]Merhaba.

- Şöyle bir durum var, SKIN kullanınca da bir de onun boyaması devreye giriyor.

- Şöyle içerik düzenleme sırasında kullandınız mı bilmiyorum ama kullanmadıysanız, içerik doldurma işlemini ListView Items için BeginUpdate / EndUpdate arasına alırsanız en azından içerik doldurma aşamasında her satır için boyama değil de sadece ürün ekrana yansıtma için tek boyama yapacağından biraz daha dilediğiniz şekilde performans artacaktır.

-
  listview1.items.beginupdate; 
 try 
   // sıralama – yer değiştirme işlemleri
 finally 
   listview1.items.endupdate; 
 end; 

şeklinde

Sizin koddaki karşılığı

procedure TForm1.ListView1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
 DragItem, DropItem, CurrentItem, NextItem: TListItem;
begin
 if Sender = Source then
   with TListView(Sender) do
   begin
     Items.BeginUpdate; // Burada ekledim.
     try // Burada ekledim.
       DropItem := GetItemAt(X, Y);
       CurrentItem := Selected;
       while CurrentItem <> nil do
       begin
         NextItem := GetNextItem(CurrentItem, SdAll, [IsSelected]);
         if DropItem = nil then
           DragItem := Items.Add
         else
           DragItem := Items.Insert(DropItem.Index);
         DragItem.Assign(CurrentItem);
         CurrentItem.Free;
         CurrentItem := NextItem;
       end;
     finally // Burada ekledim.
       Items.EndUpdate; // Burada ekledim.
     end; // Burada ekledim.
   end;
end;

Evet dediğiniz gibi   Items.BeginUpdate; Items.EndUpdate kullanarak test edince kırpmada azalma oldu. Allah razı olsun. +REP
Bazen DoubleBuffered özelliğinin hangi nesneye verileceği karışabiliyor. Ayrıca 'hwindow' olmayan bazı nesneler için bunların 'parent'ini kullanmak gerekiyor.

Grid gibi nesnelerde veriler hemen her zaman PAINT çağrıları ile 'çiziliyor'. Yani siz görüntüyü manipüle etmek isterseniz 'OnDraw' benzeri olayların içinde çizme işleminin arasına girip kendi istediğinizi gösterebilirsiniz.

Windows genellikle WinApi'deki WM_PAINT benzeri bir 'windows mesajı' iletir. Bu ilgili nesnenin gerekli kısımlarını çizmek için üretilir ve alt nesnelere doğru hiyerarşi şeklinde ilerleyebilir. Önce forma gelir, sonra panele, sonra panelin içindeki alt nesnelere, böyle böyle devam eder.

Demek ki siz OnDraw olayında bir şeyler yapacak olsanız bunlar sisteme külfet olmayıp, zaten yapılmakta olan bir iştir ve performans kaybı da olmaz.

Fakat her zaman bellekte çalışmak durumundasınız. VirtualGrid gibi nesneler böyle çalışır. Normal Grid'lerde de her satır için genellikle 'Data' adlı Pointer veya TObject türündeki bir değişkende satırdaki tüm bilgiler tutulur.

Her şeye rağmen boyama işlemi her zaman üretilmez, zira işletim sistemi sizin veride güncelleme yaptığınız bilmez. Bunun için de ekranın tazelenmesi için, örneğin DragDrop sonrasında Invalidate metodunu çağırırsınız. Böylelikle görüntü kaybından kurtulursunuz.
@ssahinoglu Bu güzel makale için teşekkür ederim Invalidate ilgi istediği gibi sonuç alamadım.

@mrmarman beyin dediği gibi kırpma durumu (style) skinden kaynaklanıyormuş.
Skini kaldırıp Windows hali ile sürükle bırak yaptığımda, gözlerim beni yanıltmıyorsa eyer kırpma sorunu yaşamıyorum.
Fakat bu seferde yapmış olduğum uygulamada maalesef görsel anlamda son derece basit oluyor. Bu sorunu nasıl çözeceğimi bilemiyorum.