Monday, February 23, 2009

Adjust the dropdownheight of a ComboBox automatically in VB.NET

I would like to adjust the size of a combobox to fit all of the items in it automatically.  One thing I noticed when testing it was if I set the dropdownheight to some large number, it automatically adjusted it to the size at runtime.  For example, if you combobox when fully filled out would need to be sized at say 200 pixels, but when you Designer you set the dropdownheight to 1000 when you run the program the combobox will only be sized at 200 pixels.  It won't create an enormously large combobox at 1000 pixels.

However the above solution just didn't seem right and I would like to have something where I wasn't hardcoding a number.  I came across this blog post below:
http://rajeshkm.blogspot.com/2006/11/adjust-combobox-drop-down-list-width-c.html

Basically he does what I want, but does it for the width of a combobox.  I converted the code to VB.NET and created a function that sets the Height as well.  The converted code and the modified function to adjust the height is below:

To call it just pass the name of the combobox to the routines

  Public Shared Sub SetComboScrollWidth(ByVal sender As Object)
    Try
      Dim senderComboBox As ComboBox = DirectCast(sender, ComboBox)
      Dim width As Integer = senderComboBox.Width
      Dim g As Graphics = senderComboBox.CreateGraphics()
      Dim font As Font = senderComboBox.Font

      'checks if a scrollbar will be displayed.
      'If yes, then get its width to adjust the size of the drop down list.
      Dim vertScrollBarWidth As Integer = IIf((senderComboBox.Items.Count > senderComboBox.MaxDropDownItems), SystemInformation.VerticalScrollBarWidth, 0)

      'Loop through list items and check size of each items.
      'set the width of the drop down list to the width of the largest item.

      Dim newWidth As Integer
      For Each s As String In DirectCast(sender, ComboBox).Items
        If s IsNot Nothing Then
          newWidth = CInt(g.MeasureString(s.Trim(), font).Width) + vertScrollBarWidth
          If width < newWidth Then
            width = newWidth
          End If
        End If
      Next
      senderComboBox.DropDownWidth = width
    Catch objException As Exception
      'Catch objException
    End Try
  End Sub

  Public Shared Sub SetComboScrollHeight(ByVal sender As Object)
    Try
      Dim senderComboBox As ComboBox = DirectCast(sender, ComboBox)
      Dim cboheight As Integer = senderComboBox.Height
      Dim g As Graphics = senderComboBox.CreateGraphics()
      Dim font As Font = senderComboBox.Font

      'Loop through list items and check size of each items.
      'increment the newheight to be the size of the items
      Dim newHeight As Integer = cboheight
      For Each s As String In DirectCast(sender, ComboBox).Items
        If s IsNot Nothing Then
          newHeight += CInt(g.MeasureString(s.Trim(), font).Height) '+ vertScrollBarWidth
        End If
      Next
      senderComboBox.DropDownHeight = newHeight
    Catch objException As Exception
      'Catch objException
    End Try
  End Sub

1 comment:

Darveson Pinoy said...

Over a year... but perhaps things have changed now at MS... When you try For Each s As String In DirectCast(sender, ComboBox).Items

you now get "Conversion from type 'DataRowView' to type 'String' is not valid"

Apparently it is impossible to iterate through the items of a combo box.... VS 2008