Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - TListBox Item Suchen via Edit und andere Items ausblenden


Xearox - Mi 08.06.11 15:29
Titel: TListBox Item Suchen via Edit und andere Items ausblenden
Folgendes:

Ich habe folgenden Code programmiert mit hilfe von den DelphiTreff Tutorials.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure TForm2.E_ArtikelSucheKeyPress(Sender: TObject; var Key: Char);
var
  i:integer;
  suchstring:string[50];
begin
suchstring:=E_ArtikelSuche.Text;
  for i := 0 to LB_Artikel.Count -1 do
  begin
    if Pos(suchstring, LB_Artikel.Items[i]) > 0 then
    begin
      LB_Artikel.ItemIndex := i;
      break;
    end;
  end
end;


nun möchte ich in meiner Listbox nach etwas suchen, zum Beispiel 512...jetzt soll er bei Eingabe im Edit Feld alle anderen Items ausblenden und nur die Items mit 512 anzeigen.
Wenn ich nun weiter Tippe, also 512MB, soll er mir nur noch die Items mit 512MB anzeigen.

Mache ich jedoch den Text im Edit Feld wieder weg, soll er mir wieder alle Anzeigen, wie kann ich das am Besten Realisieren?


Gausi - Mi 08.06.11 15:36

Indem du deine Datenspeicherung von der Anzeige trennst.

D.h. Du hast irgendwo im Hintergrund in einer geeigneten Struktur (z.B. eine ObjectList) deine Daten gespeichert. Und dann kannst du auswählen, welche dieser Daten du in der Listbox angezeigt haben willst.


zuma - Mi 08.06.11 15:38

evtl. mit ner 2ten Liste ?
deine jetzige Listbox hälst du nur noch im Hintergrund, für die Anzeige nimmst du eine neue,
beim suchen nimmst du aus deiner hintergrundliste alle treffer in deine neue liste und fertig, wenn suche = leer, dann einfach alle aus hintergrundliste in anzeigeliste.

Edit: grmpf, etwas zu spät ...


jaenicke - Mi 08.06.11 15:41

Wobei es beim Filtern schneller ist, zwar die Daten im Hintergrund zu halten, aber dennoch bereits die visuellen Knoten vorzuhalten und nur passende sichtbar zu machen.

Das geht mit der TVirtualStringTree sehr gut.


Xearox - Mi 08.06.11 15:51

Also, die Listbox1 fülle ich mit daten aus einer Exceltabelle.
Wenn ich nun im suchfeld eingebe, 512, dann wird nur ein item markiert, welches die 512 enthält.

Ich habe mir schon folgende Gedanken gemacht, sagt mir, ob das ein Guter Anfang ist.

mit ListCount die Anzahl der Einträge herausfinden.
in einer Schleife bis zum letzten Item alles zu durchsuchen, was mit 512 zu tun hat.
Nun alle Items in der Listbox1 "entfernen" und die neuen Items, welche 512 enhalten in Listbox1 reinschreiben.
bei einem neuen zeichen wird die liste weiter reduziert.
bis dann nur noch ein Item übrig bleibt...


jaenicke - Mi 08.06.11 15:53

user profile iconXearox hat folgendes geschrieben Zum zitierten Posting springen:
in einer Schleife bis zum letzten Item alles zu durchsuchen, was mit 512 zu tun hat.
Nun alle Items in der Listbox1 "entfernen" und die neuen Items, welche 512 enhalten in Listbox1 reinschreiben.
Wenn, dann umgekehrt, zuerst die ListBox komplett leeren, dann deine Daten durchgehen und alle Einträge hinzufügen, die passen.

Aber wie gesagt: Viel einfacher und schneller geht es mit den VirtualTrees. Auch wenn man sich am Anfang etwas einarbeiten muss.


Xearox - Mi 08.06.11 15:56

hilft das hier mir weiter?
http://www.delphi-treff.de/tutorials/komponenten/virtualtreeview/einfuehrunginstallation/


jaenicke - Mi 08.06.11 16:01

Ja, da lernst du wie du damit umgehst. Und dann kannst du einfach die Sichtbarkeit entsprechend setzen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
var
  CurrentNode, FirstVisible: PVirtualNode;
begin
  CurrentNode := vstYourList.RootNode.FirstChild;
  FirstVisible := nil;
  while Assigned(CurrentNode) do
  begin
    ... vstYourList.GetNodeData(CurrentNode)^
    vstYourList.IsVisible[CurrentNode] := FilterMatches...;
    if not Assigned(FirstVisible) and vstYourList.IsVisible[CurrentNode] then
      FirstVisible := CurrentNode;
    CurrentNode := CurrentNode.NextSibling;
  end;
  vstYourList.ClearSelection;
  vstYourList.FocusedNode := nil;
  if Assigned(FirstVisible) then
  begin
    vstYourList.Selected[FirstVisible] := True;
    vstYourList.FocusedNode := FirstVisible;
  end;
Das ist so ca. der Standardfiltercode, den ich immer benutze.