Wrox Programmer Forums

Need to download code?

View our list of code downloads.

Go Back   Wrox Programmer Forums > Visual Basic > VB.NET 1.0 > VB.NET 2002/2003 Basics
Password Reminder
Register
| FAQ | Members List | Search | Today's Posts | Mark Forums Read
VB.NET 2002/2003 Basics For coders who are new to Visual Basic, working in .NET versions 2002 or 2003 (1.0 and 1.1).
Welcome to the p2p.wrox.com Forums.

You are currently viewing the VB.NET 2002/2003 Basics section of the Wrox Programmer to Programmer discussions. This is a community of tens of thousands of software programmers and website developers including Wrox book authors and readers. As a guest, you can read any forum posting. By joining today you can post your own programming questions, respond to other developers’ questions, and eliminate the ads that are displayed to guests. Registration is fast, simple and absolutely free .
DRM-free e-books 300x50
Reply
 
Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old June 3rd, 2004, 10:12 AM
Friend of Wrox
Points: 2,876, Level: 22
Points: 2,876, Level: 22 Points: 2,876, Level: 22 Points: 2,876, Level: 22
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Jun 2003
Location: Denver, CO, USA.
Posts: 428
Thanks: 57
Thanked 2 Times in 2 Posts
Default Manually Populating Value in Windows Form ComboBox

I am experiencing great frustration trying to simply populate a Windows Form Combobox with both a display item and return value. I have an UNSORTED dataset that I would like to simply sort and bind to it, but cannot come up with a way to do this. The problem is, I can't sort the data - the dataset is being created manually (in order to eliminate duplicate records retrieved by multiple Select statements) and the records are not being added in sort order as a result. The ComboBox won't let me set the Sorted property because it's bound and directs me to sort the dataset. Catch-22.

Being unable to do this the RIGHT way, I've resorted to populating the ComboBox manually so I can set the Sorted property. Adding the Display Item is as simple as combobox.Add("George"). Should be apiece of cake to then associate a different return value (just like in VB6), but I cannot find a Value property for the ComboBox.

 But how do I associate a different return value for this item, so that when "George" is selected, combobox.SelectedValue returns "147"? I do NOT want the Index of the selected value, I want a value that I have associated with "George". Nowhere can I find a property or method that lets me associate "147" with "George".

Is this just another case of "Can't be done in VS" or am I missing something?
Reply With Quote
  #2 (permalink)  
Old June 3rd, 2004, 03:58 PM
Imar's Avatar
Wrox Author
Points: 72,073, Level: 100
Points: 72,073, Level: 100 Points: 72,073, Level: 100 Points: 72,073, Level: 100
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Jun 2003
Location: Utrecht, Netherlands.
Posts: 17,089
Thanks: 80
Thanked 1,587 Times in 1,563 Posts
Default

Hi Ron,

The Add method expects an Object. So one way to do this is to create your own MyListBoxItem class. This class should expose at least two properties: a Value property and a Description property (you can choose other names, but these names are in synch with other .NET objects).

Once you have the new class, you should add instances of this class to the Items collection. If you provide a constructor that accepts a Value and a Description, you can do something like this:

  comboBox1.Items.Add(new MyListboxItem(147, "George"));

Finally, you should tell the combo box what properties to use on the object you have added for the Value and Display members:

  comboBox1.DisplayMember = "Description";
  comboBox1.ValueMember = "Value";

Remember that your combobox now holds a collection of MyListboxItem objects. So, if you get the SelectedItem, you get a generic Object that you need to cast to a MyListboxItem object before you can retrieve its Value and Description properties.

Hope this makes any sense; if not, let me know and I'll show you a more detailed example.

But, maybe you don't need all this. Can't you just sort the DataTable in the DataSet before you bind? Maybe this helps:
http://msdn.microsoft.com/library/de...ngdataview.asp

Basically, you can sort the data and expose it through a View instead off binding the DataSet directly.

Cheers,

Imar
---------------------------------------
Imar Spaanjaars
Everyone is unique, except for me.
Reply With Quote
  #3 (permalink)  
Old June 3rd, 2004, 04:26 PM
Friend of Wrox
Points: 2,876, Level: 22
Points: 2,876, Level: 22 Points: 2,876, Level: 22 Points: 2,876, Level: 22
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Jun 2003
Location: Denver, CO, USA.
Posts: 428
Thanks: 57
Thanked 2 Times in 2 Posts
Default

The solution I finally stumbled across is similar to what you've suggested below, except that I'm doing:

combobox.add(dataset.tables(0).row) ' TableRow contains my two fields

And then, as you pointed out, setting the DisplayMember and DisplayValue once the combobox has been populated. This avoids the conflict associated with setting the Sorted property on a bound combobox or creating an unnecessary view just to populate it. Either way this is an enormous PITA for what used to be as simple as:

combobox.AddItem("George")
combobox.ItemData(combobox.lastindexadded) = "147"

This "solution" furthermore creates another problem - that of retrieving and setting the SelectedValue property on the combobox. SelectedValue returns NOTHING when I use this technique (or there's some undocumented way I haven't stumbled across yet to get it to work). Instead, to get the selected value in the combobox, I had to do this (found by trial and error):

combobox.SelectedItem(0) ' assuming field 0 is the value field

Setting SelectedValue is even more painful. Hearkening back to my VB2 days, I've been forced to iterate through all the values in the combobox searching for the one I'm looking for, and then setting the index:

Dim intPos As Integer

For intPos = 0 To cboName.Items.Count - 1
   If combobox.Items.Item(intPos)(0) = Value Then
      combobox.SelectedIndex = intPos
   End If
Next

It took me *5* hours today to figure out how to do what should've taken me two minutes! I'm taking up a hit fund for the moron at MicroSoft who thought this was better than the old way, if anybody is interested in contributing.
Reply With Quote
  #4 (permalink)  
Old June 3rd, 2004, 04:38 PM
Imar's Avatar
Wrox Author
Points: 72,073, Level: 100
Points: 72,073, Level: 100 Points: 72,073, Level: 100 Points: 72,073, Level: 100
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Jun 2003
Location: Utrecht, Netherlands.
Posts: 17,089
Thanks: 80
Thanked 1,587 Times in 1,563 Posts
Default

Hi Ron,

I see your point, but you have to think a little bit outside the box to appreciate this implementation.

In classic VB, you could add simple objects to a drop down / combo. In most cases, that meant an Integer value and a String description. Perfect for 99% of the databinding solutions where you'd bind a domain table to a drop down.

With the .NET implementation, you can bind *any* object to the drop down, including your own custom objects. Happen to have an array of Manager objects laying around? Just drop them in the combox box. A list of products, employees, vehicles? Whatever it is you're working with, you can add it to the Items collection.

To retrieve the item again, you'll need to cast it to the appropriate type. As I said in my previous post, SelectedItem returns an Object, so you need to cast it to your type to get at its Value and Description properties:

Dim SelectedItem As MyListboxItem = CType(combobox1.SelectedItem, MyListboxItem)
Dim SelectedItemDescription As String = SelectedItem.Description ' returns George.

You can do the same with your implementation: simply cast the generic Object to a DataRow object.

This is one of those situations where what they say about .NET is true: ".NET makes the hard things easy and the easy things hard".....

Hope this helps,

Imar
---------------------------------------
Imar Spaanjaars
Everyone is unique, except for me.
Reply With Quote
  #5 (permalink)  
Old June 4th, 2004, 08:30 AM
Friend of Wrox
Points: 2,876, Level: 22
Points: 2,876, Level: 22 Points: 2,876, Level: 22 Points: 2,876, Level: 22
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Jun 2003
Location: Denver, CO, USA.
Posts: 428
Thanks: 57
Thanked 2 Times in 2 Posts
Default

This certainly sheds some light on our previous discussion on the topic. I now see that the combobox is much more powerful than it used to be. I'll try this approach if I can make up the time I lost figuring out my work-around. ;)

But would it have killed MS to have exposed the Value property as a list akin to what they've done with the Item property? I was brought up in the good old days when developers were encouraged to stick to the KISS principle rather than writing esoteric code that was difficult to understand and debug just for the WOW factor. This focus on classes and objects at the exclusion of simplicity just seems to me to add an unnecessary layer of complexity obfuscating what should be very straight-forward processing (necessitating additional documentation to explain why I should have to create one object just to populate another), not to mention producing bloatware with the creation of complex objects where a simple one would suffice. It also makes it difficult to find good examples on the Web demonstrating how to do what you've explained to me here. I'd imagine that a number of old VB6 programs will remain VB6 programs because of the difficulty in converting code like this.

This is, of course, a philosophical discussion (or, as some might put it, a gripe session) outside of the purpose of this forum, although I wish the MS folks were hanging out here so they could see some of the havoc they've created. Thanks again for your gentle reminder that I must keep up with the evolution of the platform even if I often can't see the point.
Reply With Quote
  #6 (permalink)  
Old June 4th, 2004, 08:50 AM
Imar's Avatar
Wrox Author
Points: 72,073, Level: 100
Points: 72,073, Level: 100 Points: 72,073, Level: 100 Points: 72,073, Level: 100
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Jun 2003
Location: Utrecht, Netherlands.
Posts: 17,089
Thanks: 80
Thanked 1,587 Times in 1,563 Posts
Default

I completely agree with you. IMO, they could have implemented it both ways. They could have created a SimpleMode property, for example. Once set to True, you can add old skool name/value pairs. SelectedItem.Value would then return the value of the selected item.
This is just one way but I am sure there are many other ways possible to simplify this control. Maybe the next version of the .NET Framework will make things easier.

In the mean time, you could file an Enhancement Request at the official Winforms site and forum: http://www.windowsforms.com/Forums/S...=41&ForumID=21

Cheers,

Imar
---------------------------------------
Imar Spaanjaars
Everyone is unique, except for me.
Reply With Quote
  #7 (permalink)  
Old June 4th, 2004, 09:05 AM
Friend of Wrox
Points: 2,876, Level: 22
Points: 2,876, Level: 22 Points: 2,876, Level: 22 Points: 2,876, Level: 22
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Jun 2003
Location: Denver, CO, USA.
Posts: 428
Thanks: 57
Thanked 2 Times in 2 Posts
Default

While we're on the subject, any clue for me why I would not be able to set SelectedIndex to 0 when the combobox.items.count = 7?
Reply With Quote
  #8 (permalink)  
Old June 4th, 2004, 09:19 AM
Imar's Avatar
Wrox Author
Points: 72,073, Level: 100
Points: 72,073, Level: 100 Points: 72,073, Level: 100 Points: 72,073, Level: 100
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Jun 2003
Location: Utrecht, Netherlands.
Posts: 17,089
Thanks: 80
Thanked 1,587 Times in 1,563 Posts
Default

No, I don't. That has always worked for me. How does your code look like?

Imar
---------------------------------------
Imar Spaanjaars
Everyone is unique, except for me.
Reply With Quote
  #9 (permalink)  
Old June 4th, 2004, 10:08 AM
Friend of Wrox
Points: 2,876, Level: 22
Points: 2,876, Level: 22 Points: 2,876, Level: 22 Points: 2,876, Level: 22
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Jun 2003
Location: Denver, CO, USA.
Posts: 428
Thanks: 57
Thanked 2 Times in 2 Posts
Default

Rife with the work-arounds previously described and I'd be embarrassed to share it. It would also take more effort on your part to figure it out than I want to ask. I was just hoping I had overlooked something obvious, as usual. :D

I can see nothing wrong with the code – it’s virtually identical with other code that works, so I’m at a loss to explain it. Like all the other anomalies I've experienced, I’ve isolated it inside a Try/Catch, which at least prevents the code from crashing. Other logic I'd already written returns a 0 on error (yet another work-around) so I'm getting the functionality I want, although with code I don't particularly like, but I'm getting used to that. I’d sure like to understand, though, how the Index can be set to 0 in one instance but not another, especially when I can reference position 0 with:

combobox.Items.Item(0)

When is a zero not a zero?

Thanks anyway, Imar!
Reply With Quote
  #10 (permalink)  
Old June 4th, 2004, 10:47 AM
Imar's Avatar
Wrox Author
Points: 72,073, Level: 100
Points: 72,073, Level: 100 Points: 72,073, Level: 100 Points: 72,073, Level: 100
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Jun 2003
Location: Utrecht, Netherlands.
Posts: 17,089
Thanks: 80
Thanked 1,587 Times in 1,563 Posts
Default

Well, you can e-mail it to me if you want? I promise I won't share it.... ;)

Anyway, if you need a specific item, you can use an indexer on the Items collection:

Dim myItem As MyListboxItem = CType(combo1.Items(0), MyListboxItem)

At this point, myItem should contain the first item in the drop down.

And I can use this code like you'd expect to preselect the first item:
Code:
      comboBox1.Items.Add(New MyListboxItem(147, "George1"))
      comboBox1.Items.Add(New MyListboxItem(148, "George2"))
      comboBox1.Items.Add(New MyListboxItem(149, "George3"))
      comboBox1.Items.Add(New MyListboxItem(150, "George4"))
      comboBox1.DisplayMember = "Description"
      comboBox1.ValueMember = "Value"
      comboBox1.SelectedIndex = 0
      Doesn't that work for you?

Cheers,

Imar
---------------------------------------
Imar Spaanjaars
Everyone is unique, except for me.
Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Combobox Populating Delay aw23 Access VBA 24 June 8th, 2005 03:39 AM
populate data in a windows form combobox from a da anibiswas General .NET 0 March 4th, 2005 03:57 PM
Populating report or form textboxes Bosstone100 Access VBA 3 November 15th, 2004 03:53 PM
Populating a form maneor Access 1 September 30th, 2004 03:41 PM
Populating Combobox by Code Syed Afzal Ahmed ADO.NET 1 July 12th, 2003 03:34 AM



All times are GMT -4. The time now is 02:15 PM.


Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
© 2013 John Wiley & Sons, Inc.