我有一个简单的组合框,里面有一些Value / Text项目。我使用ComboBox.DisplayMember和ComboBox.ValueMember来正确设置值/文本。当我尝试获取值时,它返回一个空字符串。这是我的代码:
FormLoad事件:
cbPlayer1.ValueMember = "Value";
cbPlayer1.DisplayMember = "Text";
ComboBox事件的SelectIndexChanged:
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?)
我做错了什么?
答案 0 :(得分: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; }
}
}
答案 1 :(得分:2)
正如您在调试器中看到的,SelectedItem包含您需要的信息。但是要访问SelectedItem.Value,您需要将SelectedItem强制转换为适当的类型(如果您使用的是匿名类型,则会出现问题)或使用反射。 (VS无法编译SelectedItem.Value,因为在 compile 时,VS只知道SelectedItem属于Object类型,它没有Value属性。)
要使用反射来获取Value成员,请将Type.InvokeMember与BindingFlags.GetProperty一起使用。
要转换SelectedItem,请使用Value和Text属性声明命名类型,而不是使用匿名类型,并将命名类型的实例添加到ComboBox,而不是匿名类型的实例。然后转换SelectedItem:((MyType)(cb.SelectedItem))。Value。
答案 2 :(得分:1)
不确定为什么SelectedValue
没有返回任何内容......我认为这可能是因为您没有使用数据绑定(DataSource
)。您应该尝试将卡列表分配给DataSource
属性。
关于SelectedItem
的问题:ComboBox.SelectedItem
类型为Object
,其中没有名为Value
的属性。你需要把它投射到项目的类型;但由于它是一个匿名类型,你不能......你应该创建一个类型来保存卡的值和文本,并转换为这种类型:
Card card = ComboBox.SelectedItem as Card;
if (card != null)
{
// do something with card.Value
}
答案 3 :(得分:1)
您正在SelectedIndexChanged处理程序中修改ComboBox的内容。修改内容时,会导致选中的项目未设置。设置您正在读取null,它在消息框中显示为空字符串。
答案 4 :(得分:0)
我很好奇你是将组合框绑定到一个集合,还是手动填充它。如果您将组合框绑定到某种数据源......您应该将项添加到数据源,而不是组合框本身。将项目添加到数据源时,组合框应以实物形式更新。
如果您没有绑定,则添加项目不会导致选择该项目。您需要等待用户选择项目,或者以编程方式选择代码中的项目。
答案 5 :(得分: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);