简体   繁体   English

尝试从ListBox键值对中读取“值”时出现无效的强制转换错误

[英]Invalid Cast Error when trying to read “Value” from a ListBox Key-Value pair

I'm using Visual Studio 2010 express and working on a C# WinForms application. 我正在使用Visual Studio 2010 express并在C#WinForms应用程序上工作。

My form has a ListBox object ( listData ) which has its DataSource set to use a Key-Value paired Dictionary object ( dictionary ). 我的表单有一个ListBox对象( listData ),其DataSource设置为使用Key-Value配对的Dictionary对象( dictionary )。

This is the Dictionary and how it is assigned as a DataSource to listData - 这是字典以及它如何被分配为listDataDataSource -

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

And when debugging I see that the "Value" is being assigned correctly and is clearly a number. 在调试时,我看到“Value”被正确分配,显然是一个数字。 Yet when I try to accept the same "Value" into a uint lastSelectedIndex , I get this cast error- 然而,当我尝试在uint lastSelectedIndex接受相同的“值”时,我得到了这个演员错误 -

在此输入图像描述

What am I doing wrong here? 我在这做错了什么?


This actually worked for me: 这实际上对我有用:

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

You should change this line. 你应该改变这一行。

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

to

listData.DataSource = dictionary;

The BindingSource constructor requires two parameters. BindingSource构造函数需要两个参数。 first one is for data source and second one for DataMember (ValueMember as we can say). 第一个用于数据源,第二个用于DataMember(我们可以说是ValueMember)。 You have specified null value into second parameter that's why BindingSource has taken whole KeyValuePair object as a DataMember. 您已将null值指定为第二个参数,这就是BindingSource将整个KeyValuePair对象作为DataMember的原因。

I don't think that you need to create object of BindingSource class to bind the Dictionary class. 我不认为你需要创建BindingSource类的对象来绑定Dictionary类。 but, if you still want to use then you should also specify the DataMember in second parameter. 但是,如果您仍想使用,则还应在第二个参数中指定DataMember。

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

But, I don't know whether it will work or not. 但是,我不知道它是否会起作用。 i haven't tried like this before. 我之前没有这样尝试过。

The another approach is to convert the SelectedValue into KeyValuePair object and get the Value from it. 另一种方法是将SelectedValue转换为KeyValuePair对象并从中获取Value。

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

You are trying to cast KeyValuePair object into uint. 您正在尝试将KeyValuePair对象转换为uint。 So, it cannot be convertable. 所以,它无法转换。 You have to convert it into KeyValuePair type first then get the value from Value property of that object. 您必须先将其转换为KeyValuePair类型,然后从该对象的Value属性中获取值。

I would like to suggest you to create another class where the class is having two properties 我想建议你创建另一个类,其中类有两个属性

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

The create a List<MyDataClass> object and fill the data into it. 创建一个List<MyDataClass>对象并将数据填充到其中。

Now you can assig that List object directly into that List control. 现在,您可以将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";

The reason for this issue is the order you have used to assign the DataSource and the ListBox' ValueMember property. 出现此问题的原因是您用于分配DataSource和ListBox的ValueMember属性的顺序。 If you assign the DataSource as last step it works: 如果您将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

The ListBox' SelectedIndexChanged event will be triggered as soon as you assign the DataSource. 分配DataSource后,将立即触发ListBox的SelectedIndexChanged事件。 Since you haven't specified the ValueMember at that time you get the InvalidCastException . 由于您当时未指定ValueMember ,因此您将获得InvalidCastException

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM