如何使用数据库数据(VCL)快速填充组合框

时间:2014-01-17 10:01:29

标签: database delphi combobox dataset lookup

我已经在网上阅读了各种各样的文档,这些文档应该是一个非常常见和无痛的实现。由于我没有找到一致且光滑的回复(即使Embarcadero网站描述了一些错误的属性!)我将发布一个“简短”的方法。

典型的,经常使用的情况:开发人员只想在一个组合框中显示一些数据库提取的信息(即语言选择),从中获取用户的选择,就是这样。

要求:

  1. Delphi,或多或少任何版本。 VCL已被覆盖。
  2. 数据库表。我们假设一个包含idvalue字段的简单表格。
  3. DataSet(包括查询和ClientDataSets)。
  4. 链接到DataSet的DataSource。
  5. 链接到DataSource的TDBLookupComboBox,它将显示值列表并“返回”当前选择的ID。

1 个答案:

答案 0 :(得分:6)

首先,我们决定排序顺序是否是我们想要的顺序,以及是否必须显示该表中的所有项目。通常,简单的ORDER BY子句或DataSet索引就足够了。如果不是,我们可以添加sort_order字段并用表示我们自定义排序顺序的整数填充它。如果我们只想显示一些项目,我们会添加visibleenabled字段并在我们的SQL中使用它。例如:

SELECT id, value
FROM my_database_table
WHERE visible = 1
ORDER BY sort_order

我已将visible定义为INTEGER,并针对1而不是TRUE进行检查,因为许多数据库(包括最常用的SQLite)几乎不支持布尔值。

然后是一个可选但令人惊讶的好主意:暂时在表单上添加TDBGrid,将其链接到TLookupComboBox的相同TDataSource,并检查您是否确实看到所需数据填充它。实际上很容易在查询中输入错误(假设您使用的是SQL数据集)并且没有数据,然后您就会想知道为什么TDBLookupComboBox不会填写。 一旦看到数据正确显示,删除网格。

另一个明智的想法是将ClientDataSets用于这些类型的实现:由于它们的工作方式,它们将会缓存"在程序启动时查看包含的几行,然后不再需要进一步的数据库访问(以及减速和流量)。

现在打开TDBLookupComboBox属性并仅填写以下内容:

ListSource(以及 DataSource):将其设置为连接到要显示值的数据集的TDataSource。
ListField:将其设置为您希望用户查看的字段名称。在我们的演示案例中,它是value字段 KeyField:将其设置为您希望程序返回您的值的字段名称。在我们的演示中,它是id字段。

不要忘记检查TabOrder属性,仍然有人喜欢通过按TAB键来浏览控件,没有什么比看到选择随机跳转更烦人了,因为你的ComboBox是最后放在表格上,尽管图形显示第二个!

如果您只需要显示表单并在用户按下按钮时读取TDBLookupComboBox选择的值,那么您几乎可以进行排序。
您在按钮的OnClick事件处理程序中所要做的就是使用以下代码读取组合框值:

SelectedId := MyCombo.KeyValue;

其中SelectedId是存储返回值的任何变量,MyCombo当然是TDBLookupComboBox的名称。请注意KeyValue不会包含用户在屏幕上看到的文本,但是我们在id中指定的KeyField字段的值。因此,如果我们的用户选择了数据库行:

id= 5
value= 'MyText'

MyCombo.KeyValue应包含5

但是,如果您需要动态更新表单上的内容,取决于组合框用户选择,该怎么办?我们的TDBLookupComboBox没有OnChange个活动!因此,如果你需要根据组合框选择动态更新内容,你显然不能。您可以尝试各种各样的" OnExit"等事件,但都有严重的缺点或副作用 一种可能的解决方案是创建一个继承自TDBLookupComboBox的新组件,其唯一任务是公开隐藏的OnChange事件。但这有点过头了,不是吗?

还有另外一种方法:转到你的TDBLookupComboBox绑定的 DataSet (通过DataSource)。打开其活动并双击其OnAfterScroll事件。 在那里你可以很好地模拟一个OnChange事件。 为了演示,将一个整数变量和一个TEdit框添加到表单中并调用它们:SelectedIdEditValue

procedure TMyForm.MyDataSetAfterScroll(DataSet: TDataSet);
var
  SelectedId : integer;

begin
  SelectedId := MyDataSet.FieldByName('id').AsInteger;
  EditValue.Text := MyDataSet.FieldByName('value').AsString;
end;

它是这样的:您可以使用自己的过程调用替换这两个演示行,以及根据用户在组合框中的选择动态更新表单所需的任何其他内容。

一点警告:使用DataSet OnAfterScroll也有一个缺点:事件的调用次数比你想象的要频繁。例如,可以在打开数据集时调用它,但在记录导航期间也可以多次调用它。因此,您的代码必须处理被调用的频率而不是需要。

此时你可能会搓手并认为你的工作已经完成!

完全没有!只需创建一个实现上述所有内容的简短演示应用程序,您会注意到它没有重要的画龙点睛:当它启动时,组合框有一个烦人的空白"默认选择。也就是说,即使您的数据库持有4个选项,表单也会首先显示一个空的组合框选择值。 如何使您的一个选择自动显示"预先选择"在您和您的用户期望的组合框中?

简单!

只需为我们上面已经描述过的KeyValue属性赋值。 也就是说,在OnFormCreate或其他合适的事件上,只需硬编码一个选项,例如:

MyCombo.KeyValue := DefaultId;

例如,通过使用上面发布的示例数据库行,您可以写:

MyCombo.KeyValue := 5;

,组合框将显示:" MyText"作为用户打开表单时的预选选项。

当然,您可能更喜欢设置默认密钥而不是硬编码其默认值。在示例中,您可能希望显示数据库表或其他任何标准中包含的第一个按字母顺序排列的文本描述。但基本机制如上所示:以您想要的任何方式获取键/ id值,然后将其分配给KeyValue属性。

感谢您阅读此HowTo直到最后!