locked
How can we increase the width of Dropdown of a Combo Box in Vb.net RRS feed

  • Question

  • Hi,

    I would like to know how can we increase the width of Dropdown (not the comboBox itself) of ComboBox in vb.net. Can anyone help me in this regard?

    Friday, September 4, 2020 3:50 PM

Answers

  • This will not work with a DataTable as a DataSource. Generally speaking a DataTable is overkill for working with a ComboBox, I've always used list.

    Here is how to properly rig up a ComboBox without a DataTable, use a List(OF T) instead.

    Class to hold our information

    Public Class CountryItem
       Public Property ContactTypeIdentifier() As Integer
       Public Property ContactTitle() As String
    End Class
    

    Read data from database

    Imports System.Data.SqlClient
    
    Namespace Classes
    
        Public Class Operations
            Private Shared ConnectionString As String =
                               "Data Source=.\SQLEXPRESS;" &
                               "Initial Catalog=NorthWindAzureForInserts;" &
                               "Integrated Security=True"
    
            Public Shared Function CountrySelectStatement() As String
                Return "SELECT CountryIdentifier, Name FROM dbo.Countries;"
            End Function
    
            ''' <summary>
            ''' Iterate the DataTable and perform updates for
            ''' each DataRow
            ''' </summary>
            ''' <param name="updatesTable"></param>
            Public Shared Sub Update(updatesTable As DataTable)
                ' TODO
            End Sub
            Public Shared Function Countries() As List(Of CountryItem)
                Dim nameList As New List(Of CountryItem)
    
                Dim selectStatement = "SELECT CountryIdentifier,Name FROM dbo.Countries;"
    
                Using connection As New SqlConnection(ConnectionString)
                    Using cmd As New SqlCommand(selectStatement, connection)
                        connection.Open()
    
                        Dim reader = cmd.ExecuteReader()
                        While reader.Read()
                            nameList.Add(New CountryItem() With {
                                            .ContactTypeIdentifier = reader.GetInt32(0),
                                            .ContactTitle = reader.GetString(1)
                                            })
                        End While
                    End Using
                End Using
    
                Return nameList
    
            End Function
        End Class
    
    End Namespace

    Form code to setup ComboBox and a button click event to get the selected item

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        CountryComboBox.DropDownStyle = ComboBoxStyle.DropDownList
        CountryComboBox.DisplayMember = "ContactTitle"
        CountryComboBox.DataSource = Operations.Countries
    End Sub
    
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim selectedCountry = CType(CountryComboBox.SelectedItem, CountryItem)
        MessageBox.Show($"ID: {selectedCountry.ContactTypeIdentifier} Name: {selectedCountry.ContactTitle}")
    End Sub


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    • Marked as answer by Ranjith K.U Thursday, September 10, 2020 6:17 AM
    Friday, September 4, 2020 9:25 PM

All replies

  • This may provide the width you want.

    Private Function DropDownWidth(sender As ComboBox) As Integer
    
        Dim maxWidth As Integer = 0
        Dim temp As Integer = 0
        Dim label1 As New Label()
    
        For Each item In sender.Items
            label1.Text = item.ToString()
            temp = label1.PreferredWidth
            If temp > maxWidth Then
                maxWidth = temp
            End If
        Next
    
        label1.Dispose()
    
        Return maxWidth
    
    End Function
    ComboBox1.DropDownWidth = DropDownWidth(ComboBox1)

    With and without

    In the above example the data source not DisplayMember are not set. In the following example I use a custom ComboBox.

    Imports System.ComponentModel
    Imports System.Reflection
    
    Public Class ImprovedComboBox
        Inherits ComboBox
    
        Public Sub New()
    
        End Sub
        Public Property DataSource() As Object
            Get
                Return MyBase.DataSource
            End Get
            Set
                MyBase.DataSource = Value
                DetermineDropDownWidth()
            End Set
    
        End Property
        Public Property DisplayMember() As String
            Get
                Return MyBase.DisplayMember
            End Get
            Set
                MyBase.DisplayMember = Value
                DetermineDropDownWidth()
            End Set
    
        End Property
        Public Property ValueMember() As String
            Get
                Return MyBase.ValueMember
            End Get
            Set
                MyBase.ValueMember = Value
                DetermineDropDownWidth()
            End Set
    
        End Property
        Private Sub DetermineDropDownWidth()
    
            Dim widestStringInPixels As Integer = 0
    
            For Each item As Object In Items
    
                Dim toCheck As String
                Dim pinfo As PropertyInfo
                Dim objectType As Type = item.GetType()
    
                If String.Compare(DisplayMember, "", StringComparison.Ordinal) = 0 Then
                    toCheck = item.ToString()
                Else
                    pinfo = objectType.GetProperty(Me.DisplayMember)
                    toCheck = pinfo.GetValue(item, Nothing).ToString()
                End If
    
                If TextRenderer.MeasureText(toCheck, Me.Font).Width > widestStringInPixels Then
                    widestStringInPixels = TextRenderer.MeasureText(toCheck, Me.Font).Width
                End If
    
            Next
            If DropDownRightPadding > 0 Then
                DropDownWidth = widestStringInPixels + DropDownRightPadding
            Else
                DropDownWidth = widestStringInPixels + 5
            End If
    
    
        End Sub
        <Category("Behavior"), Description("Pad Text to right for dropdown width")>
        Public Property DropDownRightPadding() As Integer
    
    End Class
    

    Use this to populate

    Public Class Person
        Public Property Id() As Integer
        Public Property FirstName() As String
        Public Property LastName() As String
        Public ReadOnly Property FullName() As String
            Get
                Return $"{FirstName} {LastName}"
            End Get
        End Property
    End Class
    Dim people As New List(Of Person) From {
        New Person() With {.Id = 1, .FirstName = "Karen", .LastName = "Payne"},
        New Person() With {.Id = 3, .FirstName = "Mary", .LastName = "Has a very long name indeed"},
        New Person() With {.Id = 2, .FirstName = "Jim", .LastName = "Smith Lelow"}
    }
    

    Then

    PeopleComboBox.DisplayMember = "FullName"
    PeopleComboBox.DataSource = people
    

    If extra right padding is needed

    Results



    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange


    Friday, September 4, 2020 4:10 PM
  • Hi Karen,

    I used your improved Combobox. Unfortunately, I'm getting this error:

    In forms, I used the following code:

    cboReferenceNo.DisplayMember = "Details"
    cboReferenceNo.DataSource = _dtTable
    cboReferenceNo.ValueMember = "Referenceid"


    • Edited by Ranjith K.U Friday, September 4, 2020 7:23 PM
    Friday, September 4, 2020 7:22 PM
  • This will not work with a DataTable as a DataSource. Generally speaking a DataTable is overkill for working with a ComboBox, I've always used list.

    Here is how to properly rig up a ComboBox without a DataTable, use a List(OF T) instead.

    Class to hold our information

    Public Class CountryItem
       Public Property ContactTypeIdentifier() As Integer
       Public Property ContactTitle() As String
    End Class
    

    Read data from database

    Imports System.Data.SqlClient
    
    Namespace Classes
    
        Public Class Operations
            Private Shared ConnectionString As String =
                               "Data Source=.\SQLEXPRESS;" &
                               "Initial Catalog=NorthWindAzureForInserts;" &
                               "Integrated Security=True"
    
            Public Shared Function CountrySelectStatement() As String
                Return "SELECT CountryIdentifier, Name FROM dbo.Countries;"
            End Function
    
            ''' <summary>
            ''' Iterate the DataTable and perform updates for
            ''' each DataRow
            ''' </summary>
            ''' <param name="updatesTable"></param>
            Public Shared Sub Update(updatesTable As DataTable)
                ' TODO
            End Sub
            Public Shared Function Countries() As List(Of CountryItem)
                Dim nameList As New List(Of CountryItem)
    
                Dim selectStatement = "SELECT CountryIdentifier,Name FROM dbo.Countries;"
    
                Using connection As New SqlConnection(ConnectionString)
                    Using cmd As New SqlCommand(selectStatement, connection)
                        connection.Open()
    
                        Dim reader = cmd.ExecuteReader()
                        While reader.Read()
                            nameList.Add(New CountryItem() With {
                                            .ContactTypeIdentifier = reader.GetInt32(0),
                                            .ContactTitle = reader.GetString(1)
                                            })
                        End While
                    End Using
                End Using
    
                Return nameList
    
            End Function
        End Class
    
    End Namespace

    Form code to setup ComboBox and a button click event to get the selected item

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        CountryComboBox.DropDownStyle = ComboBoxStyle.DropDownList
        CountryComboBox.DisplayMember = "ContactTitle"
        CountryComboBox.DataSource = Operations.Countries
    End Sub
    
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim selectedCountry = CType(CountryComboBox.SelectedItem, CountryItem)
        MessageBox.Show($"ID: {selectedCountry.ContactTypeIdentifier} Name: {selectedCountry.ContactTitle}")
    End Sub


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    • Marked as answer by Ranjith K.U Thursday, September 10, 2020 6:17 AM
    Friday, September 4, 2020 9:25 PM