We have a combo box with more than 100 items.
We want to filter out the items as we enter characters in combo box. For example if we entered 'ac' and click on the drop down option then we want it to display items starting with 'ac' only.
How can I do this?
Maybe you'd be happier using the autocompletion features built in to the OS. I gave an outline of how to do that here previously. Create an IAutoComplete object, hook it up to your combo box's list and edit control, and the OS will display a drop-down list of potential matches automatically as the user types. You won't need to adjust the combo box's list yourself.
To expand on Rob's answer about using the OnChange event, here is an example of how to do what he suggests.
procedure TForm1.FormCreate(Sender: TObject);
begin
  FComboStrings := TStringList.Create;
  FComboStrings.Add('Altair');
  FComboStrings.Add('Alhambra');
  FComboStrings.Add('Sinclair');
  FComboStrings.Add('Sirius');
  FComboStrings.Add('Bernard');
  FComboStrings.Sorted := True;
  ComboBox1.AutoComplete := False;
  ComboBox1.Items.Text := FComboStrings.Text;
  ComboBox1.Sorted := True;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
  FreeAndNil(FComboStrings);
end;
procedure TForm1.ComboBox1Change(Sender: TObject);
var
  Filter: string;
  i: Integer;
  idx: Integer;
begin
  // Dropping down the list puts the text of the first item in the edit, this restores it
  Filter := ComboBox1.Text;
  ComboBox1.DroppedDown := True;
  ComboBox1.Text := Filter;
  ComboBox1.SelStart := Length(Filter);
  for i := 0 to FComboStrings.Count - 1 do
    if SameText(LeftStr(FComboStrings[i], Length(ComboBox1.Text)), ComboBox1.Text) then
    begin
      if ComboBox1.Items.IndexOf(FComboStrings[i]) < 0 then
        ComboBox1.Items.Add(FComboStrings[i]);
    end
    else
    begin
      idx := ComboBox1.Items.IndexOf(FComboStrings[i]);
      if idx >= 0 then
        ComboBox1.Items.Delete(idx);
    end;
end;
My brief contribution working with objects in the combobox:
procedure FilterComboBox(Combo: TComboBox; DefaultItems: TStrings);
  function Origin: TStrings;
  begin
    if Combo.Tag = 0 then
    begin
      Combo.Sorted := True;
      Result := TStrings.Create;
      Result := Combo.Items;
      Combo.Tag := Integer(Result);
    end
    else
      Result := TStrings(Combo.Tag);
  end;
var
  Filter: TStrings;
  I: Integer;
  iSelIni: Integer;
begin
  if(Combo.Text <> EmptyStr) then
  begin
    iSelIni:= Length(Combo.Text);
    Filter := TStringList.Create;
    try
      for I := 0 to Origin.Count - 1 do
        if AnsiContainsText(Origin[I], Combo.Text) then
          Filter.AddObject(Origin[I], TObject(Origin.Objects[I]));
        Combo.Items.Assign(Filter);
        Combo.DroppedDown:= True;
        Combo.SelStart := iSelIni;
        Combo.SelLength := Length(Combo.Text);
    finally
      Filter.Free;
    end;
  end
  else
    Combo.Items.Assign(DefaultItems);
end;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With