开发者

Can't get Value from ComboBox

I have a simple comboBox with some Value/Text items in it. I have using ComboBox.DisplayMember and ComboBox.ValueMember to correctly set the value/text. When I try to get the value, it returns an empty string. Here's my code:

FormLoad event:

cbPlayer1.ValueMember = "Value";
cbPlayer1.DisplayMember = "Text";

SelectIndexChanged of ComboBox event:

cbPlayer1.Items.Add(new { Value = "3", Text = "This should have a value of 3" });
Messag开发者_高级运维eBox.Show(cbPlayer1.SelectedValue+"");

And it returns an empty dialog box. I also tried ComboBox.SelectedItem.Value (which VS sees, see picture) but it does not compile:

'object' does not contain a definition for 'Value' and no extension method 'Value' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)

Can't get Value from ComboBox

What am I doing wrong?


Not sure what ComboBox.SelectedValue means, it has a SelectedItem property. That would not be set when you add an item, only when the user makes a selection.

The Items property is a collection of System.Object. That allows a combo box to store and display any kind of class object. But you'll have to cast it from object to your class type to use the selected object in your code. That can't work in your case, you added an object of an anonymous type. You'll need to declare a small helper class to store the Value and Text properties. Some sample code:

  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
      comboBox1.Items.Add(new Item(1, "one"));
      comboBox1.Items.Add(new Item(2, "two"));
      comboBox1.SelectedIndexChanged += new EventHandler(comboBox1_SelectedIndexChanged);
    }
    void comboBox1_SelectedIndexChanged(object sender, EventArgs e) {
      Item item = comboBox1.Items[comboBox1.SelectedIndex] as Item;
      MessageBox.Show(item.Value.ToString());
    }
    private class Item {
      public Item(int value, string text) { Value = value; Text = text; }
      public int Value { get; set; }
      public string Text { get; set; }
      public override string ToString() { return Text; }
    }
  }


As you have seen in the debugger, SelectedItem contains the information you need. But to access SelectedItem.Value, you need to cast SelectedItem to the appropriate type (which is problematic if you are using an anonymous type) or use reflection. (VS can't compile SelectedItem.Value because at compile time VS only knows that SelectedItem is of type Object, which doesn't have a Value property.)

To use reflection to get the Value member, use Type.InvokeMember with BindingFlags.GetProperty.

To cast SelectedItem, declare a named type with Value and Text properties instead of using an anonymous type, and add instances of the named type to the ComboBox, instead of instances of the anonymous type. Then cast SelectedItem: ((MyType)(cb.SelectedItem)).Value.


Not sure why SelectedValue doesn't return anything... I assume it could be due to the fact that you're not using data binding (DataSource). You should try to assign a list of cards to the DataSource property.

Regarding the issue with SelectedItem : ComboBox.SelectedItem is of type Object, which doesn't have a property named Value. You need to cast it to the item's type ; but since it is an anonymous type, you can't... you should probably create a type to hold the value and text of the card, and cast to this type :

Card card = ComboBox.SelectedItem as Card;
if (card != null)
{
    // do something with card.Value
}


You are modifying the contents of the ComboBox in SelectedIndexChanged handler. When you modify the contents, it causes the selected items to be unset. Set you are reading in null, which is displayed in the message box as an empty string.


I am curious whether you are binding the combobox to a collection, or populating it manually. If you are binding the combobox to a data source of some kind...you should be adding items to the data source, not the combobox itself. When an item is added to the datasource, the combobox should update in kind.

If you are not binding, then adding an item will not cause that item to be selected. You would need to either wait for the user to select the item, or programmatically select the item in code.


To avoid having to create a new class for all your comboboxes I would suggest you just use a KeyValuePair like in the following example:

cbPlayer1.ValueMember = "Value";
cbPlayer1.DisplayMember = "Key";

cbPlayer1.DataSource = new List<KeyValuePair<string,string>>()
{new KeyValuePair<string,string>("3","This should have the value of 3")};

You still need to cast the selected value

string selectedValue = (string)cbPlayer1.SelectedValue;

MessageBox.Show(selectedValue);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜