2009-12-05 6 views
2

У меня есть простой comboBox с некоторыми элементами Value/Text. У меня есть ComboBox.DisplayMember и ComboBox.ValueMember, чтобы правильно установить значение/текст. Когда я пытаюсь получить значение, он возвращает пустую строку. Вот мой код:Не удается получить значение из ComboBox

FormLoad событие:

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

SelectIndexChanged события ComboBox:

cbPlayer1.Items.Add(new { Value = "3", Text = "This should have a value of 3" }); 
MessageBox.Show(cbPlayer1.SelectedValue+""); 

И это возвращает диалоговое окно пустым. Я также попытался ComboBox.SelectedItem.Value (который видит VS см рисунок), но он не компилируется:

'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?) 

alt text

Что я делаю неправильно?

ответ

6

Не уверен, что означает ComboBox.SelectedValue, у него есть свойство SelectedItem. Это не будет установлено при добавлении элемента, только когда пользователь сделает выбор.

Свойство Items - это коллекция System.Object. Это позволяет комбо-ящику хранить и отображать любые объекты класса. Но вам придется отбрасывать его с объекта на ваш тип класса, чтобы использовать выделенный объект в вашем коде. Это не может работать в вашем случае, вы добавили объект анонимного типа. Вам нужно объявить небольшой вспомогательный класс для хранения свойств Value и Text.Пример кода примера:

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; } 
    } 
    } 
+0

Это метод, который я предпочитаю делать. Спасибо за помощь, это сработало. – ademers

2

Как вы видели в отладчике, SelectedItem содержит необходимую информацию. Но чтобы получить доступ к SelectedItem.Value, вам нужно выделить SelectedItem соответствующему типу (что является проблематичным, если вы используете анонимный тип) или использовать отражение. (VS не может скомпилировать SelectedItem.Value, потому что при компиляции времени VS только знает, что SelectedItem имеет типа объект, который не имеет свойства Value.)

Чтобы использовать отражение для получения члена значения, используйте тип .InvokeMember с BindingFlags.GetProperty.

Чтобы выдать SelectedItem, объявите именованный тип с свойствами Value и Text вместо анонимного типа и добавьте экземпляры именованного типа в ComboBox вместо экземпляров анонимного типа. Затем выберите SelectedItem: ((MyType) (cb.SelectedItem)). Значение.

1

Не знаете, почему SelectedValue ничего не возвращает ... Я предполагаю, что это может быть связано с тем, что вы не используете привязку данных (DataSource). Вы должны попытаться присвоить список карт DataSource.

Что касается вопроса с SelectedItem: ComboBox.SelectedItem имеет тип Object, который не имеет свойство с именем Value. Вам нужно наложить его на тип элемента; но так как это анонимный тип, вы не можете ... Вы, вероятно, следует создать тип для хранения значения и текст карты, и приведение к этому типу:

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

Вы изменяете содержимое ComboBox в обработчике SelectedIndexChanged. Когда вы изменяете содержимое, это приводит к отключению выбранных элементов. Установите, что вы читаете значение null, которое отображается в поле сообщения как пустая строка.

0

Мне любопытно, являетесь ли вы привязкой к коллекции или собираете ее вручную. Если вы привязываете combobox к источнику данных какого-то рода ... вы должны добавлять элементы к источнику данных, а не к самому combobox. Когда элемент добавляется к источнику данных, combobox должен обновляться в натуральной форме.

Если вы не являетесь обязательным, то добавление элемента не приведет к выбору этого элемента. Вам нужно либо дождаться, когда пользователь выберет элемент, либо программным образом выделит элемент в коде.

0

Чтобы избежать того, чтобы создать новый класс для все вашего Наримера я предлагаю вам просто использовать KeyValuePair как в следующем примере:

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")}; 

Вам все еще нужно, чтобы бросить выбранное значение

string selectedValue = (string)cbPlayer1.SelectedValue; 

MessageBox.Show(selectedValue); 
Смежные вопросы