C
CJ Taylor
Alright before I get started, first of all, this is a help article. I'm
just shocked I didn't think of a solution or couldn't find one on the web at
all. So I figured I would write a quick blurb on here, in someone wants to
post it on there blog so it can be spidered, feel free. I don't have one
yet, should probably set one up.
Alright... Now I brought this issue up a few weeks ago and kinda put it to
the way side but now it has become an issue again with an application I am
developing. I believe Armin was looking for a solution as well, and had
one, but we both agreed it was a bit rough. Well sorta... I use the same
idea, just a little different. And maybe if its written out people will
understand.
Now... what the hell am I talking about? The infamous <select none> inside
a databound combo box. how many times have you been annoyed by a
non-required field but dot net doesn't support adding items to databound
list controls!
So, my fine friends this is a quick and dirty way to do it, which I'll
explain on the way (its not long). And hopefully it will help everyone out.
Alright, a little info about ComboBox. 1, its not as dumb as we all
thought, in fact, its quite ingenious (well, databinding in dot net itself
is pretty cool, this just makes it better). Combobox only cares about 2
interfaces in binding (much like most things) IList, or IListSource.
So knowing this, and knowing the the massive amount of classes that probably
implement IList we can start coming to conculsions.
In my example, we are going to use System.Data.DataTable class for our IList
provider. And use a DataRow as our Object to add to the IList/IListSource
Collection. I find these to be the easiest ones because everything is
implemented as needed (you could roll your own, but in the end, your going
to basically come up with a datarow with less properties/methods. It's up
to you)
The important thing to remember is, Combobox cares about 2 things (as do
you) the DisplayMember and the ValueMember. These are pulled from
Properties within our list source by the combobox. In our case, they
represent the fields of the datarow, or a property of the indexer on IList
(i.e. IList(0)("fieldName"))
So we declare a untyped datarow, and datatable
Dim dr as DataRow
Dim dt as new DataTable("MyTable")
the name of the table isn't important here, I do it out of habit.
Then, add your columns to the datatable for the combobox to bind onto.
dt.Columns.Add(New DataColumn("DisplayMember", getType(String)))
dt.Columns.Add(New DataColumn("ValueMember", getType(Integer)))
Datatypes aren't really important on the valuemember since it can be an
object (rmember though, if it is an object and you wanted to use
SelectedValue you have to implement IComparable)
First, we are going to go ahead and add in our "none" row.
dr = dt.NewRow()
dr("DisplayMember") = "< none ... >"
dr("ValueMember") = 0
dt.Rows.Add(dr)
this adds our first row to the table, obviously not bound to a dataset or
any adapter, so no update worries. I then take the dataset I want data off
of to load into the combobox and load it into my table
Dim cRow as DataRow
for each cRow in myDataSet.Tables("yourTableHere")
dr = dt.NewRow()
dr("DisplayMember") = cRow("PropertyName")
dr("ValueMember") = cRow("OtherPropertyName")
dt.Rows.Add (dr)
next
Finally, bind your source to your combobox.
me.myComboBox.DataSource = dt
me.myComboBox.DisplayMember = "DisplayMember"
me.myComboBox.ValueMember = "ValueMember"
Obviously, you can replace DisplayMember and ValueMember vlaues with
whatever you want, but this is just an example. And thats it. You will be
bound and ready.
A little janky, but it gets the job done with no questions.
Hope it helps.
CJ
just shocked I didn't think of a solution or couldn't find one on the web at
all. So I figured I would write a quick blurb on here, in someone wants to
post it on there blog so it can be spidered, feel free. I don't have one
yet, should probably set one up.
Alright... Now I brought this issue up a few weeks ago and kinda put it to
the way side but now it has become an issue again with an application I am
developing. I believe Armin was looking for a solution as well, and had
one, but we both agreed it was a bit rough. Well sorta... I use the same
idea, just a little different. And maybe if its written out people will
understand.
Now... what the hell am I talking about? The infamous <select none> inside
a databound combo box. how many times have you been annoyed by a
non-required field but dot net doesn't support adding items to databound
list controls!
So, my fine friends this is a quick and dirty way to do it, which I'll
explain on the way (its not long). And hopefully it will help everyone out.
Alright, a little info about ComboBox. 1, its not as dumb as we all
thought, in fact, its quite ingenious (well, databinding in dot net itself
is pretty cool, this just makes it better). Combobox only cares about 2
interfaces in binding (much like most things) IList, or IListSource.
So knowing this, and knowing the the massive amount of classes that probably
implement IList we can start coming to conculsions.
In my example, we are going to use System.Data.DataTable class for our IList
provider. And use a DataRow as our Object to add to the IList/IListSource
Collection. I find these to be the easiest ones because everything is
implemented as needed (you could roll your own, but in the end, your going
to basically come up with a datarow with less properties/methods. It's up
to you)
The important thing to remember is, Combobox cares about 2 things (as do
you) the DisplayMember and the ValueMember. These are pulled from
Properties within our list source by the combobox. In our case, they
represent the fields of the datarow, or a property of the indexer on IList
(i.e. IList(0)("fieldName"))
So we declare a untyped datarow, and datatable
Dim dr as DataRow
Dim dt as new DataTable("MyTable")
the name of the table isn't important here, I do it out of habit.
Then, add your columns to the datatable for the combobox to bind onto.
dt.Columns.Add(New DataColumn("DisplayMember", getType(String)))
dt.Columns.Add(New DataColumn("ValueMember", getType(Integer)))
Datatypes aren't really important on the valuemember since it can be an
object (rmember though, if it is an object and you wanted to use
SelectedValue you have to implement IComparable)
First, we are going to go ahead and add in our "none" row.
dr = dt.NewRow()
dr("DisplayMember") = "< none ... >"
dr("ValueMember") = 0
dt.Rows.Add(dr)
this adds our first row to the table, obviously not bound to a dataset or
any adapter, so no update worries. I then take the dataset I want data off
of to load into the combobox and load it into my table
Dim cRow as DataRow
for each cRow in myDataSet.Tables("yourTableHere")
dr = dt.NewRow()
dr("DisplayMember") = cRow("PropertyName")
dr("ValueMember") = cRow("OtherPropertyName")
dt.Rows.Add (dr)
next
Finally, bind your source to your combobox.
me.myComboBox.DataSource = dt
me.myComboBox.DisplayMember = "DisplayMember"
me.myComboBox.ValueMember = "ValueMember"
Obviously, you can replace DisplayMember and ValueMember vlaues with
whatever you want, but this is just an example. And thats it. You will be
bound and ready.
A little janky, but it gets the job done with no questions.
Hope it helps.
CJ