Sign in Join
Wiki copytemporary

TComboBox: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11A **TComboBox** ![](/wiki-images/7/75/Tcombobox.png) is a combination of an edit box and a (drop-down) list allowing one of several options to be chosen.
22
33# Usage
44
55To 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.
66
77In 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]].
88
99Here are a few examples to use a combobox *ComboBox1* on a form *Form1*:
1010
1111## Fill ComboBox
1212
1313### By the Object Inspector
1414
1515- Select the ComboBox on your form with one click.
1616- Go in the Object Inspector in the Properties tab on the property *Items*.
1717- Click on the button with the three dots. The String Editor opens.
1818- Enter your text and confirm your work with *OK*.
1919
2020### By code when you create the form
2121
2222- 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.
2323- In the source editor, you now insert the desired selection texts, for our example, you write as follows:
2424
2525``` pascal
2626procedure TForm1.FormCreate(Sender: TObject);
2727begin
2828 ComboBox1.Items.Clear; //Delete all existing choices
2929 ComboBox1.Items.Add('Red'); //Add an choice
3030 ComboBox1.Items.Add('Green');
3131 ComboBox1.Items.Add('Blue');
3232 ComboBox1.Items.Add('Random Color');
3333end;
3434```
3535
3636## Make that something happens after the selection
3737
3838Like 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:
3939
4040- Doubleclick the ComboBox on the form or choose the *OnChange* event in the Object Inspector and click on the button \[...\].
4141- 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:
4242
4343``` pascal
4444procedure TForm1.ComboBox1Change(Sender: TObject);
4545begin
4646 case ComboBox1.ItemIndex of //what entry (which item) has currently been chosen
4747 0: Color:=clRed;
4848 1: Color:=clGreen;
4949 2: Color:=clBlue;
5050 3: Color:=Random($1000000);
5151 end;
5252end;
5353```
5454
5555- Start your application, the selection changes the background color of the form.
5656
5757## Events
5858
5959The *OnGetItems* event is invoked when widgetset items list can be populated, so it is triggered when the button of the combo box is pressed.
6060
6161## Owner drawn ComboBox
6262
6363In general, it is advantageous to let the ComboBox show in the [theme](http://en.wikipedia.org/wiki/Skin_%28computing%29) 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:
6464
6565> **Note:** **Parameters of ComboBoxDrawItem:**\
6666> \
6767> **Control:**\
6868> 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:
6969>
7070> ``` pascal
7171> if Control is TComboBox then
7272> TComboBox(Control).Canvas.FillRect(ARect);
7373> ```
7474>
7575> **Index:** Specifies the item location, so you have access to the string **`<ComboBox>.Items[Index]`**.\
7676> **ARect:** Describes the rectangle, which is necessary for drawing the background.\
7777> **State:** Status of the items, whether normal, focused, selected etc.
7878
7979### Draw a filled rectangle
8080
8181- You can modify the example [[TComboBox|Fill ComboBox by code when you create the form]].
8282- Change from *ComboBox1* in the Object Inspector the property *Style* to *csOwnerDrawFixed*.
8383- Create in the Object Inspector the event handler for the event *OnDrawItem*, by clicking on the button \[...\].
8484- Add the following code to the handler:
8585
8686``` pascal
8787procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer;
8888 ARect: TRect; State: TOwnerDrawState);
8989var
9090 ltRect: TRect;
9191
9292 procedure FillColorfulRect(aCanvas: TCanvas; myRect: TRect); //paint random color
9393 // Fills the rectangle with random colours
9494 var
9595 y: Integer;
9696 begin
9797 for y:=myRect.Top to myRect.Bottom - 1 do begin
9898 aCanvas.Pen.Color:=Random($1000000);
9999 aCanvas.Line(myRect.Left, y, myRect.Right, y);
100100 end;
101101 end;
102102
103103begin
104104 ComboBox1.Canvas.FillRect(ARect); //first paint normal background
105105 ComboBox1.Canvas.TextRect(ARect, 22, ARect.Top, ComboBox1.Items[Index]); //paint item text
106106
107107 ltRect.Left := ARect.Left + 2; //rectangle for color
108108 ltRect.Right := ARect.Left + 20;
109109 ltRect.Top := ARect.Top + 1;
110110 ltRect.Bottom := ARect.Bottom - 1;
111111
112112 ComboBox1.Canvas.Pen.Color:=clBlack;
113113 ComboBox1.Canvas.Rectangle(ltRect); //draw a border
114114
115115 if InflateRect(ltRect, -1, -1) then //resize rectangle by one pixel
116116 if Index = 3 then
117117 FillColorfulRect(ComboBox1.Canvas, ltRect) //paint random color
118118 else begin
119119 case Index of
120120 0: ComboBox1.Canvas.Brush.Color := clRed;
121121 1: ComboBox1.Canvas.Brush.Color := clGreen;
122122 2: ComboBox1.Canvas.Brush.Color := clBlue;
123123 end;
124124 ComboBox1.Canvas.FillRect(ltRect); //paint colors according to selection
125125 end;
126126end;
127127```
128128
129129- Your example might look like:
130130
131131![](/wiki-images/1/1d/ComboBoxBsp1.png) -\> ![](/wiki-images/7/70/ComboBoxBsp2.png)
132132
133133### Preceded image
134134
135135In 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.
136136
137137- Create an application analogous example [[TComboBox|Fill ComboBox by code when you create the form]].
138138- Change from *ComboBox1* in the Object Inspector the property *Style* to *csOwnerDrawFixed*.
139139- Add a [[TImageList]] from the component palette *Common controls* on your form.
140140- 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.
141141- Add four images in the ImageList:
142142 - Doubleclick *ImageList1* or leftclick *ImageList1* and select *ImageList Editor...*.
143143 - Click on *Add* and select an image (see \<Lazarus directory\>/images/... there are various images or icons in 16x16px size).
144144 - Have you added four images, confirm your work with \[OK\].
145145- Create in the Object Inspector the event handler for the event *OnDrawItem*, by clicking on the button \[...\].
146146- Add the following code to the handler:
147147
148148``` pascal
149149procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer;
150150 ARect: TRect; State: TOwnerDrawState);
151151begin
152152 ComboBox1.Canvas.FillRect(ARect); //first paint normal background
153153 ComboBox1.Canvas.TextRect(ARect, 20, ARect.Top, ComboBox1.Items[Index]); //paint item text
154154 ImageList1.Draw(ComboBox1.Canvas, ARect.Left + 1, ARect.Top + 1, Index); //draw image according to index on canvas
155155end;
156156```
157157
158158- Your example might look like:
159159
160160![](/wiki-images/1/1d/ComboBoxBsp1.png) -\> ![](/wiki-images/c/ca/ComboBoxBsp3.png)
161161
162162## Styles
163163
164164### csSimple
165165
166166**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.
167167
168168There'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.
169169
170170**csSimple** style is Windows specific. Non-widows widgetset most likely don't implement and fall back to **csDropDown**.
171171
172172Here's an example of (non-autosized) csSimple ComboBox on two different widgetset. (as of Lazarus 2.0.8):
173173
174-Image:cssimple_win.png\|Win32 Image:cssimple_gtk2.png\|Gtk2
174+![](/wiki-images/0/08/Cssimple_win.png)
175+
176+Win32
177+
178+![](/wiki-images/5/58/Cssimple_gtk2.png)
179+
180+Gtk2
175181
176182# Proposed Features
177183
178184## ReadOnly
179185
180186ReadOnly property has been deprecated since 2017. It has been removed as of today.
181187
182188However, it's possible to reinstate ReadOnly property as a mirror of TEdit readonly.
183189
184190The 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).
185191
186192How, ReadOnly property is expected to work:
187193
188194- it's available for any ComboBox style
189195- it's does not influence or is not influenced by any ComboBox style selected or changed (unlike the previous implementation of ReadOnly)
190196- 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).
191197
192198:* 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)
193199
194200## TextHint
195201
196202As ComboBox bears traits of TEdit, it's should be possible to set TextHint for comboBox, if the value is empty.
197203
198204Introduce TextHint property that should act similar to TEdit
199205
200206- 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)
201207
202208# See also
203209
204210- [[doc:lcl/stdctrls/tcombobox.html|TComboBox]]
205211- [[TEdit]]
206212- [[TListBox]]
207213- [[TDBComboBox]]
208214- [[TDBLookupComboBox]]
209215
210216---
211217*From the Free Pascal wiki, page "TComboBox", as it stood on 2022-09-13 after a change by Paskal, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history