如何禁用LCL空TListBox聚焦后按空格弹出搜索框功能
问题:Lazarus GTK2 下空TListBox按空格弹出搜索框如何关闭
开发环境
- FreePascal 3.2.0
- Lazarus 2.0.12
- GTK2 GUI 后端
- Ubuntu Linux 18.04 操作系统
问题描述
我遇到了 TListBox 组件的异常行为:
- 点击聚焦空的 ListBox(调用 SetFocus)后
- 按下 [空格] 键,会弹出类似编辑框或搜索框的控件(见下图)。
- 该控件会在3秒左右自动消失。
请问如何关闭这个「特性」?
现有临时方案
我目前的临时解决方案是使用 onEnter 事件的处理程序,判断列表为空时转移 ListBox 的焦点,代码片段如下:
procedure TFrmMain.lbxTestEnter(Sender: TObject); begin if mUseWorkAround then begin if LbxTest.Items.Count = 0 then begin PnlButton.SetFocus; exit; end; end; end;
我不确定这个方案是否是最优解,寻求更合理的解决方法。
完整复现代码
unit UFrmTestListBox; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls; const PNL_MESSAGE = 'WORK AROUND IS %sACTIVE! '; type { TFrmMain } TFrmMain = class(TForm) BtnToggle: TButton; GbxList: TGroupBox; GbxLog: TGroupBox; LbxTest: TListBox; MmLog: TMemo; PnlButton: TPanel; SplMain: TSplitter; procedure BtnToggleClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure lbxTestEnter(Sender: TObject); private mUseWorkAround: Boolean; mCounter: Integer; procedure OutLn(S:String); public end; var FrmMain: TFrmMain; implementation {$R *.lfm} procedure TFrmMain.FormCreate(Sender: TObject); begin mUseWorkAround:= false; mCounter := 0; PnlButton.Caption:=Format(PNL_MESSAGE,['NOT ']); end; procedure TFrmMain.lbxTestEnter(Sender: TObject); begin inc(mCounter); OutLn(''); OutLn(Format('--- %d -----------------------', [mCounter])); OutLn('ListBox onEnter event'); if mUseWorkAround then begin OutLn('Work around is active!'); if LbxTest.Items.Count = 0 then begin OutLn('ListBox is empty, change focus to the button panel.'); PnlButton.SetFocus; exit; end; end else begin OutLn('Work around NOT active!'); OutLn('ListBox is empty, press [SPACE] & EditField appears.') end; end; procedure TFrmMain.BtnToggleClick(Sender: TObject); begin mUseWorkAround:=not mUseWorkAround; if mUseWorkAround then PnlButton.Caption:=Format(PNL_MESSAGE,['']) else PnlButton.Caption:=Format(PNL_MESSAGE,['NOT ']); end; procedure TFrmMain.OutLn(S:String); begin MmLog.Lines.BeginUpdate; MmLog.Lines.Append(S); MmLog.Lines.EndUpdate; MmLog.SelStart := Length(MmLog.Lines.Text); end; end.
解决方案
这个弹出框是GTK2原生列表控件自带的增量搜索功能,不是Lazarus封装的bug,有两种更合理的解决方式,都比转移焦点的方案体验更好:
方案1:完全关闭搜索功能(最优解,一行代码搞定)
如果你的业务场景完全不需要ListBox的键盘搜索功能,直接关闭对应属性即可,不管列表是否为空都不会再弹出搜索框:
在Form的Create事件中添加一行代码:
procedure TFrmMain.FormCreate(Sender: TObject); begin // 原有代码不变,新增下面这行 LbxTest.Search := False; mUseWorkAround:= false; mCounter := 0; PnlButton.Caption:=Format(PNL_MESSAGE,['NOT ']); end;
你也可以直接在IDE的对象检查器里找到LbxTest的Search属性,设为False即可,连代码都不用写。
方案2:仅空列表时禁用搜索(保留非空时的搜索能力)
如果你需要保留列表有内容时的增量搜索功能,只需要拦截空列表时的键盘输入即可,不会打乱用户的焦点操作预期:
给LbxTest添加OnKeyPress事件处理:
procedure TFrmMain.lbxTestKeyPress(Sender: TObject; var Key: char); begin if LbxTest.Items.Count = 0 then // 拦截所有可打印字符,不触发搜索逻辑 Key := #0; end;
原来的转移焦点方案存在体验问题:用户主动点击选中列表框时,焦点无故跳走会打断操作预期,上面两种方案都没有这个问题。
内容的提问来源于stack exchange,提问作者huckfinn
相关产品推荐
相关产品推荐

