I always do like this (and I do it quite often):
I have an array of string
or a TStringList
containing the list-box items. Then, in Edit1Change
I clear the Items property and add only those strings that match the text in the edit box.
Array Of String
If you work with an array of strings, such as
var
arr: array of string;
that is initialized somehow, as in
procedure TForm1.FormCreate(Sender: TObject);
begin
SetLength(arr, 3);
arr[0] := 'cat';
arr[1] := 'dog';
arr[2] := 'horse';
end;
then you can do
procedure TForm1.Edit1Change(Sender: TObject);
var
i: Integer;
begin
ListBox1.Items.BeginUpdate;
ListBox1.Items.Clear;
if length(Edit1.Text) = 0 then
for i := 0 to high(arr) do
ListBox1.Items.Add(arr[i])
else
for i := 0 to high(arr) do
if Pos(Edit1.Text, arr[i]) > 0 then
ListBox1.Items.Add(arr[i]);
ListBox1.Items.EndUpdate;
end;
This will only display those strings in the array that contain Edit1.Text
; the string need not start with Edit1.Text
. To accomplish this, replace
Pos(Edit1.Text, arr[i]) > 0
with
Pos(Edit1.Text, arr[i]) = 1
TStringList
In case of a TStringList
, as in
var
arr: TStringList;
and
procedure TForm1.FormCreate(Sender: TObject);
begin
arr := TStringList.Create;
arr.Add('cat');
arr.Add('dog');
arr.Add('horse');
end;
you can do
procedure TForm1.Edit1Change(Sender: TObject);
var
i: Integer;
begin
ListBox1.Items.BeginUpdate;
ListBox1.Items.Clear;
if length(Edit1.Text) = 0 then
ListBox1.Items.AddStrings(arr)
else
for i := 0 to arr.Count - 1 do
if Pos(Edit1.Text, arr[i]) = 1 then
ListBox1.Items.Add(arr[i]);
ListBox1.Items.EndUpdate;
end;
Case-Sensitivity
The above code uses case-sensitive matching, so that "bo" will not match "Boston", for instance. To make the code not sensitive to the case, write
if Pos(AnsiLowerCase(Edit1.Text), AnsiLowerCase(arr[i])) > 0 then
instead of
if Pos(Edit1.Text, arr[i]) > 0 then