尝试从 ListBox 键值对读取 "Value" 时出现无效的转换错误

Invalid Cast Error when trying to read "Value" from a ListBox Key-Value pair

我正在使用 Visual Studio 2010 express 并开发 C# WinForms 应用程序。

我的表单有一个 ListBox 对象 (listData),它的 DataSource 设置为使用键值对字典对象 (dictionary)。

这是词典以及如何将其作为 DataSource 分配给 listData-

Dictionary<string, uint> dictionary = new Dictionary<string, uint>();`
listData.DataSource = new BindingSource(dictionary, null);
listData.DisplayMember = "Key";
listData.ValueMember = "Value";

并且在调试时我看到 "Value" 被正确分配并且显然是一个数字。然而,当我尝试将相同的 "Value" 接受到 uint lastSelectedIndex 时,我得到了这个转换错误 -

我做错了什么?


这实际上对我有用:

lastSelectedIndex = ((KeyValuePair<string, uint>)listData.SelectedItem).Value;

您应该更改此行。

listData.DataSource = new BindingSource(dictionary, null);

listData.DataSource = dictionary;

BindingSource 构造函数需要两个参数。第一个用于数据源,第二个用于 DataMember(我们可以说是 ValueMember)。您在第二个参数中指定了空值,这就是 BindingSource 将整个 KeyValuePair 对象作为 DataMember 的原因。

我认为您不需要创建 BindingSource class 的对象来绑定字典 class。但是,如果您仍然想使用,那么您还应该在第二个参数中指定 DataMember。

listData.DataSource = new BindingSource(dictionary, "Value");

但是,我不知道它是否有效。我以前没有这样尝试过。

另一种方法是将 SelectedValue 转换为 KeyValuePair 对象并从中获取值。

uint lastSelectedIndex = ((KeyValuePair<string, uint>)listData.SelectedValue).Value

您正在尝试将 KeyValuePair 对象转换为 uint。所以,它不能转换。您必须先将其转换为 KeyValuePair 类型,然后从该对象的 Value 属性 中获取值。

我建议您创建另一个 class,其中 class 具有两个属性

public class MyDataClass
{
    public uint Value{ get; set;}
    public string Display{get;set;}
    public MyDataClass(string display, uint val)
    {
        Display = display;
        Value = val;
    }
    public override string ToString()
    {
         return this.Display;
    }
}

创建一个 List<MyDataClass> 对象并将数据填充到其中。

现在您可以将该 List 对象直接分配到该 List 控件中。

List<MyDataClass> lstItems = new List<MyDataClass>();
lstItems.Add(new MyDataClass("Item 1", 1));
lstItems.Add(new MyDataClass("Item 2", 2));
lstItems.Add(new MyDataClass("Item 3", 3));


listData.DataSource = lstItems;
listData.DisplayMember = "Display";
listData.ValueMember = "Value";

出现此问题的原因是您用于分配 DataSource 和列表框 ValueMember 属性 的顺序。如果您将 DataSource 指定为最后一步,它会起作用:

Dictionary<string, uint> dictionary = new Dictionary<string, uint>();
dictionary.Add("1", 1);
dictionary.Add("2", 2);
dictionary.Add("3", 3);

listData.DisplayMember = "Key";
listData.ValueMember = "Value";
var bs = new BindingSource();
bs.DataSource = dictionary;
listData.DataSource = bs;  // as last step

ListBox' SelectedIndexChanged 事件将在您分配数据源后立即触发。因为你当时没有指定 ValueMember 你得到 InvalidCastException.