delphidelphi-xe6tlistbox

Filtering a Listbox using an Edit box


I'm trying to filter a listbox in Delphi using an Edit box, but it's not working. Here's my code based on the OnChange event of an Edit box.

procedure TReportDlgForm.FilterEditOnChange(Sender: TObject);
var
  I: Integer;
begin
  ListBox1.Items.BeginUpdate;
  try
    for I := 0 to ListBox1.Items.Count - 1 do
      ListBox1.Selected[I] := ContainsText(ListBox1.Items[I], FilterEdit.Text);
  finally
    ListBox1.Items.EndUpdate;
  end;
end;

I'm hoping that when I type in my edit box that the Listbox items will filter.


Solution

  • You must keep values from your list box in some variable and make search in this variable, not in ListBox items! In ListBox we only going to show result of search.

    type
      TForm1 = class(TForm)
        Edit1: TEdit;
        ListBox1: TListBox;
        procedure Edit1Change(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
      private
        { Private declarations }
        FList: TStringList;
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    uses
      System.StrUtils;
    
    {$R *.dfm}
    
    procedure TForm1.Edit1Change(Sender: TObject);
    var
      I: Integer;
      S: String;
    begin
      ListBox1.Items.BeginUpdate;
      try
        ListBox1.Clear;
        if Edit1.GetTextLen > 0 then begin
          S := Edit1.Text;
          for I := 0 to FList.Count - 1 do begin
            if ContainsText(FList[I], S) then
              ListBox1.Items.Add(FList[I]);
          end;
        end;
      finally
        ListBox1.Items.EndUpdate;
      end;
    end;
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      FList := TStringList.Create;
      FList.Assign(ListBox1.Items);
    end;
    
    procedure TForm1.FormDestroy(Sender: TObject);
    begin
      FList.Free;
    end;