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