Bobski Bobski - 22 days ago 5
Vb.net Question

Reusable function to adjust the width of combobox items to longest item in the list

My intent is to be able to use a function to adjust the width of the drop down so that all items included in the drop down are shown (length wise). I'm trying to create a function where I'll be able to use it for multiple comboboxes. Currently this is being called from a LOAD CBO function, after the data has been loaded however it is not adjusting the .dropDownWidth.

Private Sub AdjustCombobox(ByVal comboboxName As ComboBox)
Dim maxwidth = 0
Dim temp = 0

For Each Item As Object In comboboxName.Items
temp = TextRenderer.MeasureText(Item.ToString(), comboboxName.Font).Width
If temp > maxwidth Then
maxwidth = temp
End If
Next

comboboxName.DropDownWidth = maxwidth
End Sub


EDIT:

comboboxload function

Dim da As New SqlDataAdapter(sql, objconnection)
Dim ds As New DataSet

da.Fill(ds, "Prov")

If ds.Tables("Prov").Rows.Count > 0 Then
With c
.DataSource = ds.Tables("Prov")
.ValueMember = "No"
.DisplayMember = "Name"
.SelectedIndex = -1
End With
End If

Answer

First, I would use the actual DataSource, not the items. This allows a really short solution:

Private Function GetMaxDataSize(dt As DataTable, mem As String) As Int32

    Dim longestItem = dt.AsEnumerable.Select(Function(q) q.Field(Of String)(mem)).
                OrderBy(Function(z) z.Length).
                Last()

    ' assumes as the CBO's use the same Font
    Dim longestSize = TextRenderer.MeasureText(longestItem, cboE.Font)
    Return longestSize.Width +
                SystemInformation.VerticalScrollBarWidth + 5

End Function

Note that the method accounts for the VerticalScrollBarWidth and a slight fudge factor to account fopr internal gutters, padding, margins etc. If different combos use different fonts, pass each to the method as well. Usage:

cboE.DropDownWidth = GetMaxDataSize(dtLorem, "Text")

Using `Lorem ipsum dolor" fragments, with one especially long one, the result:

enter image description here