【问题标题】:Combobox Style 'csDropDownList' in DelphiDelphi中的组合框样式'csDropDownList'
【发布时间】:2011-08-23 09:39:22
【问题描述】:

我在 delphi 7 中创建了一个表单并在其上添加了一个组合框。组合框包含项目列表。我不希望该用户可以将值输入到 Combobox 所以我已经设置了

combobox.style := csDropDownList;

但是通过代码我想使用combobox.text := 'New Item'; 但它不起作用。请注意,我要显示的文本不在项目列表中,我不想在那里添加它。请问有什么解决办法吗?

【问题讨论】:

  • 你想要的项目是总是“新项目”还是每次都不一样?
  • 您需要重新考虑您的设计。你说的不是下拉列表。
  • @ain:文本也会有所不同。我只想通过代码设置文本。谢谢。
  • 正如大卫所说,你的 UI 设计是错误的。您应该提供包含可用项目的下拉列表,并有一个单独的“新项目”按钮。这使得界面对用户来说更加清晰,IMO。

标签: delphi combobox delphi-7


【解决方案1】:

不,这根本不是 Windows 组合框控件的工作方式。

但是,如果您坚持,并且您不在乎您的用户会感到困惑,您可以将Style 设置为csDropDown,然后再做

procedure TForm1.ComboBox1KeyPress(Sender: TObject; var Key: Char);
begin
  Key := #0;
end;

作为组合框的OnKeyPress 事件。然后用户不能手动输入文本,而只能从列表中的项目中进行选择。但是,仍然可以通过设置Text 属性将文本设置为您喜欢的任何内容(即使它不在列表中):

ComboBox1.Text := 'Sample';

【讨论】:

  • 可以,只要它在列表中。
  • @GolezTrol:当然,但是 OP 写道“请注意,我要显示的文本不在项目列表中,我不想在其中添加它。”
  • 当您的答案只是单行(错误)时,我确实对它投了反对票。现在撤消它,您将其提升为真实且合适的答案。
  • 但是用户可以使用复制/粘贴来输入不在列表中的内容。
  • @GolezTrol:第一行还是一样,但它不是假的。在 Microsoft Windows 中,您不能将具有“下拉列表”样式的组合框控件的“文本”设置为不在列表中的任何内容。
【解决方案2】:

设置ItemIndex 属性。如果您还不知道,可以通过ComboBox.Items.IndexOf('New Item') 获取该文本的索引。

Combobox.ItemIndex := Combobox.Items.IndexOf('New item');

【讨论】:

  • 那你不能。这就是拥有一个下拉列表的全部本质。除了列表中的内容之外,您无法选择任何内容。甚至来自代码。
  • 一种解决方法是使用ComboBox.ItemIndex := ComboBox.Items.Add('New Item');,但这会将“新项目”添加到列表中。
  • 如果它违反了 OP 的先决条件,我不会称之为解决方法。
【解决方案3】:

下面的示例代码演示了如何绘制自定义文本以响应发送到 ComboBox 控件父窗口的WM_DRAWITEM 消息(这应该是示例工作的表单,否则子类化控件或完整绘制控制是必要的)。

要接收此消息,请将控件的Style 属性设置为“csOwnerDrawFixed”,但不要为OnDrawItem 事件设置处理程序,以便在我们干预绘图的所有其他情况下应用默认绘图。

ItemIndex 为-1 时,该示例设置了一个文本,但可以在其他情况下对其进行调整/调整。请注意,绘图代码不完整或不准确,示例只是演示了一种方法:

type
  TForm1 = class(TForm)
    ComboBox1: TComboBox;
    [..]
  private
    procedure WMDrawItem(var Msg: TWMDrawItem); message WM_DRAWITEM;
  end;

[...]

procedure TForm1.WMDrawItem(var Msg: TWMDrawItem);
var
  Font: HFONT;
begin
  inherited;
  if (Msg.Ctl = ComboBox1.Handle) and (Msg.DrawItemStruct.itemID = $FFFFFFFF) and
      ((Msg.DrawItemStruct.itemAction and ODA_DRAWENTIRE) = ODA_DRAWENTIRE) then begin

    Font := SelectObject(Msg.DrawItemStruct.hDC, ComboBox1.Canvas.Font.Handle);
    SelectObject(Msg.DrawItemStruct.hDC, GetStockObject(DC_BRUSH));

    if (Msg.DrawItemStruct.itemState and ODS_SELECTED) = ODS_SELECTED then begin
      SetDCBrushColor(Msg.DrawItemStruct.hDC, ColorToRGB(clHighlight));
      SetBkColor(Msg.DrawItemStruct.hDC, ColorToRGB(clHighlight));
      SetTextColor(Msg.DrawItemStruct.hDC, ColorToRGB(clHighlightText));
    end else begin
      SetDCBrushColor(Msg.DrawItemStruct.hDC, ColorToRGB(clWindow));
      SetBkColor(Msg.DrawItemStruct.hDC, ColorToRGB(clWindow));
      SetTextColor(Msg.DrawItemStruct.hDC, ColorToRGB(clWindowText));
    end;

    FillRect(Msg.DrawItemStruct.hDC, Msg.DrawItemStruct.rcItem, 0);
    TextOut(Msg.DrawItemStruct.hDC, 4, 4, '_no_selected_item_', 18);

    SelectObject(Msg.DrawItemStruct.hDC, Font);
  end;
end;

【讨论】:

    【解决方案4】:

    我认为您想要正常的东西,在尚未进行选择时在 ComboBox 中显示某些内容。一个空白矩形的瞬间。想象一个充满空白组合框的表单... ;)

    我看到大多数程序员所做的是将第一项作为标题显示在 ComboBox 中。

    因此,在 FormCreate 中(填充 ComboBox 之后),将其 ItemIndex 设置为 0,这将显示标题。

    在其 OnChange 事件中,您可以选择在选择项目 0 时不执行任何操作(“真实”项目的索引基数为 1),或者如果

    必须是第一次使用组合框的每个人的超级普遍抱怨。我无法理解没有一个编码器如何识别它。

    Borland 等人所要做的就是用 ItemIndex=0 初始化一个新的 ComboBox,这样混乱就消失了。您必须设置索引 0 肯定不是很明显 - 因为您在单击时会看到空白行,所以合乎逻辑的结论是 it 的索引为 0。可能他们想给设计师添加标签的选项而是在组合框之外。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-17
      • 2011-01-28
      • 2010-12-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多