如何让TDBLookupComboBox显示您输入的内容?

时间:2015-04-30 16:16:44

标签: delphi delphi-xe7

我的表单上有TDBLookupComboBox

当我将光标放入其中并输入时,选择会跳到我输入的内容(或尽可能接近)。

但是,我没有得到任何关于我在该领域输入内容的迹象。

TDBComboBox的效果与TDBLookupComboBox类似,但是当我在字段中输入内容时,我输入的字符会显示在常规文字中,而“完成”字样也会显示在字段中。选择的出现在常规文本后面的反向/选择中。

有没有办法让TDBLookupComboBox在这方面表现得像TDBComboBox

1 个答案:

答案 0 :(得分:1)

不,你不能让TDBLookupComboBox像TDBComboBox一样(没有一点黑客攻击)。

问题是TDBLookupComboBox用于从另一个表中查找索引字段(通常是数字)。所选索引在目标字段中设置。当你制作TDBLookupComboBox" editable" (比如TDBComboBox),您可以键入任何内容,甚至不在源表中的值。这不应该发生(按设计)。您在目标字段中设置的索引值是什么?

您有几种选择。 你可以" hack" TDBLookupComboBox覆盖绘制过程以使用未选择的(已键入的)文本覆盖所选文本。这并不容易。特别是如果您想要正确维护功能。但是这里有一些代码,我认为我已经接近你想要的了。虽然在查找不在查找数据集中的内容时,它不会再进一步​​了。 (它也没有考虑正确对齐的文本等。):

type
  TDBLookupComboBox = class(DBCtrls.TDBLookupComboBox)
  protected
    procedure Paint; override;
    procedure KeyPress(var Key: Char); override;
  end;

type
  TForm1 = class(TForm)
    DBLookupComboBox1: TDBLookupComboBox;
//.....

procedure TDBLookupComboBox.Paint;
var
  TextPart: String;
begin
  inherited;
  Canvas.Font := Font;
  Canvas.Brush.Color := Color;
  // keeps case like the field is drawn
  TextPart := Copy(Text, 1, Length(SearchText));
  Canvas.TextOut(2, 2, TextPart);
end;

procedure TDBLookupComboBox.KeyPress(var Key: Char);
begin
  inherited;
  // we need this because paint is already called
  // we need to call it again to overwrite the text
  invalidate;
end;

它会覆盖表单顶部的DBLookupComboBox。您不必将其编译为新组件。您可以使用DBLookupComboBox将其粘贴到表单中。我们需要在按下之后再次调用Paint(使用invalidate),因为在进入该例程之前已经调用了paint。

另一种选择是使用TDBComboBox。您可以填写OnEnter中的pulldown项目。

procedure TForm1.DBComboBox1Enter(Sender: TObject);
begin
  DBComboBox1.Items.Clear;
  IBQuery1.First;
  while not IBQuery1.EOF do
  begin
    DBComboBox1.Items.Add(IBQuery1.FieldByName('TESTFIELD').DisplayText);
    IBQuery1.Next;
  end;
end;

如果速度太慢(进入组合框时),您也可以在打开数据集时填充项目。

Jedi-library的另外几个选项:

JvDBLookupCombo1
打字时直接下拉。原始类型文本保留在框中。

TJvDBSearchComboBox
也可以做你想要的但没有连接到目标数据源。您需要在OnExit上自行设置所需的字段。