如何使全文检索支持自动完成的组合框? [英] How to make a combo box with fulltext search autocomplete support?

查看:168
本文介绍了如何使全文检索支持自动完成的组合框?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想一个用户能够从 TComboBox 项目,并为该项目类型在第二或第三个字出现在的AutoSuggest 下拉选项

I would like a user to be able to type in the second or third word from a TComboBox item and for that item to appear in the AutoSuggest dropdown options

例如,组合框包含项目:

For example, a combo box contains the items:


  • 主席约翰·布朗

  • 太太阿曼达·布朗

  • 主席布赖恩·琼斯

  • 夫人萨曼莎·史密斯

当用户键入BR下拉列表中显示:

When the user types "Br" the dropdown displays:


  • 主席约翰·布朗

  • 太太阿曼达·布朗

  • 主席布赖恩·琼斯

和当用户键入乔下拉列表中显示:

and when the user types "Jo" the dropdown displays:


  • 主席约翰·布朗

  • 主席布赖恩·琼斯

问题是,的AutoSuggest 功能只包括在下拉列表中,与哪些用户有输入等上面没有任何的例子开始将出现在下拉列表中的项目。

The problem is that the AutoSuggest functionality only includes items in the dropdown list that begin with what the user has input and so in the examples above nothing will appear in the dropdown.

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

Is it possible to use the IAutoComplete interface and/or other related interfaces to get around this issue?

推荐答案

下面的示例使用插入的类的 TComboBox 组件。从原始类的主要区别是,项目被存储在独立的 StoredItems 属性,而不是结果,在<一href=\"http://docwiki.embarcadero.com/Libraries/XE2/en/Vcl.StdCtrls.TComboBox.Items\"><$c$c>Items作为一般(使用,因为简单)。结果

The following example uses the interposed class of the TComboBox component. The main difference from the original class is that the items are stored in the separate StoredItems property instead of
the Items as usually (used because of simplicity).

StoredItems 正在观看<一个href=\"http://docwiki.embarcadero.com/Libraries/en/System.Classes.TStringList.OnChange\"><$c$c>OnChange事件每当你(通过添加或从该字符串列表中删除,例如)更改,当前的过滤器将反映甚至当组合结果列表中掉了下来。

The StoredItems are being watched by the OnChange event and whenever you change them (for instance by adding or deleting from this string list), the current filter will reflect it even when the combo
list is dropped down.

这里的要点是抓住<一个href=\"http://msdn.microsoft.com/en-us/library/windows/desktop/ms647591%28v=vs.85%29.aspx\"><$c$c>WM_COMMAND消息通知<一个href=\"http://msdn.microsoft.com/en-us/library/windows/desktop/bb775814%28v=vs.85%29.aspx\"><$c$c>CBN_EDITUPDATE其中,每当组合编辑文本更改,但还没有呈现被​​发送。当它到来时,你只需通过 StoredItems 列表你在你的组合编辑键入搜索,并填写<一个href=\"http://docwiki.embarcadero.com/Libraries/XE2/en/Vcl.StdCtrls.TComboBox.Items\"><$c$c>Items财产的比赛。

The main point here is to catch the WM_COMMAND message notification CBN_EDITUPDATE which is being sent whenever the combo edit text is changed but not rendered yet. When it arrives, you just search through the StoredItems list for what you have typed in your combo edit and fill the Items property with matches.

有关文本搜索使用<一个href=\"http://docwiki.embarcadero.com/Libraries/en/System.StrUtils.ContainsText\"><$c$c>ContainsText所以搜索不区分大小写。忘了提,维基,<一个href=\"http://docwiki.embarcadero.com/Libraries/en/Vcl.StdCtrls.TComboBox.AutoComplete\"><$c$c>AutoComplete特征已被关闭,因为它有自己的,不受欢迎,逻辑用于此目的。

For text searching is used the ContainsText so the search is case insensitive. Forgot to mention,
the AutoComplete feature has to be turned off because it has its own, unwelcomed, logic for this purpose.

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, 0, 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.

这篇关于如何使全文检索支持自动完成的组合框?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆