My application has the following method, which previously worked, but after refactoring into multiple assemblies no longer works.
/// <summary>
/// Attempt to set the combobox to the item with the supplied string
/// </summary>
protected void SetComboBoxSelection(ComboBox cmb, string ItemText)
{
if (cmb.DisplayMember.ToLower() == "key" && cmb.ValueMember.ToLower() == "value")
{
foreach (KeyValuePair<string, object> item in cmb.Items)
{
if (item.Key == ItemText || ((string)item.Key).HasPatternMatch(ItemText))
{
cmb.SelectedItem = item;
return;
}
}
}
}
I get the following exception:
System.InvalidCastException: 'Unable to cast object of type 'System.Collections.Generic.KeyValuePair`2[System.String,NetworkSyncObjects.NetworkFolder]' to type 'System.Collections.Generic.KeyValuePair`2[System.String,System.Object]'.'
This method is being used to set the selection of various comboboxes, each with a different dictionary type, but all of which has the 'key' as a string type. Now, my previous question was closed due to the very unhelpful answer of (paraphrasing) "thats not allowed. heres an duplicate question that only sort of explains why".
Once again, this code WORKED. But now it doesn't. I understand that it its apparently not working due to the supposed invalid casting of the items within the list. (The duplicate answer was about casting the list itself, not the items within the list).
dynamic item
-> doesn't compile.KeyValuePair<string,dynamic>
-> compiles but gets an identical runtime exception as noted abovevar obj as dynamic
/ var obj as KeyValuePair<string,object>
-> both always result in a null obj
How can I modify this method to work with any combobox whose itemsource is a Dictionary<string,T>
where T is various types of objects)?
For example, some will be: Dictionary<string,NetworkFolder>
, Dictionary<string,FileInfo>
, Dictionary<string,DirectoryInfo>
, Dictionary<string,int>
As far as I can tell, there is no way to access the Key
portion of the KeyValuePair within the list unless you cast the list, which is apparently not allowed without explicitly calling out the exact type in the keyvaluepair. Once again, no idea why this was working and now isnt. But here I am.
Updated Method, using the IDictionary
interface and directly accessing the datasource binding was how I resolved it.
Modified from this post: https://stackoverflow.com/a/55850559/12135042
protected void SetComboBoxSelection(ComboBox cmb, string ItemText)
{
if (cmb.DisplayMember.ToLower() == "key" && cmb.ValueMember.ToLower() == "value")
{
IDictionary Items = (IDictionary)((BindingSource)cmb.DataSource).DataSource;
int i = 0;
foreach (string item in Items.Keys)
{
if (item == ItemText || item.HasPatternMatch(ItemText))
{
cmb.SelectedIndex = i;
return;
}
i++;
}
}
}