Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database 如何用数据库数据(VCL)快速填充组合框_Database_Delphi_Combobox_Dataset_Lookup - Fatal编程技术网

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

Database 如何用数据库数据(VCL)快速填充组合框,database,delphi,combobox,dataset,lookup,Database,Delphi,Combobox,Dataset,Lookup,我在网上读过各种各样的文档,都是关于什么应该是一个非常普遍和无痛的实现。由于我没有找到一致而圆滑的回复(甚至Embarcadero网站也错误地描述了一些属性!),我将发布一篇“简短”的指南 典型的、频繁的用例:开发人员只想轻松地在一个组合框(即语言选择)中显示几个数据库提取的信息,从中获得用户的选择,就这样 要求: 德尔福,或多或少的任何版本。包括VCL 数据库表。让我们假设一个简单的表有id和value字段 数据集(包括查询和客户端数据集) 链接到数据集的数据源 链接到数据源的TDBLooku

我在网上读过各种各样的文档,都是关于什么应该是一个非常普遍和无痛的实现。由于我没有找到一致而圆滑的回复(甚至Embarcadero网站也错误地描述了一些属性!),我将发布一篇“简短”的指南

典型的、频繁的用例:开发人员只想轻松地在一个组合框(即语言选择)中显示几个数据库提取的信息,从中获得用户的选择,就这样

要求:

  • 德尔福,或多或少的任何版本。包括VCL
  • 数据库表。让我们假设一个简单的表有
    id
    value
    字段
  • 数据集(包括查询和客户端数据集)
  • 链接到数据集的数据源
  • 链接到数据源的TDBLookupComboBox,它将显示值列表并“返回”当前选择的id

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

    SELECT id, value
    FROM my_database_table
    WHERE visible = 1
    ORDER BY sort_order
    
    我将
    visible
    定义为整数,并将其与
    1
    TRUE
    进行对比检查,因为许多数据库(包括最常用的SQLite)几乎不支持布尔值

    然后是一个可选但通常出人意料的好主意:在表单上临时添加一个TDBGrid,将其链接到TLookupComboBox的同一个TDataSource,并检查是否确实看到了所需的数据。事实上,很容易在查询中键入某些内容(假设您使用的是SQL数据集),但却没有得到任何数据,然后您就会疑惑为什么TDBLookupComboBox无法填充。 一旦看到数据正确显示,请移除网格

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

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

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

    别忘了检查TabOrder属性,仍然有人喜欢通过按下
    TAB
    键在控件中导航,没有什么比看到组合框在表单上最后一个位置时随机跳转更烦人的了,尽管它以图形方式显示第二个

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

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

    id= 5
    value= 'MyText'
    
    MyCombo.KeyValue应包含
    5

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

    还有另一种方法:转到您的TDBLookupComboBox绑定到的数据集(通过数据源)。打开它的事件,然后双击它的
    onScroll
    事件。 在这里,您可以很好地模拟OnChange事件。 为了便于演示,在表单中添加一个整数变量和一个TEdit框并调用它们:
    SelectedId
    EditValue

    procedure TMyForm.MyDataSetAfterScroll(DataSet: TDataSet);
    var
      SelectedId : integer;
    
    begin
      SelectedId := MyDataSet.FieldByName('id').AsInteger;
      EditValue.Text := MyDataSet.FieldByName('value').AsString;
    end;
    
    就是这样:您可以用自己的过程调用和其他任何需要根据用户在组合框中的选择动态更新表单的内容来替换这两个演示行

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

    在这一点上,你可能会摩擦你的手,认为你的工作完成了

    一点也不!只需创建一个实现上述所有功能的简短演示应用程序,您就会注意到它缺少一个重要的收尾:当它启动时,组合框有一个恼人的“空白”默认选项。也就是说,即使您的数据库中有4个选项,表单也会首先显示一个空的组合框selected值。 如何使您的选择之一在组合框中自动显示为您和您的用户期望的“预选”

    简单

    只需为上面已经描述过的KeyValue属性指定一个值。
    MyCombo.KeyValue := DefaultId;
    
    MyCombo.KeyValue := 5;