【问题标题】:How to allow selecting a NULL value in a TDBLookupComboBox?如何允许在 TDBLookupComboBox 中选择 NULL 值?
【发布时间】:2019-04-04 10:14:01
【问题描述】:

我有一个TDBLookupComboBox 显示一个fkLookup 类型的TStringField,它允许Null 值(来自一个可为空的整数数据库列)。

下拉列表显示来自已连接表的已分配LookupDataSet 中的项目。如果字段为Null,则不显示任何列表项,组合框为空。如果该字段有值,则会显示正确的描述。

我可以通过按分配的NullValueKey 将其重置为Null

没关系,但用户更喜欢使用鼠标。所以我可以提供一个清晰的按钮,但我认为列表顶部的附加行会更好。我该怎么做?

【问题讨论】:

    标签: delphi combobox null dataset


    【解决方案1】:

    您可以将空行放入查询中,如果需要对其进行排序,可以将其显示在列表顶部,如下所示:

    select 0 as sort,
           convert(int, null) as UserID,
           'Clear' as Name
    union all
    select 1 as sort,
           u.UserID,
           u.Name
    from   tblUser u
    order by sort, Name
    

    sort 列将使其显示在顶部,之后您可以根据需要进行排序。

    【讨论】:

    • 对我来说这看起来很骇人听闻,而且“清除”项的工作方式不是很一致:单击它会清空组合框并将字段设置为空,但是当您再次打开下拉列表时,没有列表条目会像普通条目一样显示为已选中。我接受了这一点,因为使用标准 TDBLookupComboBox 似乎没有更好的解决方案。
    【解决方案2】:

    您可以使用带有下一个 SQL(Firebird 语法)的查询作为您的 LookupDataSet

    SELECT CAST (NULL AS INTEGER) AS ID, CAST ('clear' AS VARCHAR(80)) AS NAME FROM table_name
    UNION
    SELECT ID, NAME FROM table_name
    

    但是,在此实现中,clear 项目将位于列表的末尾。

    在我们聊天讨论后添加

    恐怕我们永远不会像 normal 字段那样具有空值字段的行为,因为 null 不是一个值,正如这里正确提到的那样:https://petercai.com/null-is-not-a-value/。我们只能为它做一些变通方法。

    例如,我们可以看到 null 的自定义显示值,例如 SELECT CASE WHEN OurField IS NULL THEN '(empty)' ELSE OurField END AS OurField。我们可以通过人工菜单项设置 null。但这不是一个完整、复杂的解决方案。

    【讨论】:

    • 你确定这会像预期的那样工作吗?我不能完全像这样尝试,因为在这种情况下我的 DataSet 不能来自 SQL 查询。也许我可以使用其他方式添加 Null 行,但在其他一些问题中,这样做似乎还不够,而且它的行为不像组合框中的正常值。
    • 我的意思是这个问题:stackoverflow.com/questions/33606879/…
    • 我测试过了。如果在下拉菜单中选择clear,则db字段中将写入null。
    • 非常感谢!我猜你也是反过来测试的,所以你也可以回复上面那个老问题?
    • 不幸的是,没有。我不熟悉查找字段的工作原理(
    【解决方案3】:

    这并不是所要求的,但对于订阅了 DevExpress VCL ExpressEditors 的开发人员来说,它可能是更好的解决方案:TcxDBLookupComboBox 中有一个隐藏功能它可以在组合框内提供一个漂亮的清除按钮!

    它的工作方式与TcxButtonEdit 中的完全一样,您可以在设计时添加按钮,只是Buttons 属性没有在TcxDBLookupComboBox 中公开,因此只能在运行时设置:(

    procedure TForm1.FormCreate(Sender: TObject);
    begin
      AddClearButton(cxDBLookupComboBox1.Properties);
    end;
    
    procedure TForm1.AddClearButton(Prop: TcxCustomEditProperties);
    begin
      with Prop.Buttons.Add do begin
        Kind:= bkText;
        Caption:= #$2715; //Unicode X-symbol
      end;
      Prop.OnButtonClick:= ClearButtonClick;
    end;
    
    procedure TForm1.ClearButtonClick(Sender: TObject; AButtonIndex: Integer);
    begin
      if AButtonIndex = 1 then
        with TcxCustomEdit(Sender) do begin
          EditValue:= Null;
          PostEditValue;
        end;
    end;
    

    这可能也适用于其他编辑控件,但至少对于 TcxDBSpinEdit 无效。

    【讨论】:

    • 使用 devexpress 控件我认为您也可以使用 ctrl-delete 来清除组合框
    • 这在标准组合框中也是可能的。我已经在问题中提到了这一点(NullValueKey property)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-18
    • 1970-01-01
    • 2022-07-07
    • 1970-01-01
    • 1970-01-01
    • 2013-01-17
    • 1970-01-01
    相关资源
    最近更新 更多