views:

4685

answers:

4

I am writing a winforms app in which a user selects an item from a listbox and edits some data that forms part of an associated object. The edits are then applied from the object list to an underlying file.

In ASP.Net assigning a different system value to a list item than the display text the user sees is trivial. In a winforms app you have to set the "Displaymember" and the "Valuemember" of each item in a slightly more complicated (and not oft related on the internet) process.

This I have done. In debug mode I have confirmed that every item now has a value which is the display member (a "friendly" string that the user sees) and a key, the valuemember, which holds the key to a hashtable object where the data to be updated exists.

So when a user picks a string to edit the program should pass the "key" to the hashtable, yank out the object and allow editing to take place upon it.

The catch?

I can't see any obvious way of telling the program to look at the item's valuemember. I naively expected it to populate the list box's "SelectedValue" property, but that would be too simple by far. So how the hell do I get to the list item value?

A: 

Try grabbing the "ValueMember" from within the ListBox1_SelectedValueChanged event.

private void ListBox1_SelectedValueChanged(object sender, EventArgs e)
{
    if (ListBox1.SelectedIndex != -1)
    {
        string orbit = ListBox1.SelectedValue.ToString();
    }
}

ArrayList planets = new ArrayList();
planets.Add(new Planet("Mercury", "1"));
planets.Add(new Planet("Venus", "2"));

//Remember to set the Datasource
ListBox1.DataSource = planets;
//Name and Orbit are properties of the 'Planet' class
ListBox1.DisplayMember = "Name";
ListBox1.ValueMember = "Orbit";
Phaedrus
+2  A: 

Using both the SelectedIndexChanged and SelectedValueChanged didn't work for me - the ListBox's SelectedValue property was always null. This surprised me, too.

As a lame workaround, you could just pull the object out of the ListBox directly, using the SelectedIndex:

public Form1()
{
    InitializeComponent();

    this.listBox1.DisplayMember = "Name";
    this.listBox1.ValueMember = "ID";

    this.listBox1.Items.Add(new Test(1, "A"));
    this.listBox1.Items.Add(new Test(2, "B"));
    this.listBox1.Items.Add(new Test(3, "C"));
    this.listBox1.Items.Add(new Test(4, "D"));
    this.listBox1.Items.Add(new Test(5, "E"));
}

private void OnSelectedIndexChanged(object sender, EventArgs e)
{
    if(-1 != this.listBox1.SelectedIndex)
    {
        Test t = this.listBox1.Items[this.listBox1.SelectedIndex] as Test;
        if(null != t)
        {
            this.textBox1.Text = t.Name;
        }
    }
}

(Test is just a simple class with two properties - ID and Name).

It seems like there should be a better way, but if nothing else this should work.

Andy
Did you set the DataSource property?
Phaedrus
I did not, but I was only trying to put together a quick sample. I assumed (incorrectly?) that the SelectedValue would be set regardless of where the data came from.
Andy
+1  A: 

Okay so the answer came as a result of Andy's answer, hence my upvoting that answer.

But when I created a little class and tried to cast the listitem into that class the program threw an exception.

Revealingly the exception told me that the program could not cast a DictionaryEntry into a class of the type I had defined.

So I deleted the proxy class and reframed the request thus:

DictionaryEntry de = (DictionaryEntry)listbox.SelectedItem;
string htKey = de.Key.ToString();

And it's all good.

Bizarrely simple answer in the end. Thanks for the hint Andy.

As this *is* the answer I will accept it in 48 hours.
A: 

hehehe I ended up here when I was searching how to get the value of an Item in ListBox, then the obvious came to my mind. The secret is that Item method in c#, VB and others is an array, so to get a value of any Item you just have to write this:

ListBox1.Items[1].toString();//Get value of the #1 Item in the ListBox;

To get all the Items and put into a document or to a string, just do a for like this:

String Value;
for(int c=0;c<ListBox1.Items.Count;c++){
Value = Value + ListBox1.Items[c].toString();
}
//Thats it

I hope I helped you guys out. This is the most simple answer to your post.