带有字典数据源的列表框显示完整的 KeyValuePair 而不仅仅是值

ListBox with Dictionary data source displays full KeyValuePair instead of just value

我有一个以 Dictionary<int, UmfTag> 作为数据源的列表框。我已将列表框的 DisplayMember 设置为 "Value" 并将 ValueMember 设置为 "Key," 但是当显示列表框时,它会显示所有 KeyValuePair 而不仅仅是值。

我的代码:

listBoxAllTags.DataSource = new BindingSource(punchedTagDict, null);
listBoxAllTags.DisplayMember = "Value";
listBoxAllTags.ValueMember = "Key";

每个KeyValuePair中的Value是我的自定义对象UmfTag。除了其他属性外,它还包含一个 ID 和一个描述。 UmfTag 的 ToString() 方法 returns String.Format("{0:D4} - {1}", Id, Description)。例如,对于具有 Id = 12Description = "Name" 的 UmfTag,值将显示为

0012 - Name

以上是我想要在列表框中显示的内容。不幸的是,出于某种原因,列表框显示整个 KeyValuePair 而不是仅显示 Value,因此它显示

[12, 0012 - Name]

正如您从我的代码中看到的那样,我明确地将 DisplayMember 设置为 "Value." 那为什么它不起作用?我尝试将 Dictionary<int, UmfTag> 转换为 List<KeyValuePair<int, UmfTag>>,但问题仍然存在。

可以将Dictionary转换为List<UmfTag>并忽略Key(因为Key是UmfTag本身的Id),但我想保留这个作为字典的集合。如果必须的话,我可以从列表中重建字典,但这似乎效率低下。

我一定是做错了什么,但我的代码似乎与所有其他关于使用字典和数据源的主题相同,所以我的问题是什么?

编辑: 因为我需要将列表中的某些项目加粗和斜体化,所以我编写了自己的 DrawListBox 方法,每当调用 listBoxAllTags_DrawItem 时都会调用该方法。这是我的方法:

private void DrawListBox(object sender, DrawItemEventArgs e, ListBox listBox, Dictionary<int, UmfTag> searchedDict)
{
    if(e.Index < 0) return;

    e.DrawBackground();
    FontStyle fontStyle = FontStyle.Regular;
    Brush brush = Brushes.Black;

    // Embolden the first x items, where x = the number of searched results
    if(e.Index < searchedDict.Count)
        fontStyle = FontStyle.Bold;

    // Make the selected item have white font (so you can see it over the blue background)
    if((e.State & DrawItemState.Selected) == DrawItemState.Selected)
        brush = Brushes.White;

    e.Graphics.DrawString(listBox.Items[e.Index].ToString(), new Font("Arial", 8, fontStyle), brush, e.Bounds);
    e.DrawFocusRectangle();
}

我在此方法中放置了一个断点,并调查了 e.Graphics.DrawString 调用 listBox.Items[e.Index].ToString() 的第一个参数的值。该值是完整的 KeyValuePair。我不知道为什么会这样,但我想我只需要更改那行代码即可获得项目的价值 属性.

要获取 ComboBoxListBox 中项目的文本,您应该始终使用 GetItemText 方法。

该方法检查是否设置了 ComboBoxDisplayMember 属性,然后 returns DisplayMember 中指定的成员的字符串表示形式属性 用于您传递给方法的对象,否则为对象的 returns ToString

var txt = listBox1.GetItemText(listBox1.Items[e.Index]);