Welcome to AspAdvice Sign in | Join | Help

.Net Discoveries

An attempt to pass along some answers I have discovered in my .Net coding.
Using the WinForm ComboBox Like the Asp.Net DropDownList

Prologue

Most of the development I do centers around ASP.Net rather than WinForms. I do however do a little work in the WinForms sphere occasionally. I was putting something together the other day and found that there are some little, yet significant differences between the WinForms ComboBox and the ASP.Net DropDownList. Specifically I found that in the ASP.Net DropDownList, you can set the displayed text to be different than the value. The WinForms ComboBox doesn't allow this.

Problem

In the application I was developing, I wanted the ComboBox to behave like the ASP DropDownList and allowing me to display text yet have the VALUE returned be an integer that corresponded with another array. WinForms DOES support this, HOWEVER, not in as straight forward a way as you might think. (In the interest of giving credit where credit is due, I pieced together much of this post by reading a post and subsequent comments on Martin G. Brown's blog - Thanks for the help Martin).

Solution

First, a little about the difference between ASP and WinForms ComboBoxes. Take the example here of an ASP.Net DropDownList's front-end code:

<asp:DropDownList runat="server" ID="ddlTest">
    <asp:ListItem Text="My Name" Value="0" />
    <asp:ListItem Text="Your Name" Value="1" />
</asp:DropDownList>

or the following back-end code for adding items to an existing DropDownList:

ddlTest.Items.Add(New ListItem("My Name", 0))
ddlTest.Items.Add(New ListItem("Your Name", 1))

In either case, notice that I can explicitly set the value and the text to be different. This allows me to display friendly text, yet pass around a key (such as an ID) when the user selects the entry rather than having to use the text as a key. Also notice that I can set both of these at the same time. This would allow me to pull a list of objects, say names from a database, and then display them along with associated values (such as a primary key id) pretty quickly. Let's look at doing this with the WinForms combo box.

Let's do a little setup here so we can continue with our project when we're done "looking." Create a Windows Form application and add a ComboBox (name it cmboDoIt) and two Buttons (one named btnDoIt and one named btnShowIt).

Click on the ComboBox, go to the properties pane and click the ... button next to Items, you'll notice that the String Collection Editor comes up. It asks you to enter the strings for the collection, one per line. So you can enter the text, but not the values. Let's try doing it runtime and see if that'll do it.

If you go to the code behind and try adding an item, like you did for the DropDownList. Notice that the Item that you add is of type Object. But of what kind of object? String. This doesn't allow you to add a value to the item. So how could we do this? The answer lies in the ability of a ComboBox to be bound to a data source. If we create a data source with more than one "column", we can bind to the data source and then SPECIFY which column will be the text and which will be the value.

To do this, we first need to create a data source. We'll do this by creating a class to hold our two data pieces. Add the following class definition to our form, just before the final End Class tag:

Public Class ValueDescriptionPair
   Private _value As Object
   Private _description As String

   Public Sub New(ByVal Description As String, ByVal Value As Object)
      _value = Value
      _description = Description
   End Sub

   Public ReadOnly Property Value() As Object
      Get
         Return _value
      End Get
   End Property

   Public ReadOnly Property Description() As String
      Get
         Return _description
      End Get
   End Property

   Public Overrides Function ToString() As String
      Return _description
      End Function
End Class

Basically we create a class that can hold both our value and our description. We add a ToString function so that we don't end up with any funky output when we use our description. We also define a constructor so we can pass our value/description pair in to create the object. Now we can create an array of our ValueDescriptionPair objects, load it with data (we'll just do it by hand in this example) and then bind it all to our ComboBox. To do this, add the following to our btnDoIt_Click event handler.

Dim vdpArray As New ArrayList

vdpArray.Add(New ValueDescriptionPair("My Name", 0))
vdpArray.Add(New ValueDescriptionPair("Your Name", 1))
cmboDoIt.DataSource = vdpArray
cmboDoIt.ValueMember = "Value"
cmboDoIt.DisplayMember = "Description"

Here we create an ArrayList of our ValueDescriptionPair. We then add 2 elements, bind our DataSource and then define which member to assign as a value and which to assign as a description. Let's wire up one last piece before we run the application. Add the following to your btnShowIt_Click event handler:

MessageBox.Show("The value for " & cmboDoIt.SelectedItem.ToString & _
   " is " & cmboDoIt.SelectedValue)

This will just display your selected entry and the corresponding value. Now to use the value, all you need to do is use the ComboBox's SelectedValue property and you're good to go.

Note: as an FYI, this can also be done using a generic collection. Simply change the following lines (remember to add the Imports System.Collections.Generic statement to the top of the code as well):

Dim vdpArray As New ArrayList
Dim vdpArray As New List(Of ValueDescriptionPair)

Epilogue

There you have it. Pretty simple once you've got it all in place, but very convenient when needed. I'm not sure why you can't add data items that contain both value and description like you can with the DropDownList but it's an easy work around.

Posted: Monday, October 12, 2009 6:27 PM by Yougotiger

Comments

No Comments

Leave a Comment

(required) 

(required) 

(optional)

(required) 

Enter the code you see below

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS