ComboBox Item (Windows Forms)

  • Thread starter Thread starter Jerad Rose
  • Start date Start date
J

Jerad Rose

I'm baffled by this -- is there not a typed object used for ComboBox Items?
Best I can tell, all of the methods for ComboBox that accept an Item are of
type Object. Why in the world is a common/standard .NET control accepting
an Object as a parameter type?

In Web Forms, there is a ListItem object that can be passed in to
add/retrieve objects from a DropDownItems collection. I searched Google
groups, and all the solutions I'm finding are creating their own custom
name/value pair class, and using that when adding items to a ComboBox.
Seriously?

It would even be forgivable for .NET 1.0 or 1.1, but we're several years
later in .NET 2.0, and it's still using objects?

Please, can someone give me a logical reason behind this? I'd really like
to be wrong on this, and am just totally missing something.

Thanks in advance.
 
All of .Net is based on objects. Everything is an object. You can bind your
ComboBox to a list of strings, a list of objects, a dataset, etc. If you
bind it to a list of string, [item] is a string. If you bind it to a list
of objects, [item] is an object of that type. If you bind it to a dataset
or datatable, [item] is a datarow. I'm not sure exactly what your problem
is, but it seems to make a lot of sense to me.

Robin S.
 
Thanks for the response, Robin.

Yes, I understand that the object is the fundamental class behind every
class. I guess I wasn't clear on my confusion.

To me, when an object is used as a parameter, it leaves too much open for
type mismatches. For example, since the ComboBox allows you to bind to a
list of strings, a dataset, etc., I would think it would be better to have
these explicitly defined as overloaded parameters (i.e. Add(string[] items),
Add(DataSet dataSet), etc.), rather than just the open-ended Object. This
approach seems to regress us back to the days of VB6 and late binding.

But my main point is this. There is currently no way to add an item to a
combo box that has a different Value and Text property, other than creating
my own name/value pair class, and passing that to the Add method. This
seems ridiculous to me. In fact, I'm not even sure I can set the Text of a
ComboBox Item separately from the Value, since Item is an Object, and
therefore there is no ComboBox1.Items[0].Text property.

Do you see my point?

Thanks again.
Jerad

RobinS said:
All of .Net is based on objects. Everything is an object. You can bind
your ComboBox to a list of strings, a list of objects, a dataset, etc. If
you bind it to a list of string, [item] is a string. If you bind it to a
list of objects, [item] is an object of that type. If you bind it to a
dataset or datatable, [item] is a datarow. I'm not sure exactly what your
problem is, but it seems to make a lot of sense to me.

Robin S.
-----------------------------
Jerad Rose said:
I'm baffled by this -- is there not a typed object used for ComboBox
Items? Best I can tell, all of the methods for ComboBox that accept an
Item are of type Object. Why in the world is a common/standard .NET
control accepting an Object as a parameter type?

In Web Forms, there is a ListItem object that can be passed in to
add/retrieve objects from a DropDownItems collection. I searched Google
groups, and all the solutions I'm finding are creating their own custom
name/value pair class, and using that when adding items to a ComboBox.
Seriously?

It would even be forgivable for .NET 1.0 or 1.1, but we're several years
later in .NET 2.0, and it's still using objects?

Please, can someone give me a logical reason behind this? I'd really
like to be wrong on this, and am just totally missing something.

Thanks in advance.
 
If you have a name/value pair in a class, with a ToString method, and you
bind that to the combobox, I believe you will find the ToString result
shows up in the combobox. If you don't put in the ToString method, I think
it just shows the name of the class or something like that.

Here's an example in VB. I can convert this in C# if you want. This one is
databound. If you want one that's not databound, I can give you that one
too. This is from a small project I wrote that shows 5 different ways to
put data in and take data out of a combobox. If you post your e-mail, I'll
send it to you.


Public Class MainForm


Dim CustomerList As List(Of Customer)
Private _Loading as Boolean

'CustomerTable is already loaded from the database.
Private Sub LoadComboBoxes()
_Loading = True
'add a blank entry to the list
CustomerList = New List(Of Customer)
CustomerList.Add(Customer.Create(0, String.Empty))
Dim CbxCount As Integer = 0
For Each dr As DataRow In CustomerTable.Rows
CustomerList.Add(Customer.Create(CType(dr("CustomerID"),
Integer), _
dr("CustomerName").ToString))
Next dr
ListComboBox.DataSource = CustomerList
ListComboBox.DisplayMember = "CustomerName"
ListComboBox.ValueMember = "CustomerID"
_Loading = False
End Sub

Private Sub ListComboBox_SelectedIndexChanged(ByVal sender As Object,
ByVal e As System.EventArgs) Handles ListComboBox.SelectedIndexChanged
If Not _Loading AndAlso TableComboBox.SelectedIndex >= 0 Then
Dim cust As Customer = CType(ListComboBox.SelectedItem,
Customer)
MessageBox.Show(String.Format("ID = {0}, Customer Name = {1}",
_
cust.CustomerID, cust.CustomerName), "Combo Box",
MessageBoxButtons.OK, _
MessageBoxIcon.Information,
MessageBoxDefaultButton.Button1)
End If
End Sub

Private Class Customer

Private _CustomerName As String
Public Property CustomerName() As String
Get
Return _CustomerName
End Get
Set(ByVal value As String)
_CustomerName = value
End Set
End Property

Private _CustomerID As Integer
Public Property CustomerID() As Integer
Get
Return _CustomerID
End Get
Set(ByVal value As Integer)
_CustomerID = value
End Set
End Property

Private Sub New()

End Sub

Public Shared Function Create(ByVal id As Integer, ByVal name As
String) As Customer
Dim cust As New Customer()
cust.CustomerID = id
cust.CustomerName = name
Return cust
End Function

Public Overrides Function ToString() As String
Return Me.CustomerName
End Function
End Class
End Class





Robin S.
-----------------------
Jerad Rose said:
Thanks for the response, Robin.

Yes, I understand that the object is the fundamental class behind every
class. I guess I wasn't clear on my confusion.

To me, when an object is used as a parameter, it leaves too much open for
type mismatches. For example, since the ComboBox allows you to bind to a
list of strings, a dataset, etc., I would think it would be better to
have these explicitly defined as overloaded parameters (i.e. Add(string[]
items), Add(DataSet dataSet), etc.), rather than just the open-ended
Object. This approach seems to regress us back to the days of VB6 and
late binding.

But my main point is this. There is currently no way to add an item to a
combo box that has a different Value and Text property, other than
creating my own name/value pair class, and passing that to the Add
method. This seems ridiculous to me. In fact, I'm not even sure I can
set the Text of a ComboBox Item separately from the Value, since Item is
an Object, and therefore there is no ComboBox1.Items[0].Text property.

Do you see my point?

Thanks again.
Jerad

RobinS said:
All of .Net is based on objects. Everything is an object. You can bind
your ComboBox to a list of strings, a list of objects, a dataset, etc.
If you bind it to a list of string, [item] is a string. If you bind it
to a list of objects, [item] is an object of that type. If you bind it
to a dataset or datatable, [item] is a datarow. I'm not sure exactly
what your problem is, but it seems to make a lot of sense to me.

Robin S.
-----------------------------
Jerad Rose said:
I'm baffled by this -- is there not a typed object used for ComboBox
Items? Best I can tell, all of the methods for ComboBox that accept an
Item are of type Object. Why in the world is a common/standard .NET
control accepting an Object as a parameter type?

In Web Forms, there is a ListItem object that can be passed in to
add/retrieve objects from a DropDownItems collection. I searched
Google groups, and all the solutions I'm finding are creating their own
custom name/value pair class, and using that when adding items to a
ComboBox. Seriously?

It would even be forgivable for .NET 1.0 or 1.1, but we're several
years later in .NET 2.0, and it's still using objects?

Please, can someone give me a logical reason behind this? I'd really
like to be wrong on this, and am just totally missing something.

Thanks in advance.
 
Thanks again Robin for your response.

I've been able to use databinding before to populate ComboBoxes. My main
issue is that there is no built-in method for adding simple value/text pairs
to ComboBoxes. For example, in ASP.NET, I can do this:

MyDropDownList.Items.Add(new ListItem("SomeValue", "SomeText"))

(See http://msdn2.microsoft.com/en-us/library/e7s6873c.aspx)

And be done with it. But in order to accomplish this in WindowsForms, I
have to create my own "ListItem" class (or something similar), and pass it
to the ComboBox.Items.Add method (see
http://msdn2.microsoft.com/en-us/library/system.windows.forms.combobox.objectcollection.add.aspx).
I understand that it is open to accepting various types of objects, which
actually provides more flexibility. But I would think the preferred
approach would be to set up the Add method to accept a base class (like
ListItem) which can be implemented by other classes for this purpose. But
the DropDownList on Web Forms is completely inconsistent with Windows Forms
ComboBox in this respect.

I'd be curious to find out the reasoning behind this.

Anyway, thanks again for your input.

Jerad

RobinS said:
If you have a name/value pair in a class, with a ToString method, and you
bind that to the combobox, I believe you will find the ToString result
shows up in the combobox. If you don't put in the ToString method, I think
it just shows the name of the class or something like that.

Here's an example in VB. I can convert this in C# if you want. This one is
databound. If you want one that's not databound, I can give you that one
too. This is from a small project I wrote that shows 5 different ways to
put data in and take data out of a combobox. If you post your e-mail, I'll
send it to you.


Public Class MainForm


Dim CustomerList As List(Of Customer)
Private _Loading as Boolean

'CustomerTable is already loaded from the database.
Private Sub LoadComboBoxes()
_Loading = True
'add a blank entry to the list
CustomerList = New List(Of Customer)
CustomerList.Add(Customer.Create(0, String.Empty))
Dim CbxCount As Integer = 0
For Each dr As DataRow In CustomerTable.Rows
CustomerList.Add(Customer.Create(CType(dr("CustomerID"),
Integer), _
dr("CustomerName").ToString))
Next dr
ListComboBox.DataSource = CustomerList
ListComboBox.DisplayMember = "CustomerName"
ListComboBox.ValueMember = "CustomerID"
_Loading = False
End Sub

Private Sub ListComboBox_SelectedIndexChanged(ByVal sender As Object,
ByVal e As System.EventArgs) Handles ListComboBox.SelectedIndexChanged
If Not _Loading AndAlso TableComboBox.SelectedIndex >= 0 Then
Dim cust As Customer = CType(ListComboBox.SelectedItem,
Customer)
MessageBox.Show(String.Format("ID = {0}, Customer Name = {1}",
_
cust.CustomerID, cust.CustomerName), "Combo Box",
MessageBoxButtons.OK, _
MessageBoxIcon.Information,
MessageBoxDefaultButton.Button1)
End If
End Sub

Private Class Customer

Private _CustomerName As String
Public Property CustomerName() As String
Get
Return _CustomerName
End Get
Set(ByVal value As String)
_CustomerName = value
End Set
End Property

Private _CustomerID As Integer
Public Property CustomerID() As Integer
Get
Return _CustomerID
End Get
Set(ByVal value As Integer)
_CustomerID = value
End Set
End Property

Private Sub New()

End Sub

Public Shared Function Create(ByVal id As Integer, ByVal name As
String) As Customer
Dim cust As New Customer()
cust.CustomerID = id
cust.CustomerName = name
Return cust
End Function

Public Overrides Function ToString() As String
Return Me.CustomerName
End Function
End Class
End Class





Robin S.
-----------------------
Jerad Rose said:
Thanks for the response, Robin.

Yes, I understand that the object is the fundamental class behind every
class. I guess I wasn't clear on my confusion.

To me, when an object is used as a parameter, it leaves too much open for
type mismatches. For example, since the ComboBox allows you to bind to a
list of strings, a dataset, etc., I would think it would be better to
have these explicitly defined as overloaded parameters (i.e. Add(string[]
items), Add(DataSet dataSet), etc.), rather than just the open-ended
Object. This approach seems to regress us back to the days of VB6 and
late binding.

But my main point is this. There is currently no way to add an item to a
combo box that has a different Value and Text property, other than
creating my own name/value pair class, and passing that to the Add
method. This seems ridiculous to me. In fact, I'm not even sure I can
set the Text of a ComboBox Item separately from the Value, since Item is
an Object, and therefore there is no ComboBox1.Items[0].Text property.

Do you see my point?

Thanks again.
Jerad

RobinS said:
All of .Net is based on objects. Everything is an object. You can bind
your ComboBox to a list of strings, a list of objects, a dataset, etc.
If you bind it to a list of string, [item] is a string. If you bind it
to a list of objects, [item] is an object of that type. If you bind it
to a dataset or datatable, [item] is a datarow. I'm not sure exactly
what your problem is, but it seems to make a lot of sense to me.

Robin S.
-----------------------------
I'm baffled by this -- is there not a typed object used for ComboBox
Items? Best I can tell, all of the methods for ComboBox that accept an
Item are of type Object. Why in the world is a common/standard .NET
control accepting an Object as a parameter type?

In Web Forms, there is a ListItem object that can be passed in to
add/retrieve objects from a DropDownItems collection. I searched
Google groups, and all the solutions I'm finding are creating their own
custom name/value pair class, and using that when adding items to a
ComboBox. Seriously?

It would even be forgivable for .NET 1.0 or 1.1, but we're several
years later in .NET 2.0, and it's still using objects?

Please, can someone give me a logical reason behind this? I'd really
like to be wrong on this, and am just totally missing something.

Thanks in advance.
 
Back
Top