delphi dev cxLookupComboBox 模糊搜索

//不是过滤DATASET,适合用在下拉数据很多的情况。过滤的必须是下拉有添加的列
procedure cxLookupComboBoxLikeSearchInitPopup(Sender: TObject);
var
 FEdit: TcxLookupComboBox absolute Sender;
 i: integer;
begin
// if FEdit.Properties.IncrementalSearch then
//  FEdit.Properties.IncrementalSearch := False;
 with FEdit.Properties.DataController, Filter do
 begin
  Clear;
  Options := [fcoCaseInsensitive]; //不区分大小写
  Root.BoolOperatorKind := fboOR;
  if Root.IsEmpty then
  begin
   //提前加载过滤条件
   for i := 0 to FEdit.Properties.ListColumns.Count -1 do
    Root.AddItem(FEdit.Properties.ListColumns[i], foLike, '', '');
  end;
  Active := False;
 end;
end;

procedure cxLookupComboBoxLikeSearchChange(Sender: TObject);
var
 FEdit: TcxLookupComboBox absolute Sender;
 i: integer;
 InputText :string;
 KeyIndex: integer;
begin
 if FEdit.Tag = 1 then
  Exit;
 InputText := FEdit.Text;
 with FEdit.Properties.DataController, Filter do
 begin
  if (InputText = '') then
  begin
   Active := False;
   Exit;
  end;
  if not Root.IsEmpty then  //第一次用滚轮的话没有触发 oninit所以不能执行下面的
  begin
   try
    //要加beginupdate endupdate 不然下面获取相关FocusedIndex 不会刷新
    FEdit.Properties.Grid.BeginUpdate;
    Active := False;
    for i := 0 to FEdit.Properties.ListColumns.Count -1 do
     TcxFilterCriteriaItem(Root.Items[i]).Value := '%'+FEdit.Text+'%';
    Active := True;
   finally
    FEdit.Properties.Grid.EndUpdate;
   end;
   //过滤有符合条件的数据
   if FEdit.Properties.DataController.RowCount > 0 then
   begin
    //没有选中,重新找一下keyindex 比如1584- 有匹配到数据,然后退格删掉-  这时就没有选中了。这个是BUG这里要处理一下
    if FEdit.Properties.DataController.GetSelectedCount = 0 then
    begin
     //重新找一下
     KeyIndex := FEdit.Properties.DataController.FindRecordIndexByText(0, FEdit.Properties.ListFieldIndex,InputText, True, False, True);
     {
     说明:

     FEdit.Properties.DataController.FocusedDataRowIndex
     //可以理解为表格看得见的焦点index,表格有可能会过滤。FocusedDataRowIndex 目前看到的效果是等价FocusedRowIndex
     FEdit.Properties.DataController.FocusedRowIndex
     //所有数据的焦点index,拿数据用这个。如果要拿表格当前视图的就可以
     FEdit.Properties.DataController.FocusedRecordIndex

     获得的KeyIndex是所有记录的index这里过滤了所以要转换成过滤后的index
     比如222# 在没有过滤的情况index=10 过滤出来只有5条记录他是排在第2条
     这里设置的FocusedRowIndex 是基于过滤出来的数据,所以应该设置2才对
     需要通过 FilteredIndexByRecordIndex 转换一下

     }
     if KeyIndex <> -1 then
     begin
      KeyIndex := FEdit.Properties.DataController.FilteredIndexByRecordIndex[KeyIndex];
      //设置回焦点行,同步一下
      FEdit.Properties.DataController.FocusedRowIndex := KeyIndex;
      FEdit.Properties.Grid.SyncSelected(True);
     end;
    end
    else
     KeyIndex := FEdit.Properties.DataController.FocusedRowIndex;
    //DEV内部处理 FEdit.Properties.Grid.TopRowIndex 的有问题,上面都是定位到FocusedRecordIndex
    //但是没有显示选中,是因为看不见。这里重新去调用处理一下
    FEdit.Properties.Grid.MakeRowVisible(KeyIndex);
   end;
  end;
 end;
end;

procedure cxLookupComboBoxLikeSearchCloseUp(Sender: TObject);
var
 FEdit: TcxLookupComboBox absolute Sender;
begin
 //没有数据行,又有内容.过滤失败
 if (FEdit.Properties.DataController.RowCount = 0) and (FEdit.Text <> '') then
 begin
  FEdit.Tag :=1;
  FEdit.Text := '';
  //这里可以写上修改ado的值 这里只是写个模板而已
  FEdit.Tag := 0;
 end;
 FEdit.Properties.DataController.Filter.Active := False;
end;

procedure cxLookupComboBoxLikeSearchEditValueChanged(Sender: TObject);
var
 FEdit: TcxLookupComboBox absolute Sender;
 KeyIndex: integer;
 InputText: string;
begin
 if FEdit.Tag =1 then
  Exit;
 try
  FEdit.Tag := 1;
  KeyIndex := -1;
  if FEdit.Text <> '' then
   KeyIndex := FEdit.Properties.DataController.FocusedRecordIndex;
//  Value1 := '';
//  Value2 := '';
  if KeyIndex <> -1 then
  begin
   //这里只写示例,取第一列,第二例的值。
//   Value1 := FEdit.Properties.DataController.Values[KeyIndex, 0];
//   Value2 := FEdit.Properties.DataController.Values[KeyIndex, 1];
  end
  else
    FEdit.Text := '';
  //同步修改ado的值
//  ADOQuery2.Edit;
//  ADOQuery2.FieldByName('xx').Value := Value1;
//  ADOQuery2.FieldByName('xx').Value := Value2;
//  ADOQuery2.Post;
 finally
  FEdit.Tag := 0;
 end;
end;

用之前请设置

Properties.IncrementalSearch = False

GridMode = False

DropDownListStyle = lsEditList

关闭GridMode后, 输入后回车:

离开焦点后,如果输入的内容是下拉列表没有的, 事件触发顺序:

PropertiesCloseUp
PropertiesEditValueChanged (不会触发)

有的存在下拉列表的话,事件触发顺序:

PropertiesEditValueChanged 

PropertiesCloseUp

如果是输入后,用鼠标离开焦点,则什么先触发closeup

适合场景为:下拉数据很多的情况下,一般下拉的数据来源都是用dataset。
当下拉数据有3W条时,非常卡。

DEV版本为: devcl20120105

posted @ 2023-11-19 10:01  Tag  阅读(290)  评论(0编辑  收藏  举报