Try to call MyBase.OnMeasureItem
at the end of the method
I'm trying to solve this exact same problem myself right at the moment for an application that I am migrating from VB6 to VB.NET. The owner-drawn combo control I have in VB6 sets the height of the drop-down through a SetWindowPos API call in response to the WM_CTLCOLORLISTBOX message on the combo control, which gives us access to the HWnd for the drop-down list of the combo control. The following code was added to my class that inherits from ComboBox and seems to do the trick, but still needs testing. I'm not sure it's the most elegant way of doing this either. Obviously you'll need to change the line that sets the newHeight variable, but this should give you the general idea.
Private Declare Function GetWindowRect Lib "user32" _
(ByVal hwnd As Integer, ByRef lpRect As RECT) As Integer
Private Declare Sub SetWindowPos Lib "user32" _
(ByVal hwnd As Integer, ByVal hWndInsertAfter As Integer, _
ByVal X As Integer, ByVal Y As Integer, _
ByVal cx As Integer, ByVal cy As Integer, _
ByVal wFlags As Integer)
Private Const SWP_NOZORDER As Integer = &H4
Private Const SWP_NOACTIVATE As Integer = &H10
Private Const SWP_FRAMECHANGED As Integer = &H20
Private Const SWP_NOOWNERZORDER As Integer = &H200
Private _hwndDropDown As Integer = 0
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
Const WM_CTLCOLORLISTBOX As Integer = &H134
If m.Msg = WM_CTLCOLORLISTBOX Then
If _hwndDropDown = 0 Then
_hwndDropDown = m.LParam.ToInt32
Dim r As RECT
GetWindowRect(m.LParam.ToInt32, r)
// height of four items plus 2 pixels for the border in my test
Dim newHeight As Integer = 4 * MyBase.ItemHeight + 2
SetWindowPos(m.LParam.ToInt32, 0, _
tr.Left, _
tr.Top, _
MyBase.DropDownWidth, _
newHeight, _
SWP_FRAMECHANGED Or _
SWP_NOACTIVATE Or _
SWP_NOZORDER Or _
SWP_NOOWNERZORDER)
End If
End If
MyBase.WndProc(m)
End Sub
Protected Overrides Sub OnDropDownClosed(ByVal e As System.EventArgs)
_hwndDropDown = 0
MyBase.OnDropDownClosed(e)
End Sub
Edit: I just tried to reproduce your problem but everything works fine:
class MyCustomComboBox : ComboBox
{
public MyCustomComboBox()
{
DrawMode = DrawMode.OwnerDrawVariable;
DropDownHeight = 255;
DropDownWidth = 300;
MaxDropDownItems = 20;
}
protected override void OnMeasureItem(MeasureItemEventArgs e)
{
base.OnMeasureItem(e);
if (e.Index % 2 == 0)
e.ItemHeight = ItemHeight * 3;
else
e.ItemHeight = ItemHeight * 2;
}
protected override void OnDrawItem(DrawItemEventArgs e)
{
base.OnDrawItem(e);
// Draw the background of the item.
e.DrawBackground();
Rectangle rectangle = new Rectangle(2, e.Bounds.Top + 2,
e.Bounds.Height, e.Bounds.Height - 4);
e.Graphics.FillRectangle(new SolidBrush(Color.Gray), rectangle);
Font myFont = new Font(FontFamily.GenericSansSerif, 30, FontStyle.Bold);
e.Graphics.DrawString(this.Items[e.Index] as string, myFont, Brushes.Black,
new RectangleF(e.Bounds.X + rectangle.Width, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height));
// Draw the focus rectangle if the mouse hovers over an item.
e.DrawFocusRectangle();
}
}
If I remember correctly you have to set the property DrawMode to OwnerDrawVariable to enable drawing custom item heights. If you do this you'll also have to handle the DrawItem event. Have a look at the property help in MSDN.