简体   繁体   中英

How to iterate through the keys of a dictionary via ComboBox.Items

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).

Here is what I've tried

  • using dynamic item -> doesn't compile.
  • using KeyValuePair<string,dynamic> -> compiles but gets an identical runtime exception as noted above
  • using the var obj as dynamic / var obj as KeyValuePair<string,object> -> both always result in a null obj

Question:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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