Difference between revisions of "TComboBox"

From Lazarus wiki
Jump to navigationJump to search
(add "Usage")
 
(17 intermediate revisions by 5 users not shown)
Line 1: Line 1:
 
{{TComboBox}}
 
{{TComboBox}}
  
>> [[LCL Components]] >> TComboBox<br/>
+
A '''TComboBox''' [[image:tcombobox.png]] is a combination of an edit box and a (drop-down) list allowing one of several options to be chosen.
  
This page explains how to use the [[doc:lcl/stdctrls/tcombobox.html|TComboBox]] component. When I mention to click on something, unless I explicitly say to right-click, you always left-click on the item in question.
+
=Usage=
  
==Description==
+
To use a [[doc:lcl/stdctrls/tcombobox.html|TComboBox]] on a [[TForm|form]], you can simply select it on the ''[[Standard tab]]'' of the [[Component Palette]] and place it by clicking on the form.
 
 
A combination of an edit box and a (drop-down) list allowing one of several options to be chosen.
 
 
 
[[image:Comp_Standard_TComboBox.png]]
 
 
 
==Usage==
 
 
 
To use a [[doc:lcl/stdctrls/tcombobox.html|TComboBox]] on a [[TForm|form]], you can simply select it on the ''Standard'' component pallet and place it by clicking on the form.<br>
 
  
 
In the ComboBox, the stored [[String|strings]] are stored in the property ''Items'', that is of type TStrings. Thus you can assign or remove strings in the ComboBox, as in a [[TStringList-TStrings Tutorial|TStringList]] or its parent [[TStringList-TStrings Tutorial|TStrings]].
 
In the ComboBox, the stored [[String|strings]] are stored in the property ''Items'', that is of type TStrings. Thus you can assign or remove strings in the ComboBox, as in a [[TStringList-TStrings Tutorial|TStringList]] or its parent [[TStringList-TStrings Tutorial|TStrings]].
Line 19: Line 11:
 
Here are a few examples to use a combobox ''ComboBox1'' on a form ''Form1'':
 
Here are a few examples to use a combobox ''ComboBox1'' on a form ''Form1'':
  
===Fill ComboBox===
+
==Fill ComboBox==
  
====by the Object Inspector====
+
===By the Object Inspector===
  
 
* Select the ComboBox on your form with one click.
 
* Select the ComboBox on your form with one click.
Line 28: Line 20:
 
* Enter your text and confirm your work with ''OK''.
 
* Enter your text and confirm your work with ''OK''.
  
====by code when you create the form====
+
===By code when you create the form===
  
 
* Create the ''OnCreate'' event handler for the form, by clicking on your form, use the Object Inspector, the tab events, select the ''OnCreate'' event and click the button [...] or double click the button in the form.  
 
* Create the ''OnCreate'' event handler for the form, by clicking on your form, use the Object Inspector, the tab events, select the ''OnCreate'' event and click the button [...] or double click the button in the form.  
 
* In the source editor, you now insert the desired selection texts, for our example, you write as follows:
 
* In the source editor, you now insert the desired selection texts, for our example, you write as follows:
<source>
+
 
 +
<syntaxhighlight lang=pascal>
 
procedure TForm1.FormCreate(Sender: TObject);   
 
procedure TForm1.FormCreate(Sender: TObject);   
 
begin
 
begin
Line 41: Line 34:
 
   ComboBox1.Items.Add('Random Color');   
 
   ComboBox1.Items.Add('Random Color');   
 
end;
 
end;
</source>
+
</syntaxhighlight>
  
===Make that something happens after the selection===
+
==Make that something happens after the selection==
  
 
Like all components, even the TComboBox provides various [[Event_order|events]], that are called when the user use the combobox. To respond to a change of the selection in the ComboBox, you can use the ''OnChange'' event:
 
Like all components, even the TComboBox provides various [[Event_order|events]], that are called when the user use the combobox. To respond to a change of the selection in the ComboBox, you can use the ''OnChange'' event:
 
* Doubleclick the ComboBox on the form or choose the ''OnChange'' event in the Object Inspector and click on the button [...].
 
* Doubleclick the ComboBox on the form or choose the ''OnChange'' event in the Object Inspector and click on the button [...].
 
* The event handler is created, now you can insert your desired source, in our example we want to change the background color of the form:
 
* The event handler is created, now you can insert your desired source, in our example we want to change the background color of the form:
<source>
+
 
 +
<syntaxhighlight lang=pascal>
 
procedure TForm1.ComboBox1Change(Sender: TObject);
 
procedure TForm1.ComboBox1Change(Sender: TObject);
 
begin
 
begin
Line 58: Line 52:
 
   end;
 
   end;
 
end;
 
end;
</source>
+
</syntaxhighlight>
 +
 
 
* Start your application, the selection changes the background color of the form.
 
* Start your application, the selection changes the background color of the form.
  
===Own drawed ComboBox===
+
==Events==
 +
The ''OnGetItems''  event is invoked when widgetset items list can be populated, so it is triggered when the button of the combo box is pressed.
  
In general, it is advantageous to let the ComboBox represent in [http://en.wikipedia.org/wiki/Skin_%28computing%29 theme] by the setting of the user. In some cases (for example, to program a game with a colorful surface), you can deviate from this standard and draw the according to your own choice. How this works, you can try now:
+
==Owner drawn ComboBox==
 +
 
 +
In general, it is advantageous to let the ComboBox show in the [http://en.wikipedia.org/wiki/Skin_%28computing%29 theme] the user has chosen in his settings. In some cases (for example, to program a game with a colorful surface), you can deviate from this standard and draw it according to your own choice. This is how this works:
  
 
{{Note|'''Parameters of ComboBoxDrawItem:'''<br><br>
 
{{Note|'''Parameters of ComboBoxDrawItem:'''<br><br>
'''Control:'''<br> If multiple controls (E.g. multiple ComboBoxes) access this event handle, you know which threw this event. You could in our example, instead of '''<code>ComboBox1.Canvas.FillRect(ARect)</code>''' also '''<code>TComboBox(Control).Canvas.FillRect(ARect)</code>''' write, where you should query still possible before, whether it is a TComboBox:
+
'''Control:'''<br> If multiple controls (e.g. multiple ComboBoxes) access this event handle, you know which control caused the event. In our example, instead of '''<code>ComboBox1.Canvas.FillRect(ARect)</code>''' you could also write '''<code>TComboBox(Control).Canvas.FillRect(ARect)</code>'''. However, you should still check in advance, whether it is a TComboBox:
<source>
+
 
 +
<syntaxhighlight lang=pascal>
 
   if Control is TComboBox then
 
   if Control is TComboBox then
 
     TComboBox(Control).Canvas.FillRect(ARect);     
 
     TComboBox(Control).Canvas.FillRect(ARect);     
</source>
+
</syntaxhighlight>
 +
 
 
'''Index:'''  
 
'''Index:'''  
 
Specifies the item location, so you have access to the string '''<code><ComboBox>.Items[Index]</code>'''.<br>
 
Specifies the item location, so you have access to the string '''<code><ComboBox>.Items[Index]</code>'''.<br>
Line 78: Line 78:
 
Status of the items, whether normal, focused, selected etc.   
 
Status of the items, whether normal, focused, selected etc.   
 
}}
 
}}
<br>
 
  
====Draw a filled rectangle====
+
===Draw a filled rectangle===
  
'''in progress --[[User:Michl|Michl]] 22:14, 2 June 2014 (CEST)'''
+
* You can modify the example [[TComboBox#by_code_when_you_create_the_form|Fill ComboBox by code when you create the form]].
 +
* Change from ''ComboBox1'' in the Object Inspector the property ''Style'' to ''csOwnerDrawFixed''.
 +
* Create in the Object Inspector the event handler for the event ''OnDrawItem'', by clicking on the button [...].
 +
* Add the following code to the handler:
  
* Modifizieren Sie am besten das Beispiel [[TComboBox/de#per Code beim Erstellen des Formulars|ComboBox füllen per Code beim Erstellen des Formulars]].
+
<syntaxhighlight lang=pascal>
* Ändern Sie von ''ComboBox1'' im Objektinspektor die Eigenschaft ''Style'' auf ''csOwnerDrawFixed''.
 
* Erstellen Sie im Objektinspektor den Eventhandler für das Ereignis ''OnDrawItem'', indem Sie auf den Button [...] klicken.
 
* Folgenden Code fügen Sie dem Eventhandler zu:
 
<source>
 
 
procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer;
 
procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer;
 
   ARect: TRect; State: TOwnerDrawState);
 
   ARect: TRect; State: TOwnerDrawState);
Line 94: Line 92:
 
   ltRect: TRect;
 
   ltRect: TRect;
  
   procedure FillColorfulRect(aCanvas: TCanvas; myRect: TRect);              //Zufallsfarben zeichnen
+
   procedure FillColorfulRect(aCanvas: TCanvas; myRect: TRect);              //paint random color
 +
  // Fills the rectangle with random colours
 
   var
 
   var
 
     y: Integer;
 
     y: Integer;
Line 105: Line 104:
  
 
begin
 
begin
   ComboBox1.Canvas.FillRect(ARect);                                        //Zuerst Standard - Hintergrund zeichnen
+
   ComboBox1.Canvas.FillRect(ARect);                                        //first paint normal background
   ComboBox1.Canvas.TextRect(ARect, 22, ARect.Top, ComboBox1.Items[Index]);  //Itemtext zeichnen
+
   ComboBox1.Canvas.TextRect(ARect, 22, ARect.Top, ComboBox1.Items[Index]);  //paint item text
  
   ltRect.Left  := ARect.Left  + 2;                                        //Kästchen für Farbe zeichnen
+
   ltRect.Left  := ARect.Left  + 2;                                        //rectangle for color
 
   ltRect.Right  := ARect.Left  + 20;
 
   ltRect.Right  := ARect.Left  + 20;
 
   ltRect.Top    := ARect.Top    + 1;
 
   ltRect.Top    := ARect.Top    + 1;
Line 114: Line 113:
  
 
   ComboBox1.Canvas.Pen.Color:=clBlack;
 
   ComboBox1.Canvas.Pen.Color:=clBlack;
   ComboBox1.Canvas.Rectangle(ltRect);                                      //Ein Rahmen um die Farbkästchen zeichnen
+
   ComboBox1.Canvas.Rectangle(ltRect);                                      //draw a border
  
   if InflateRect(ltRect, -1, -1) then                                      //Farbkästchen um ein Pixel verkleinern
+
   if InflateRect(ltRect, -1, -1) then                                      //resize rectangle by one pixel
 
     if Index = 3 then
 
     if Index = 3 then
       FillColorfulRect(ComboBox1.Canvas, ltRect)                            //Zufallsfarben zeichnen
+
       FillColorfulRect(ComboBox1.Canvas, ltRect)                            //paint random color
 
     else begin
 
     else begin
 
       case Index of
 
       case Index of
Line 125: Line 124:
 
         2: ComboBox1.Canvas.Brush.Color := clBlue;
 
         2: ComboBox1.Canvas.Brush.Color := clBlue;
 
       end;
 
       end;
       ComboBox1.Canvas.FillRect(ltRect);                                    //Farben entsprechend Auswahl zeichnen
+
       ComboBox1.Canvas.FillRect(ltRect);                                    //paint colors according to selection
 
     end;
 
     end;
 
end;
 
end;
</source>  
+
</syntaxhighlight>
* So könnte Ihr Beispiel dann aussehen:
+
 +
* Your example might look like:
 +
 
 
[[image:ComboBoxBsp1.png]] -> [[image:ComboBoxBsp2.png]]
 
[[image:ComboBoxBsp1.png]] -> [[image:ComboBoxBsp2.png]]
<br>
 
<br>
 
  
====Vorangestellte Images====
+
===Preceded image===
  
In diesem Beispiel werden wir ein paar Images in eine [[TImageList/de|TImageList]] laden und diese vor die Items der Combobox zeichnen. Es ist ein einfaches Beispiel, welches nur generell zeigen soll, wie Sie verfahren können. Details, wie das Prüfen, ob das entsprechende Image vorhanden ist usw. führe ich in diesem Beispiel explizit nicht aus. Dies müsste von Ihnen je nach Notwendigkeit vorgenommen werden.
+
In this example, we load a few images in a [[TImageList]] and draw them in front of the items in the combobox. It is a simple example which only generally show what you can do. I don't run explicitly details, such as checking, whether the corresponding image exists etc. in this example. This should be done by you depending on the need.
  
* Erstellen Sie eine Anwendung analog dem Beispiel [[TComboBox/de#per Code beim Erstellen des Formulars|ComboBox füllen per Code beim Erstellen des Formulars]].
+
* Create an application analogous example [[TComboBox#by_code_when_you_create_the_form|Fill ComboBox by code when you create the form]].
* Ändern Sie von ''ComboBox1'' im Objektinspektor die Eigenschaft ''Style'' auf ''csOwnerDrawFixed''.  
+
* Change from ''ComboBox1'' in the Object Inspector the property ''Style'' to ''csOwnerDrawFixed''.
* Fügen Sie eine [[TImageList/de|TImageList]] von der Komponentenpalette ''Common Controls'' auf Ihr Formular hinzu.
+
* Add a [[TImageList]] from the component palette ''Common controls'' on your form.
* Voreingestellt ist in ''ImageList1'' die Höhe ''Height'' und Breite ''Width'' von je 16 Pixel. Dies lassen wir so. Damit die Images ordentlich in unsere Combobox passen, stellen wir im Objektinspektor die Eigenschaft ''ItemHeight'' von ''ComboBox1'' auf ''18''.
+
* The ''Height'' and ''Width'' of 16 pixels is preset in ''ImageList1''. We allow this. To fit neatly the images into our combo box, we make the property ''ItemHeight'' from ''ComboBox1'' to ''18'' in the Object Inspector.
* Fügen Sie nun vier Images der ImageList zu:
+
* Add four images in the ImageList:
** Doppelklicken Sie ''ImageList1'' oder Linksklicken Sie ''ImageList1'' und wählen Sie ''ImageList-Editor...''.
+
** Doubleclick ''ImageList1'' or leftclick ''ImageList1'' and select ''ImageList Editor...''.
** Klicken Sie auf ''Hinzufügen'' und wählen Sie ein Image aus (unter <Lazarusverzeichnis>/images/... sind diverse Images bzw. Icons in der Größe 16x16px zu finden).
+
** Click on ''Add'' and select an image (see <Lazarus directory>/images/... there are various images or icons in 16x16px size).
** haben Sie vier Images zugefügt, bestätigen Sie Ihre Arbeit mit [OK].
+
** Have you added four images, confirm your work with [OK].
* Erstellen Sie im Objektinspektor den Eventhandler für das Ereignis ''OnDrawItem'', indem Sie auf den Button [...] klicken.
+
* Create in the Object Inspector the event handler for the event ''OnDrawItem'', by clicking on the button [...].
* Folgenden Code fügen Sie dem Eventhandler zu:
+
* Add the following code to the handler:
<source>
+
 
 +
<syntaxhighlight lang=pascal>
 
procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer;
 
procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer;
 
   ARect: TRect; State: TOwnerDrawState);
 
   ARect: TRect; State: TOwnerDrawState);
 
begin
 
begin
   ComboBox1.Canvas.FillRect(ARect);                                        //Zuerst Standard - Hintergrund zeichnen
+
   ComboBox1.Canvas.FillRect(ARect);                                        //first paint normal background
   ComboBox1.Canvas.TextRect(ARect, 20, ARect.Top, ComboBox1.Items[Index]);  //Itemtext zeichnen
+
   ComboBox1.Canvas.TextRect(ARect, 20, ARect.Top, ComboBox1.Items[Index]);  //paint item text
   ImageList1.Draw(ComboBox1.Canvas, ARect.Left + 1, ARect.Top + 1, Index);  //Image entsprechend Index auf Canvas zeichnen
+
   ImageList1.Draw(ComboBox1.Canvas, ARect.Left + 1, ARect.Top + 1, Index);  //draw image according to index on canvas
 
end;
 
end;
</source>
+
</syntaxhighlight>
* So könnte Ihr Beispiel dann aussehen:
+
 
 +
* Your example might look like:
 +
 
 
[[image:ComboBoxBsp1.png]] -> [[image:ComboBoxBsp3.png]]
 
[[image:ComboBoxBsp1.png]] -> [[image:ComboBoxBsp3.png]]
<br>
 
<br>
 
  
{{LCL Components Footer |TListBox|TScrollBar}}
+
==Styles==
 +
===csSimple===
 +
'''csSimple''' represents itself a simple edit box with a list box underneath. The list box is only shown, if there's enough height allocated. By default the height is set to shown the edit box only.
 +
 
 +
There's no dropdown icon to show the list box. Items can be changed by using keyboard (arrow keys), or by clicking an an item, if the control is high enough to show the items list.
 +
 
 +
'''csSimple''' style is Windows specific. Non-widows widgetset most likely don't implement and fall back to '''csDropDown'''.
 +
 
 +
 
 +
Here's an example of (non-autosized) csSimple ComboBox on two different widgetset. (as of Lazarus 2.0.8):
 +
 
 +
<gallery>
 +
Image:cssimple_win.png|Win32
 +
Image:cssimple_gtk2.png|Gtk2
 +
</gallery>
 +
 
 +
=Proposed Features=
 +
==ReadOnly==
 +
ReadOnly property has been deprecated since 2017. It has been removed as of today.
 +
 
 +
However, it's possible to reinstate ReadOnly property as a mirror of TEdit readonly.
 +
 
 +
The complexity of ComboBox is that it bears features of both ListBox and Edit (but it's not a descendant of either).
 +
While ComboBox does provides the means to change the selection (just like TEdit), it might be helpful also to make the edit box readonly. (Note, that this is different to csDropDownList. ccDropDownList typically implements a dropdown as a button).
 +
 
 +
How, ReadOnly property is expected to work:
 +
* it's available for any ComboBox style
 +
* it's does not influence or is not influenced by any ComboBox style selected or changed (unlike the previous implementation of ReadOnly)
 +
* if set to true, the edit box (if supported by the comboBox style on the widgetset) becomes ReadOnly (in terms of TEdit). The content cannot be changed by any text input actions (such as editing, pasting, or dragging the text around).
 +
:* the combobox value CAN be changed by selecting a different item from the dropdown, by either using a mouse (or respective key combinations, i.e. up or down arrows)
 +
 
 +
==TextHint==
 +
As ComboBox bears traits of TEdit, it's should be possible to set TextHint for comboBox, if the value is empty.
 +
 
 +
Introduce TextHint property that should act similar to TEdit
 +
* if text value of combobox is empty, the TextHint should be presented (in the colors and font style, that's applicable to the current widgetset theme)
 +
 
 +
= See also =
 +
 
 +
* [[doc:lcl/stdctrls/tcombobox.html|TComboBox]]
 +
* [[TEdit]]
 +
* [[TListBox]]
 +
* [[TDBComboBox]]
 +
* [[TDBLookupComboBox]]
 +
 
 
{{LCL Components}}
 
{{LCL Components}}
 
[[Category:LCL]]
 
[[Category:Components]]
 
--[[User:Michl|Michl]] 22:14, 2 June 2014 (CEST)
 

Latest revision as of 07:37, 13 September 2022

Deutsch (de) English (en) español (es) suomi (fi) français (fr) 日本語 (ja)

A TComboBox tcombobox.png is a combination of an edit box and a (drop-down) list allowing one of several options to be chosen.

Usage

To use a TComboBox on a form, you can simply select it on the Standard tab of the Component Palette and place it by clicking on the form.

In the ComboBox, the stored strings are stored in the property Items, that is of type TStrings. Thus you can assign or remove strings in the ComboBox, as in a TStringList or its parent TStrings.

Here are a few examples to use a combobox ComboBox1 on a form Form1:

Fill ComboBox

By the Object Inspector

  • Select the ComboBox on your form with one click.
  • Go in the Object Inspector in the Properties tab on the property Items.
  • Click on the button with the three dots. The String Editor opens.
  • Enter your text and confirm your work with OK.

By code when you create the form

  • Create the OnCreate event handler for the form, by clicking on your form, use the Object Inspector, the tab events, select the OnCreate event and click the button [...] or double click the button in the form.
  • In the source editor, you now insert the desired selection texts, for our example, you write as follows:
procedure TForm1.FormCreate(Sender: TObject);  
begin
  ComboBox1.Items.Clear;             //Delete all existing choices
  ComboBox1.Items.Add('Red');        //Add an choice
  ComboBox1.Items.Add('Green');
  ComboBox1.Items.Add('Blue');
  ComboBox1.Items.Add('Random Color');  
end;

Make that something happens after the selection

Like all components, even the TComboBox provides various events, that are called when the user use the combobox. To respond to a change of the selection in the ComboBox, you can use the OnChange event:

  • Doubleclick the ComboBox on the form or choose the OnChange event in the Object Inspector and click on the button [...].
  • The event handler is created, now you can insert your desired source, in our example we want to change the background color of the form:
procedure TForm1.ComboBox1Change(Sender: TObject);
begin
  case ComboBox1.ItemIndex of  //what entry (which item) has currently been chosen
    0: Color:=clRed;
    1: Color:=clGreen;
    2: Color:=clBlue;
    3: Color:=Random($1000000);
  end;
end;
  • Start your application, the selection changes the background color of the form.

Events

The OnGetItems event is invoked when widgetset items list can be populated, so it is triggered when the button of the combo box is pressed.

Owner drawn ComboBox

In general, it is advantageous to let the ComboBox show in the theme the user has chosen in his settings. In some cases (for example, to program a game with a colorful surface), you can deviate from this standard and draw it according to your own choice. This is how this works:

Light bulb  Note: Parameters of ComboBoxDrawItem:

Control:
If multiple controls (e.g. multiple ComboBoxes) access this event handle, you know which control caused the event. In our example, instead of ComboBox1.Canvas.FillRect(ARect) you could also write TComboBox(Control).Canvas.FillRect(ARect). However, you should still check in advance, whether it is a TComboBox:

  if Control is TComboBox then
    TComboBox(Control).Canvas.FillRect(ARect);

Index: Specifies the item location, so you have access to the string <ComboBox>.Items[Index].
ARect: Describes the rectangle, which is necessary for drawing the background.
State: Status of the items, whether normal, focused, selected etc.

Draw a filled rectangle

  • You can modify the example Fill ComboBox by code when you create the form.
  • Change from ComboBox1 in the Object Inspector the property Style to csOwnerDrawFixed.
  • Create in the Object Inspector the event handler for the event OnDrawItem, by clicking on the button [...].
  • Add the following code to the handler:
procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer;
  ARect: TRect; State: TOwnerDrawState);
var
  ltRect: TRect;

  procedure FillColorfulRect(aCanvas: TCanvas; myRect: TRect);              //paint random color
  // Fills the rectangle with random colours
  var
    y: Integer;
  begin
    for y:=myRect.Top to myRect.Bottom - 1 do begin
      aCanvas.Pen.Color:=Random($1000000);
      aCanvas.Line(myRect.Left, y, myRect.Right, y);
    end;
  end;

begin
  ComboBox1.Canvas.FillRect(ARect);                                         //first paint normal background
  ComboBox1.Canvas.TextRect(ARect, 22, ARect.Top, ComboBox1.Items[Index]);  //paint item text 

  ltRect.Left   := ARect.Left   + 2;                                        //rectangle for color
  ltRect.Right  := ARect.Left   + 20;
  ltRect.Top    := ARect.Top    + 1;
  ltRect.Bottom := ARect.Bottom - 1;

  ComboBox1.Canvas.Pen.Color:=clBlack;
  ComboBox1.Canvas.Rectangle(ltRect);                                       //draw a border 

  if InflateRect(ltRect, -1, -1) then                                       //resize rectangle by one pixel
    if Index = 3 then
      FillColorfulRect(ComboBox1.Canvas, ltRect)                            //paint random color
    else begin
      case Index of
        0: ComboBox1.Canvas.Brush.Color := clRed;
        1: ComboBox1.Canvas.Brush.Color := clGreen;
        2: ComboBox1.Canvas.Brush.Color := clBlue;
      end;
      ComboBox1.Canvas.FillRect(ltRect);                                    //paint colors according to selection
    end;
end;
  • Your example might look like:

ComboBoxBsp1.png -> ComboBoxBsp2.png

Preceded image

In this example, we load a few images in a TImageList and draw them in front of the items in the combobox. It is a simple example which only generally show what you can do. I don't run explicitly details, such as checking, whether the corresponding image exists etc. in this example. This should be done by you depending on the need.

  • Create an application analogous example Fill ComboBox by code when you create the form.
  • Change from ComboBox1 in the Object Inspector the property Style to csOwnerDrawFixed.
  • Add a TImageList from the component palette Common controls on your form.
  • The Height and Width of 16 pixels is preset in ImageList1. We allow this. To fit neatly the images into our combo box, we make the property ItemHeight from ComboBox1 to 18 in the Object Inspector.
  • Add four images in the ImageList:
    • Doubleclick ImageList1 or leftclick ImageList1 and select ImageList Editor....
    • Click on Add and select an image (see <Lazarus directory>/images/... there are various images or icons in 16x16px size).
    • Have you added four images, confirm your work with [OK].
  • Create in the Object Inspector the event handler for the event OnDrawItem, by clicking on the button [...].
  • Add the following code to the handler:
procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer;
  ARect: TRect; State: TOwnerDrawState);
begin
  ComboBox1.Canvas.FillRect(ARect);                                         //first paint normal background
  ComboBox1.Canvas.TextRect(ARect, 20, ARect.Top, ComboBox1.Items[Index]);  //paint item text 
  ImageList1.Draw(ComboBox1.Canvas, ARect.Left + 1, ARect.Top + 1, Index);  //draw image according to index on canvas
end;
  • Your example might look like:

ComboBoxBsp1.png -> ComboBoxBsp3.png

Styles

csSimple

csSimple represents itself a simple edit box with a list box underneath. The list box is only shown, if there's enough height allocated. By default the height is set to shown the edit box only.

There's no dropdown icon to show the list box. Items can be changed by using keyboard (arrow keys), or by clicking an an item, if the control is high enough to show the items list.

csSimple style is Windows specific. Non-widows widgetset most likely don't implement and fall back to csDropDown.


Here's an example of (non-autosized) csSimple ComboBox on two different widgetset. (as of Lazarus 2.0.8):

Proposed Features

ReadOnly

ReadOnly property has been deprecated since 2017. It has been removed as of today.

However, it's possible to reinstate ReadOnly property as a mirror of TEdit readonly.

The complexity of ComboBox is that it bears features of both ListBox and Edit (but it's not a descendant of either). While ComboBox does provides the means to change the selection (just like TEdit), it might be helpful also to make the edit box readonly. (Note, that this is different to csDropDownList. ccDropDownList typically implements a dropdown as a button).

How, ReadOnly property is expected to work:

  • it's available for any ComboBox style
  • it's does not influence or is not influenced by any ComboBox style selected or changed (unlike the previous implementation of ReadOnly)
  • if set to true, the edit box (if supported by the comboBox style on the widgetset) becomes ReadOnly (in terms of TEdit). The content cannot be changed by any text input actions (such as editing, pasting, or dragging the text around).
  • the combobox value CAN be changed by selecting a different item from the dropdown, by either using a mouse (or respective key combinations, i.e. up or down arrows)

TextHint

As ComboBox bears traits of TEdit, it's should be possible to set TextHint for comboBox, if the value is empty.

Introduce TextHint property that should act similar to TEdit

  • if text value of combobox is empty, the TextHint should be presented (in the colors and font style, that's applicable to the current widgetset theme)

See also


LCL Components
Component Tab Components
Standard TMainMenu • TPopupMenu • TButton • TLabel • TEdit • TMemo • TToggleBox • TCheckBox • TRadioButton • TListBox • TComboBox • TScrollBar • TGroupBox • TRadioGroup • TCheckGroup • TPanel • TFrame • TActionList
Additional TBitBtn • TSpeedButton • TStaticText • TImage • TShape • TBevel • TPaintBox • TNotebook • TLabeledEdit • TSplitter • TTrayIcon • TControlBar • TFlowPanel • TMaskEdit • TCheckListBox • TScrollBox • TApplicationProperties • TStringGrid • TDrawGrid • TPairSplitter • TColorBox • TColorListBox • TValueListEditor
Common Controls TTrackBar • TProgressBar • TTreeView • TListView • TStatusBar • TToolBar • TCoolBar • TUpDown • TPageControl • TTabControl • THeaderControl • TImageList • TPopupNotifier • TDateTimePicker
Dialogs TOpenDialog • TSaveDialog • TSelectDirectoryDialog • TColorDialog • TFontDialog • TFindDialog • TReplaceDialog • TTaskDialog • TOpenPictureDialog • TSavePictureDialog • TCalendarDialog • TCalculatorDialog • TPrinterSetupDialog • TPrintDialog • TPageSetupDialog
Data Controls TDBNavigator • TDBText • TDBEdit • TDBMemo • TDBImage • TDBListBox • TDBLookupListBox • TDBComboBox • TDBLookupComboBox • TDBCheckBox • TDBRadioGroup • TDBCalendar • TDBGroupBox • TDBGrid • TDBDateTimePicker
Data Access TDataSource • TCSVDataSet • TSdfDataSet • TBufDataset • TFixedFormatDataSet • TDbf • TMemDataset
System TTimer • TIdleTimer • TLazComponentQueue • THTMLHelpDatabase • THTMLBrowserHelpViewer • TAsyncProcess • TProcessUTF8 • TProcess • TSimpleIPCClient • TSimpleIPCServer • TXMLConfig • TEventLog • TServiceManager • TCHMHelpDatabase • TLHelpConnector
Misc TColorButton • TSpinEdit • TFloatSpinEdit • TArrow • TCalendar • TEditButton • TFileNameEdit • TDirectoryEdit • TDateEdit • TTimeEdit • TCalcEdit • TFileListBox • TFilterComboBox • TComboBoxEx • TCheckComboBox • TButtonPanel • TShellTreeView • TShellListView • TXMLPropStorage • TINIPropStorage • TJSONPropStorage • TIDEDialogLayoutStorage • TMRUManager • TStrHolder
LazControls TCheckBoxThemed • TDividerBevel • TExtendedNotebook • TListFilterEdit • TListViewFilterEdit • TLvlGraphControl • TShortPathEdit • TSpinEditEx • TFloatSpinEditEx • TTreeFilterEdit • TExtendedTabControl •
RTTI TTIEdit • TTIComboBox • TTIButton • TTICheckBox • TTILabel • TTIGroupBox • TTIRadioGroup • TTICheckGroup • TTICheckListBox • TTIListBox • TTIMemo • TTICalendar • TTIImage • TTIFloatSpinEdit • TTISpinEdit • TTITrackBar • TTIProgressBar • TTIMaskEdit • TTIColorButton • TMultiPropertyLink • TTIPropertyGrid • TTIGrid
SQLdb TSQLQuery • TSQLTransaction • TSQLScript • TSQLConnector • TMSSQLConnection • TSybaseConnection • TPQConnection • TPQTEventMonitor • TOracleConnection • TODBCConnection • TMySQL40Connection • TMySQL41Connection • TMySQL50Connection • TMySQL51Connection • TMySQL55Connection • TMySQL56Connection • TMySQL57Connection • TSQLite3Connection • TIBConnection • TFBAdmin • TFBEventMonitor • TSQLDBLibraryLoader
Pascal Script TPSScript • TPSScriptDebugger • TPSDllPlugin • TPSImport_Classes • TPSImport_DateUtils • TPSImport_ComObj • TPSImport_DB • TPSImport_Forms • TPSImport_Controls • TPSImport_StdCtrls • TPSCustomPlugin
SynEdit TSynEdit • TSynCompletion • TSynAutoComplete • TSynMacroRecorder • TSynExporterHTML • TSynPluginSyncroEdit • TSynPasSyn • TSynFreePascalSyn • TSynCppSyn • TSynJavaSyn • TSynPerlSyn • TSynHTMLSyn • TSynXMLSyn • TSynLFMSyn • TSynDiffSyn • TSynUNIXShellScriptSyn • TSynCssSyn • TSynPHPSyn • TSynTeXSyn • TSynSQLSyn • TSynPythonSyn • TSynVBSyn • TSynAnySyn • TSynMultiSyn • TSynBatSyn • TSynIniSyn • TSynPoSyn
Chart TChart • TListChartSource • TRandomChartSource • TUserDefinedChartSource • TCalculatedChartSource • TDbChartSource • TChartToolset • TChartAxisTransformations • TChartStyles • TChartLegendPanel • TChartNavScrollBar • TChartNavPanel • TIntervalChartSource • TDateTimeIntervalChartSource • TChartListBox • TChartExtentLink • TChartImageList
IPro TIpFileDataProvider • TIpHtmlDataProvider • TIpHttpDataProvider • TIpHtmlPanel
Virtual Controls TVirtualDrawTree • TVirtualStringTree • TVTHeaderPopupMenu