Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / VB

Load a ComboBox at Runtime

5.00/5 (6 votes)
7 Jan 2011CPOL2 min read 46.7K  
Learn how to use a dataset object to load a combobox (or other similar objects) at runtime instead of needing to set anything up at design time.
Have you ever come across a problem that is WAY too simple to be this hard? I recently stumbled into a situation like that. The concept seemed simple enough. I needed to populate a ComboBox on a .NET form at runtime. The data that needed to go into it would come in the form of a DataSet. This can’t be hard, right? ComboBoxes take DataSets at design time so I figured I would just dump the DataSet in at runtime, set up the DisplayMember and ValueMember, and I would be good to go.

I tried to do the following:
VB
'dst is our pre-loaded DataSet.  It has
'two fields: ID and Value.
ComboBox1.DataSource = dst
ComboBox1.DisplayMember = "Value"
ComboBox1.ValueMember = "ID"


Unfortunately, this throws the error “Cannot bind to the new display member. Parameter name: newDisplayMember”. So that doesn’t work. I did some research and came across an article that indicated that you needed to assign the DisplayMember and ValueMember before the DataSource was assigned so that it would populate correctly, so I tried it using the following code:

VB
'dst is our pre-loaded DataSet.  It has
'two fields: ID and Value.
ComboBox1.DisplayMember = "Value"
ComboBox1.ValueMember = "ID"
ComboBox1.DataSource = dst


This time it actually ran (no exceptions thrown) but when I looked at the items in the ComboBox, there was only one item (there should have been 10) and its text was “System.Data.DataViewManagerListItemTypeDescriptor”.

Once again I turned to Google for the answer. This time, I came across an article that pointed out that you needed to specify which table in the DataSet you were attempting to access. That made sense, so I tried it like so:
VB
'dst is our pre-loaded DataSet.  It has
'two fields: ID and Value.
ComboBox1.DataSource = dst.Tables("ComboList")
ComboBox1.DisplayMember = "Value"
ComboBox1.ValueMember = "ID"


Finally, this worked as intended. The ComboBox populated and the values it returned were correct. What seemed to be a simple problem ended up taking half an hour to resolve.

As a side note, I did run across one more issue that might catch some of you off guard. When it seems like everything is set up right but for some reason the entire list is populated with “System.Data.DataRowView” entries (or the value of a particular selection comes out as this), you have mis-labeled your column. This is the system’s way of telling you that you made a mistake. Just check the column names and try again.

So, I have a working solution. I looked into extracting this functionality into its own function in order to make my life easier. After I got all done, I wasn’t sure that this added any improvements or if it just changed how I entered the information. I’ll give you the code and let you decide:

VB
'A much simpler call that assumes the table is the first table
'in the DataSet is the correct one and it assumes the first
'column is the identity column and the second one is the data
'column.
Public Sub PopulateCombo(ByRef cbo As Windows.Forms.ComboBox, _
                         ByVal dst As DataSet)
    'Calls the full method using our assumptions
    PopulateCombo(cbo, dst, dst.Tables(0).Columns(0).ToString, _
                  dst.Tables(0).Columns(1).ToString, _
                  dst.Tables(0).ToString)
End Sub
'The complete method that populates a ComboBox reference with
'data from the created DataSet.  This is the full method.
Public Sub PopulateCombo(ByRef cbo As Windows.Forms.ComboBox, _
                         ByVal dst As DataSet, _
                         ByVal strValueMember As String, _
                         ByVal strDisplayMember As String, _
                         ByVal strTableName As String)
    With cbo
        .DataSource = dst.Tables(strTableName)
        .DisplayMember = strDisplayMember
        .ValueMember = strValueMember
    End With
End Sub


To call this method, you would use the following code in the OnLoad section of your Form:

VB
'Load the ComboBox from our DataSet
PopulateCombo(ComboBox1, dst)


So, that turns a few lines into one and it is clearer to read. If you are going to be doing this multiple times, it might be useful. It might also help if you wanted to create a class to manage this method, then add a section for storing DataSets. This way, you could load the data from the database once and then call it over and over with the same code. Now it is starting to make sense to do it this way.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)