使用字典作为数据源绑定组合框

72

我正在使用.NET 2.0,尝试将ComboBox的数据源绑定到已排序的字典。

所以我遇到的错误是“在数据源上找不到DataMember属性'Key'。”

        SortedDictionary<string, int> userCache = UserCache.getSortedUserValueCache();
        userListComboBox.DataSource = new BindingSource(userCache, "Key"); //This line is causing the error
        userListComboBox.DisplayMember = "Key";
        userListComboBox.ValueMember = "Value";
9个回答

154
SortedDictionary<string, int> userCache = new SortedDictionary<string, int>
{
  {"a", 1},
  {"b", 2},
  {"c", 3}
};
comboBox1.DataSource = new BindingSource(userCache, null);
comboBox1.DisplayMember = "Key";
comboBox1.ValueMember = "Value";

但是你为什么把ValueMember设置为"Value",它不应该绑定到"Key"(还有DisplayMember也应该绑定到"Value")吗?


1
"ArgumentException: 无法绑定到新的显示成员。参数名称:newDisplayMember。" 我不知道用户803952遇到了什么错误,但当我尝试使用IDictionary<int, string>时,我遇到了这个错误。 - Ryan Lundy
当我尝试将一个Dictionary<decimal, string>绑定到ComboBox并收到异常“Complex DataBinding accepts as a data source either an IList or an IListSource.”时,这个答案对我有用。 - kad81
我使用comboBox1.DataSource = new BindingSource(userCache, null)没有任何问题; 如果你认为这是有问题的语句,你可以尝试用以下语句替换它:comboBox1.DataSource = userCache.Select(kv => new { Key = kv.Key, Value = kv.Value }).ToArray(); - dmihailescu
3
你可能想尝试的另一件事是,在设置 DisplayMember 和 ValueMember 后,将行 comboBox1.DataSource = new BindingSource(userCache, null); 移动到下面。 - dmihailescu
2
有时候,如果在 DisplayMember 赋值之前分配了 DataSource,执行会在 DisplayMember 赋值行处阻塞。对我来说,这个方法可行 - cBox.DataSource = null; cBox.DisplayMember = "Value"; cBox.ValueMember = "Key"; cBox.DataSource = new BindingSource(dict, null); // @dmihailescu 是正确的 - Park JongBum
显示剩余2条评论

24
我使用了Sorin Comanescu的解决方案,但在尝试获取选定值时遇到了问题。我的组合框是一个工具栏组合框。我使用了"combobox"属性,它会公开一个普通的组合框。

我有一个

 Dictionary<Control, string> controls = new Dictionary<Control, string>();

绑定代码(Sorin Comanescu的解决方案-非常有效):

 controls.Add(pictureBox1, "Image");
 controls.Add(dgvText, "Text");
 cbFocusedControl.ComboBox.DataSource = new BindingSource(controls, null);
 cbFocusedControl.ComboBox.ValueMember = "Key";
 cbFocusedControl.ComboBox.DisplayMember = "Value";

问题在于我尝试获取选定的值时,没有意识到该如何检索它。经过几次尝试,我得到了以下代码:

 var control = ((KeyValuePair<Control, string>) cbFocusedControl.ComboBox.SelectedItem).Key

希望能对其他人有所帮助!


这个有效,我已经在我的代码中使用了以下内容使其工作。https://gist.github.com/psykzz/5374823 - PsyKzz
你也可以这样做(获取所选值): var value = comboBox.SelectedItem; var someItem = value.GetType().GetProperty("Key").GetValue(value, null); - Miroslav Lazovich
1
最后一行也可以简化为:var control = ((KeyValuePair<Control, string>) cbFocusedControl.ComboBox.SelectedItem).Key; 1)不必要的外部括号,2)编译器已经知道 Key 是一个 Control,因为它正在转换为 KeyValuePair<Control, string>,所以不需要将其转换为 Control。 - Adam Marshall
@AdamMarshall 感谢您的建议。已根据您的建议编辑了答案。 - CristisS
你为什么不直接使用 cbFocusedControl.ComboBox.SelectedTextcbFocusedControl.ComboBox.SelectedValue 来获取 DisplayMember 和 ValueMember 呢?这样会更简单。 - Sunny Patel

6
        var colors = new Dictionary < string, string > ();
        colors["10"] = "Red";

绑定到组合框

        comboBox1.DataSource = new BindingSource(colors, null);
        comboBox1.DisplayMember = "Value";
        comboBox1.ValueMember = "Key"; 

完整源代码...将字典作为组合框数据源

Jeryy


5
userListComboBox.DataSource = userCache.ToList();
userListComboBox.DisplayMember = "Key";

简洁明了。 - hubert17

2

一个字典不能直接用作数据源,你需要做更多的工作。

SortedDictionary<string, int> userCache =  UserCache.getSortedUserValueCache();
KeyValuePair<string, int> [] ar= new KeyValuePair<string,int>[userCache.Count];
userCache.CopyTo(ar, 0);
comboBox1.DataSource = ar; new BindingSource(ar, "Key"); //This line is causing the error
comboBox1.DisplayMember = "Value";
comboBox1.ValueMember = "Key";

2

我知道这个话题已经很老了,但我也遇到了同样的问题。

我的解决方案:

我们如何填充下拉框:

foreach (KeyValuePair<int, string> item in listRegion)
{
    combo.Items.Add(item.Value);
    combo.ValueMember = item.Value.ToString();
    combo.DisplayMember = item.Key.ToString();
    combo.SelectedIndex = 0;
}

这就是我们进入的方式:

 MessageBox.Show(combo_region.DisplayMember.ToString());

我希望它能帮助到某些人。


1
如果这不起作用,为什么不直接在字典上执行 foreach 循环,将所有项添加到组合框中呢?
foreach(var item in userCache)
{
    userListComboBox.Items.Add(new ListItem(item.Key, item.Value));
}

绑定和添加项目并不是同一回事。嗯,也许这正是原帖作者真正需要的,谁知道呢?;) - jv42
我知道,但我没有看到任何依赖于数据绑定本身的代码。 - thekip
好的,你提出的方法可以运行,但是 "new ListItem" 存在于 System.Web.UI.WebControls 命名空间中,我不会为 Windows 窗体应用程序导入它。 - user803952
我也不会这样做,不过我猜应该有一个 WinForms 的替代方案吧?我对 WinForms 不是很熟悉。 - thekip
可以使用 new ComboBoxItem("itemtext","itemid"); 来代替。 - ashveli

0

尝试像这样做...

SortedDictionary<string, int> userCache = UserCache.getSortedUserValueCache();

    // Add this code
    if(userCache != null)
    {
        userListComboBox.DataSource = new BindingSource(userCache, null); // Key => null
        userListComboBox.DisplayMember = "Key";
        userListComboBox.ValueMember = "Value";
    }

0

使用 -->

comboBox1.DataSource = colors.ToList();

除非将字典转换为列表,否则组合框无法识别其成员。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接