[ krle_zr @ 17.09.2010. 18:24 ] @
Pozdrav, zanima me kako mogu pretraziti listu za odredjenim nazivom objekta i ukloniti one koji ne pripadaju trazenom stringu. Radim na inkrementalnoj pretrazi ListView-a i skoro sam resio ali mi uvek ostaje zadnji objekt u listi ukoliko je nesto pronadjeno. Ne znam kako da prodjem kroz celu listu a da na kraju ne moram da testiram uslov:

Code:

...
until (gi.Items.Count = 0) or (gi.Items.Items[N] = gi.Items.Last);

gi je klasa koja ima svojstvo fItems: TObjectList i ono sluzi za prikaz podataka u listview kao tree

Inace mi u suprotnom izbacuje Exception. Ukoliko nesto nije jasno pisite slobodno postovacu ceo kod.

[ Almedin @ 18.09.2010. 13:11 ] @
Hoces ukloniti one koji ne zadovoljavaju neki uslov?

Može li ovako

Code:
for i := gi.Items.Count - 1 downto 0 do
  if gi.Items[i].Name = 'nesto' then gi.Remove(gi.Items[i]);
[ krle_zr @ 18.09.2010. 14:16 ] @
Probao sam medjutim, sad mi brise sve (uopste ne prolazi uslov, cak i kad je nasao zeljeni string) a u debageru dobijam EListError exception na nekoj adresi.

Evo koda:

Code:

{TItem je stavka listiview-a (i ima polja Title i Value) koja je vezana za gi}
var
  gi: TGroupItem;
  I, N, J: Integer;

begin
  I := 0;
  while lvGroups.Items[I] <> nil do
  begin
    if Tobject(lvGroups.Items[I].data) is TGroupItem then
    begin
      gi := TGroupItem(lvGroups.Items[I].Data);
      if gi.Expanded then gi.Collapse;
//      N := 0;
//      while gi.Items.Items[N] <> nil do 
//      repeat
      for gi.Items.Count - 1 downto 0 do
      begin
        if not (TItem(gi.Items[N]).Title = 'Group C item 2') then
        //inc (N);
        gi.Items.Remove(gi.Items[N])

//      until (gi.Items.Count = 0) or (gi.Items.Items[N] = gi.Items.Last);
      end;
      if gi.Items.Count > 1 then
      begin
        gi.Expand;
        Caption := 'Found';
        lvGroups.SetFocus;
        TlistItem(lvGroups.FindCaption(I, 'Group C item 2', False, True, False)).Selected := True;
        Inc(I);
      end
      else lvGroups.Items[I].Delete;
    end
    else Inc (I);

  end;
end;




[ Almedin @ 18.09.2010. 14:49 ] @
Ja sam razumio da je gi: TList, a u stvari je TGroupItem. Šta je TGroupItem?

Iz tvog koda naslućujem da bi moglo ovako:

Citat:
for gi.Items.Count - 1 downto 0 do
begin
if not (TItem(gi.Items.Items[N]).Title = 'Group C item 2') then
gi.Items.Items.Remove(gi.Items.Items[N]) // ili gi.Items.Remove(gi.Items.Items[N])
end;


[ krle_zr @ 18.09.2010. 15:01 ] @
Ovako, nasao sam na netu primer kako da u D7 grupisem stavke ListView-a. Svidelo mi se, pa sam pokusao da modifikujem primer i obezbedim pretragu. Ja sam uradio nesto repeat petljom, medjutim tu mi ne brise poslednju stavku ukoliko pronadje nesto. Prvo sam pokusao da sve stavke prikazem (expand all) pa onda da pretrazim ali mislim da je ovako brze jer direktno pretrazujem listu, brisem podatke a izbacujem samo trazene rezultate ukoliko ih ima.

U primeru sam dodao 8 grupa, trazi se stavka (Group C item 2) i ima je na dva mesta.
[ nikomak @ 18.09.2010. 15:31 ] @
Uh, ovaj kod je dosta haotican i lose organizovan.

U svakom slucaju za btn find

Code:

procedure TForm1.btnFindClick(Sender: TObject);
var
  gi: TGroupItem;
  I: integer;
  li: TListItem;
  K: integer;
begin
  I := 0;
  while lvGroups.Items[I] <> nil do
  begin
    if TObject(lvGroups.Items[I].Data) is TGroupItem then
    begin
      gi := TGroupItem(lvGroups.Items[I].Data);
      if gi.Expanded then
        gi.Collapse;

      for K := gi.Items.Count - 1 downto 0 do
        if TItem(gi.Items[K]).title <> 'Group C item 2' then
          gi.Items.Delete(K);

      if gi.Items.Count > 0 then
      begin
        gi.Expand;
        caption := 'Found';
        lvGroups.SetFocus;
        li := lvGroups.FindCaption(I, 'Group C item 2', false, true, false);
        if Assigned(li) then
          li.Selected := true;
        Inc(I);
      end
      else
        lvGroups.Items[I].Delete;
    end
    else
      Inc(I);

  end;
end;

[ krle_zr @ 18.09.2010. 15:47 ] @
Hvala obojci, sad je ok.

Pozdrav
[ rambo @ 19.09.2010. 22:57 ] @
Imam jedan praktičan predlog. Umesto da se mučiš sa TListView, pokušaj da koristiš VirtualTreeView. Veoma je moćna komponenta i omogućava da radiš neke veoma neverovatne stvari koje nećeš moći ni sa jednom drugom alternativom.

http://www.soft-gems.net/index...k=view&id=12&Itemid=33

Moraćeš malo da se potrudiš da razumeš kako se pravilno radi sa komponentom, ali kada to prođeš, više nećeš hteti da koristiš bilo šta drugo. Prednosti VirtualTreeView-a su ogromne. Podatke možeš da prikažeš kao običnu listu sa više kolona ili kao stablo sa neograničenim brojem nivoa. Možeš da učitaš teoretski neograničen broj redova (ograničen si samo raspoloživom količinom memorije), a rad sa njima ti neće biti usporen. Ti sam definišeš šta se nalazi u svakom redu (Node) i na taj način možeš da kontrolišeš šta se prikazuje a šta se koristi "ispod haube". Nije potrebno da posebno alociraš/dealociraš memoriju koja se koristi za svaki nod jer komponenta se sama brine o tome. Komponenta je inače potpuno Unicode što znači da nećeš imati problema da prikažeš bilo kakav tekst. Mogućnosti su praktično neograničene. Imaš dosta urađenih gotovih primera koji ilustruju neke od mogućnosti komponente a i help je veoma dobro urađen.

Nadam se da će ti ovo pomoći da rešiš neke od trenutnih ili budućih problema. Ukoliko negde zapneš, probaćemo da pomognemo, ali ti definitivno proporučujem da probaš VirtualTreeView. Običan TListView je dobar jedino za prikazivanje male do srednje količine podataka. Nije predviđen za prikaz podataka u obliku stabla. Postoji "virtuelna" podrška, ali je daleko manje fleksibilna. Sam moraš da se baviš rezervisanjem i oslobađanjem memorije što ume da bude veoma nezgodan posao. Iscrtavanje ume da bude veoma sporo kada se radi o velikoj koluičini podataka. Jedna od najgorih osobina je pretraživanje jer moraš da prolaziš kroz celu listu.

Nadam se da nisam preterao u opisivanju

Probaj pa sam prosudi.