需要一个带过滤功能的ComboBox

时间:2011-10-08 10:01:53

标签: delphi combobox components

我需要某种类型的ComboBox,它可以从DB加载它的项目。当我输入一些文本时,它应该过滤它的列表,只留下那些将我的文本放在某处(开头,中间......)的项目。并非我的所有DataSet都具有过滤功能,因此无法使用它们。有没有准备好使用具有这种能力的组件?我试图在JVCL中搜索,但没有运气。

2 个答案:

答案 0 :(得分:4)

您可以尝试自定义常规ComboBox的自动完成功能。从数据库加载项目很简单:

    ComboBox1.Items.Clear;   
    while not Table1.Eof do begin
      ComboBox1.Items.AddObject( Table1.FieldByName('Company').AsString,  
       TObject(Table1.FieldByName('CustNo').AsInteger) );
      Table1.Next;   
    end;

对于单词匹配的自动完成,您可以尝试调整this code。通过将AutoComplete设置为true来启用Items中文本开头匹配的功能,并且在尝试编写自动完成的OnChange事件处理程序之前需要关闭该功能。我建议您可以更安全地在输入键上进行匹配和选择,因为尝试在运行中进行操作会使事情变得非常毛茸茸,因为下面的代码会告诉您:

这是我的基本版本:使用带有onKeyDown的常规组合框和onChange事件,并将AutoComplete设置为false,使用上面的代码填充它,以及这两个事件

procedure TForm2.ComboBox1Change(Sender: TObject);
var
  SearchStr,FullStr: string;
  i,retVal,FoundIndex: integer;
  ctrl:TComboBox;
begin
  if fLastKey=VK_BACK then
       exit;

  // copy search pattern
  ctrl := (Sender as TCombobox);
  SearchStr := UpperCase(ctrl.Text);
  FoundIndex := -1;
  if SearchStr<>'' then
  for i := 0 to ctrl.Items.Count-1 do begin
    if Pos(SearchStr, UpperCase(ctrl.Items[i]))>0 then
    begin
       FoundIndex := i;
       fsearchkeys := ctrl.Text;
       break;
    end;
  end;

  if (FoundIndex>=0) then
  begin
    retVal := ctrl.Perform(CB_SELECTSTRING, 0, LongInt(PChar(ctrl.Items[FoundIndex]))) ;

    if retVal > CB_Err then
    begin
      ctrl.ItemIndex := retVal;
      ctrl.SelStart := Pos(SearchStr,UpperCase(ctrl.Text))+Length(SearchStr)-1;
      ctrl.SelLength := (Length(ctrl.Text) - Length(SearchStr));
    end; // retVal > CB_Err

  end; // lastKey <> VK_BACK

end;

procedure TForm2.ComboBox1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  fLastKey := Key;
end;

假设列表的内容是“David Smith”和“Mark Smithers”。在David Smith中键入S并且它匹配姓氏的第一个字母。现在它显示David Smith未选择“David S”部分,并选择“mith”部分(以便您键入的下一个字符将替换自动完成部分,标准自动完成技术)。请注意,上面的代码必须为您键入的S添加前缀,而不是您键入的“David”部分。如果你比我聪明得多,你可以找到一种方法来记住用户键入“s”然后,可能是“m”,然后是更多的字母,最后输入“Smithe”,匹配史密瑟斯,而不是大卫史密斯。另请注意,您只能将SelStart和SelLength设置为选择连续长度的字符串。

我提供的代码仅在项目列表中不包含任何重复的子字符串时才起作用。 Windows Common Control组合框“自动完成”功能仅适用于前缀匹配,而不适用于中间字符串匹配,这是有充分理由的。

因为任何实现中间字符串匹配的东西都应该绘制你未键入的部分,并且因为未选择的部分将位于中间字符串中,你可能需要从头开始编写自己的控件。不依赖于TComboBox基本代码及其基础MS Common Controls组合框功能。

答案 1 :(得分:0)

DevExpress'“TcxExtLookupCombobox”具有此功能 - 以及更多功能。可能会有点矫枉过正。