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
DataSet
s 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:
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:
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:
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:
Public Sub PopulateCombo(ByRef cbo As Windows.Forms.ComboBox, _
ByVal dst As DataSet)
PopulateCombo(cbo, dst, dst.Tables(0).Columns(0).ToString, _
dst.Tables(0).Columns(1).ToString, _
dst.Tables(0).ToString)
End Sub
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:
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
DataSet
s. 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.