Binding empty dictionary to a listbox - c#

When i try to bind a dictionary to a listbox I get an ArgumentException. Cannot bind to the new value member.
I use the following code.
Can any one tell me what is wrong. Because when i enter i row in the dictionary its working fine...
this.contactpersonenListBox = new Dictionary<int, string>();
lsContactpersonen.DataSource = new BindingSource(this.contactpersonenListBox, null);
lsContactpersonen.DisplayMember = "Value";
lsContactpersonen.ValueMember = "Key";

It doesn't make a ton of sense to bind an empty dictionary since the dictionary object doesn't report any changes, so adding an item to the dictionary after setting the data source won't show up in the ListBox.
But to get rid of the error, try setting it like this:
BindingSource b = new BindingSource();
b.DataSource = this.contactpersonenListBox;
lsContactpersonen.DisplayMember = "Value";
lsContactpersonen.ValueMember = "Key";
lsContactpersonen.DataSource = b;

Related

First Value of dictionary not getting assigned to combobox in C#

I am using Dictionary collection in C#. I want to display first value of dictionary
to combo box so that combo box by default shows first value.but instead of the first value null value get assigned.
I tried following code:
Dictionary<string, string> sampleDictionary = new Dictionary<string, string>();
sampleDictionary.add("ABC","XYZ");
sampleDictionary.add("JKL","PQR");
comboBox.SelectedValue=sampleDictionary.Values.First();
Try comboBox.SelectedIndex = 0;
You should add the values of the dictionary to your comboBox as follows:
Dictionary<string, string> sampleDictionary = new Dictionary<string, string>();
comboBox.DataSource = new BindingSource(sampleDictionary, null);
comboBox.DisplayMember = "Key";
comboBox.ValueMember = "Value";
Then, you could try: comboBox.SelectedIndex = 0;

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.
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;
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";
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.

WinForms ComboBox

I'm trying to mark one of the combobox items as selected.
So I am building my combobox like this:
var drop = new Dictionary<int, string>();
while (RegReader.Read())
{
drop.Add(Convert.ToInt32(RegReader["intRulesID"]), RegReader["txtName"].ToString());
}
RegRuleDrop.DataSource = new BindingSource(drop, null);
RegRuleDrop.DisplayMember = "Value";
RegRuleDrop.ValueMember = "Key";
Now, one of the items within the RegRuleDrop should be pre selected based on a value from a reader above this code.
Now, the problem is that I need to select value based on the actual ListItem VALUE and not TEXT.
So as an example
drop.Add(1, "Test");
drop.Add(2, "Test2");
drop.Add(3, "Test3");
I need to find the index using 1,2 or 3 not Test, Test2 or Test3
Any ideas?
When you have the DataSource set to a BindingSource the only action needed to select an item given a value belonging to the ValueMember property is
drop.Add(1, "Test1");
drop.Add(2, "Test2");
drop.Add(99, "Test99");
drop.Add(3, "Test3");
.....
RegRuleDrop.SelectedValue = 99

Parsing SelectedValue of a ListBox to int using C#.NET

I've a listbox that uses a dictionary as a datasource.
When I want to parse the listbox's selectedvalue to a int variable, it gives me a cast exception.
The dictionary~
Dictionary<int, string> AssetDictionary = new Dictionary<int, string>();
The listbox (lstAsset) datasource~
lstAsset.DisplayMember = "Value";
//lstAssetType.ValueMember = "Key"; //This should be lstAsset as corrected in the next line
lstAsset.ValueMember = "Key";
lstAsset.DataSource = new BindingSource(AssetDictionary, null);
The line where exception occurs~
int ush = (int)lstAsset.SelectedValue; //Specified cast is not valid.
Where am I doing wrong?
Provide Value Member to correct control.
lstAsset.ValueMember = "Key";
and use
int ush = Convert.ToInt32(lstAsset.SelectedValue.ToString());

ComboBox AutoComplete with Key/Value Pair

I have a ComboBox with the following code:
private void comboBox1_TextChanged(object sender, EventArgs e)
{
using (var service = WebServiceHelper.GetCoreService())
{
string physicianXml = service.SearchPhysicians(SessionInfo.Current.ClientCode, SessionInfo.Current.MachineName,
SessionInfo.Current.Username, comboBox1.Text);
var physicians = PhysicianItemList.FromXml(physicianXml);
AutoCompleteStringCollection autoCompleteStringCollection = new AutoCompleteStringCollection();
foreach (var physician in physicians.Items)
{
autoCompleteStringCollection.Add(physician.LastName + ", " + physician.FirstName);
}
comboBox1.AutoCompleteCustomSource = autoCompleteStringCollection;
comboBox1.Select(comboBox1.Text.Length, 0);
}
}
Basically, a user types the first few characters of a physician's name and it should populate the auto-complete list with the top 100 matching records. It works great, but I need to associate it back to a key (either the PK from the table, or the Physician's NPI number). It seems the AutoCompleteStringCollection doesn't support keys. Can anyone suggest a way of doing this? There are approximately 7 million records in the table, so I don't want to prepopulate the ComboBox.
Thanks
When you build your AutoCompleteStringCollection, build a Dictionary<String, int> for the name, id pairs as well. Then use some event (textbox validation or user submit/save click) to lookup and set the id. You could store the dictionary on the textbox Tag.
Edit
For some reason I thought you were working with a textbox control. Forget about the AutoCompleteStringCollection and just build a Dictionary<String, int>. For the combobox set your autocompletesource to ListItems, set the combobox display name and value and set the datasource to the dictionary.
combobox.DisplayMember = "key";
combobox.ValueMember = "value";
combobox.AutocompleteSource = AutocompleteSource.ListItems;
combobox.DataSource = myDictionary;
However you should only populate the datasource and autocomplete once when the user enters n characters in the combobox, otherwise it gets buggy. I tried to use this for a dynamic autocomplete once (eg the list clears if the user clear the text and retypes), but I had to forget about the combobox and use a hybrid textbox listbox approach much like this user
It looks like your problem is that AutoCompleteStringComplete was made specifically for strings (hence, the name).
You may want to look into the parents (IList, ICollection, IEnumerable) and see if you can homebrew something templated toward a key/value struct.
Too late but maybe someone will use this code :
this.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems;
this.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.SuggestAppend;
RNProveedor rnProveedor = new RNProveedor();
var listaProveedores = rnProveedor.Buscar();
Dictionary<int, String> dicTemp = new Dictionary<int, string>();
foreach (var entidad in listaProveedores)
{
dicTemp.Add(entidad.ProvNro, entidad.ProNombre);
}
this.DataSource = new BindingSource(dicTemp, null);
this.DisplayMember = "Value";
this.ValueMember = "Key";
And to select the value
public int GetValorDecimal()
{
KeyValuePair<int, string> objeto = (KeyValuePair<int, string>)this.SelectedItem;
return objeto.Key;
}
With this example you won't have any problem with duplicated strings as the examples above

Categories