开发者

Combobox Style 'csDropDownList' in Delphi

I have created one form in delphi 7 and added one combobox on it. The combobox contains the list of items. I dont want that user can enter the value to Combobox so i have set

combobox.style := csDropDownList;

But thorugh code i want to use combobox.text := 'New Item'; but its not worki开发者_StackOverflow社区ng. Note that the text I want to show is not in the list of items and I don't want to add it there. Please is any solution to this?


No, this is simply not the way the Windows combobox control works.

However, if you insist, and you don't care that your users will get confused, you can set Style to csDropDown and then do

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

as the combobox' OnKeyPress event. Then the user cannot enter text manually, but can only choose from the items in the list. However, you can still set the text to anything you like (even if it isn't in the list) by setting the Text property:

ComboBox1.Text := 'Sample';


Set the ItemIndex property. You can get ComboBox.Items.IndexOf('New Item') to get the index of that text, if you don't already know it.

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


Below sample code demonstrates how you can draw custom text in response to a WM_DRAWITEM message sent to the ComboBox control's parent window (this should be the form for the sample to work, otherwise subclassing controls or full drawing of items of the control would be necessary).

To receive this message set the Style property of the control to 'csOwnerDrawFixed', but do not put a handler for the OnDrawItem event so that default drawing should be applied in all other cases that we intervene drawing.

The sample sets a text when ItemIndex is -1, but it can be adapted/tweaked otherwise. Note that the drawing code is not complete or accurate, the sample just demonstrates a way how it can be done:

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;


I think you want the normal thing, to display something in the ComboBox when no selection has yet been made. Instant of a blank rectangle. Imagine a form full of blank comboboxes... ;)

What I've seen most programmers do is have the first item as the title to display in the ComboBox.

So, in FormCreate (after you've populated the ComboBox), you set its ItemIndex to 0, and this displays the title.

In its OnChange event you can choose to take no action if item 0 is selected ("real" items then have base 1 for index), or get ItemIndex-1 and skip action if < 0.

Must be a super common complaint from everyone who has used Comboboxes the first time. I can't understand how none of the coders recognize it.

All Borland et al would have had to do was to initialize a new ComboBox with ItemIndex=0 and the confusion would have been gone. It's certainly not obvious that you have to set index 0 - since you see the blank line when clicked, the logical conclusion is that it has index 0. Probably they wanted to give designers the option to add a label outside the combobox instead.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜