I have an owner-drawn TComboBox
in Delphi Seattle which ignores any settings to the DropDownCount
property. The height of the individual items is 59 pixels and the width is 311 pixels. I have 5 entries in the Items
stringlist. Setting a value below 8 results in no dropdown being shown at all, while any higher values result in only 1 item being shown in the dropdown along with a vertical scrollbar. I need to be able to show all 5 entries in the items list in the dropdown.
Here's the DFM to reproduce the problem:
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 223
ClientWidth = 527
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object ComboBox1: TComboBox
Left = 96
Top = 16
Width = 311
Height = 22
Style = csOwnerDrawVariable
ItemIndex = 0
TabOrder = 0
Text = 'ITEM ONE'
OnDrawItem = ComboBox1DrawItem
OnMeasureItem = ComboBox1MeasureItem
Items.Strings = (
'ITEM ONE'
'ITEM TWO'
'ITEM THREE'
'ITEM FOUR'
'ITEM FIVE')
end
end
And here's the PAS file:
unit CBBoxBugUnit;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
ComboBox1: TComboBox;
procedure ComboBox1MeasureItem(Control: TWinControl; Index: Integer; var Height: Integer);
procedure ComboBox1DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState);
var Working_String : String;
Text_Width ,
Text_Height ,
Output_X ,
Output_Y : Integer;
begin
ComboBox1.Canvas.Pen.Color := clWhite;
ComboBox1.Canvas.Brush.Color := clGreen;
ComboBox1.Canvas.Brush.Style := bsSolid;
ComboBox1.Canvas.Pen.Style := psSolid;
ComboBox1.Canvas.Pen.Width := 1;
ComboBox1.Canvas.Font.Color := clWhite;
ComboBox1.Canvas.Font.Name := 'ARIAL BLACK';
ComboBox1.Canvas.Font.Size := 14;
ComboBox1.Canvas.FillRect( Rect );
Working_String := self.ComboBox1.Items.Strings[ Index ];
Text_Width := self.ComboBox1.Canvas.TextWidth( Working_String );
Text_Height := self.ComboBox1.Canvas.TextHeight( Working_String );
Output_X := ( Rect.Width - Text_Width ) div 2;
Output_Y := ( Rect.Height - Text_Height ) div 2;
ComboBox1.Canvas.TextOut( Output_X , Output_Y , Working_String );
end;
procedure TForm1.ComboBox1MeasureItem(Control: TWinControl; Index: Integer; var Height: Integer);
begin
Height := 59;
end;
end.
Even though the documentation for
ItemHeight
ofTComboBox
states:VCL has internal calculations that depend on
FItemHeight
. SetItemHeight
to 59 andDropDownCount
will be honored (it is already honored but for the default 16). If you set the value in design time, the combo will also adjust its size to that of at runtime.