delphi – 如何使一个组合框与全文搜索自动完成支持?

前端之家收集整理的这篇文章主要介绍了delphi – 如何使一个组合框与全文搜索自动完成支持?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我希望用户能够从TComboBox项目中输入第二个或第三个单词,并且该项目将显示在AutoSuggest下拉列表选项中

例如,组合框包含以下项目:

>约翰·布朗先生
>阿曼达·布朗夫人
>布赖恩·琼斯先生
> Samantha Smith夫人

用户键入“Br”时,下拉列表显示

>约翰·布朗先生
>阿曼达·布朗夫人
>布赖恩·琼斯先生

用户键入“Jo”时,下拉列表显示

>约翰·布朗先生
>布赖恩·琼斯先生

问题是AutoSuggest功能包括下拉列表中的项目,从用户输入的内容开始,因此在上述示例中,下拉列表中不会出现任何内容

可以使用IAutoComplete接口和/或其他相关的接口来解决这个问题吗?

解决方法

以下示例使用插入的 TComboBox组件类。与原始类的主要区别在于,项目存储在单独的StoredItems属性中,而不是通常为 Items(由于简单而使用)。

StoredItems被OnChange事件监视,每当您更改它们(例如通过从该字符串列表中添加删除)时,即使当Combolist被删除时,当前的过滤器也将反映出来。

这里的要点是抓住WM_COMMAND消息通知CBN_EDITUPDATE,每当组合编辑文本更改但尚未呈现时,该消息通知正在发送。当它到达时,您只需搜索StoredItems列表中您在组合编辑中键入的内容,并使用匹配填充Items属性

使用ContainsText进行文本搜索,因此搜索不区分大小写。忘了提及,AutoComplete功能必须关闭,因为它有自己的,不欢迎的逻辑为此目的。

unit Unit1;

interface

uses
  Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,Dialogs,StdCtrls,StrUtils,ExtCtrls;

type
  TComboBox = class(StdCtrls.TComboBox)
  private
    FStoredItems: TStringList;
    procedure FilterItems;
    procedure StoredItemsChange(Sender: TObject);
    procedure SetStoredItems(const Value: TStringList);
    procedure CNCommand(var AMessage: TWMCommand); message CN_COMMAND;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    property StoredItems: TStringList read FStoredItems write SetStoredItems;
  end;

type
  TForm1 = class(TForm)
    ComboBox1: TComboBox;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

constructor TComboBox.Create(AOwner: TComponent);
begin
  inherited;
  AutoComplete := False;
  FStoredItems := TStringList.Create;
  FStoredItems.OnChange := StoredItemsChange;
end;

destructor TComboBox.Destroy;
begin
  FStoredItems.Free;
  inherited;
end;

procedure TComboBox.CNCommand(var AMessage: TWMCommand);
begin
  // we have to process everything from our ancestor
  inherited;
  // if we received the CBN_EDITUPDATE notification
  if AMessage.NotifyCode = CBN_EDITUPDATE then
    // fill the items with the matches
    FilterItems;
end;

procedure TComboBox.FilterItems;
var
  I: Integer;
  Selection: TSelection;
begin
  // store the current combo edit selection
  SendMessage(Handle,CB_GETEDITSEL,WPARAM(@Selection.StartPos),LPARAM(@Selection.EndPos));
  // begin with the items update
  Items.BeginUpdate;
  try
    // if the combo edit is not empty,then clear the items
    // and search through the FStoredItems
    if Text <> '' then
    begin
      // clear all items
      Items.Clear;
      // iterate through all of them
      for I := 0 to FStoredItems.Count - 1 do
        // check if the current one contains the text in edit
        if ContainsText(FStoredItems[I],Text) then
          // and if so,then add it to the items
          Items.Add(FStoredItems[I]);
    end
    // else the combo edit is empty
    else
      // so then we'll use all what we have in the FStoredItems
      Items.Assign(FStoredItems)
  finally
    // finish the items update
    Items.EndUpdate;
  end;
  // and restore the last combo edit selection
  SendMessage(Handle,CB_SETEDITSEL,MakeLParam(Selection.StartPos,Selection.EndPos));
end;

procedure TComboBox.StoredItemsChange(Sender: TObject);
begin
  if Assigned(FStoredItems) then
    FilterItems;
end;

procedure TComboBox.SetStoredItems(const Value: TStringList);
begin
  if Assigned(FStoredItems) then
    FStoredItems.Assign(Value)
  else
    FStoredItems := Value;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  ComboBox: TComboBox;
begin
  // here's one combo created dynamically
  ComboBox := TComboBox.Create(Self);
  ComboBox.Parent := Self;
  ComboBox.Left := 10;
  ComboBox.Top := 10;
  ComboBox.Text := 'Br';

  // here's how to fill the StoredItems
  ComboBox.StoredItems.BeginUpdate;
  try
    ComboBox.StoredItems.Add('Mr John Brown');
    ComboBox.StoredItems.Add('Mrs Amanda Brown');
    ComboBox.StoredItems.Add('Mr Brian Jones');
    ComboBox.StoredItems.Add('Mrs Samantha Smith');
  finally
    ComboBox.StoredItems.EndUpdate;
  end;

  // and here's how to assign the Items of the combo Box from the form 
  // to the StoredItems; note that if you'll use this,you have to do
  // it before you type something into the combo's edit,because typing 
  // may filter the Items,so they would get modified
  ComboBox1.StoredItems.Assign(ComboBox1.Items);
end;    

end.

猜你在找的Delphi相关文章