Reputation: 1973
I'm using Visual Studio 2010 express and working on a C# WinForms application.
My form has a ListBox object (listData
) which has its DataSource
set to use a Key-Value paired Dictionary object (dictionary
).
This is the Dictionary and how it is assigned as a DataSource
to listData
-
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. Yet when I try to accept the same "Value" into a uint lastSelectedIndex
, I get this cast error-
What am I doing wrong here?
This actually worked for me:
lastSelectedIndex = ((KeyValuePair<string, uint>)listData.SelectedItem).Value;
Upvotes: 3
Views: 873
Reputation: 460108
The reason for this issue is the order you have used to assign the DataSource
and the ListBox' ValueMember
property. If you assign the DataSource
as last step it works:
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. Since you haven't specified the ValueMember
at that time you get the InvalidCastException
.
Upvotes: 1
Reputation: 6849
You should change this line.
listData.DataSource = new BindingSource(dictionary, null);
to
listData.DataSource = dictionary;
The BindingSource constructor requires two parameters. first one is for data source and second one for DataMember (ValueMember as we can say). You have specified null value into second parameter that's why BindingSource has taken whole KeyValuePair object as a DataMember.
I don't think that you need to create object of BindingSource class to bind the Dictionary class. but, if you still want to use then you should also specify the DataMember in second parameter.
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.
uint lastSelectedIndex = ((KeyValuePair<string, uint>)listData.SelectedValue).Value
You are trying to cast KeyValuePair
object into 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.
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.
Now you can assig that List object directly into that List control.
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";
Upvotes: 3