带有字典数据源的列表框显示完整的 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 = 12
和 Description = "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。我不知道为什么会这样,但我想我只需要更改那行代码即可获得项目的价值 属性.
要获取 ComboBox
和 ListBox
中项目的文本,您应该始终使用 GetItemText
方法。
该方法检查是否设置了 ComboBox
的 DisplayMember
属性,然后 returns DisplayMember
中指定的成员的字符串表示形式属性 用于您传递给方法的对象,否则为对象的 returns ToString
。
var txt = listBox1.GetItemText(listBox1.Items[e.Index]);
我有一个以 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 = 12
和 Description = "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。我不知道为什么会这样,但我想我只需要更改那行代码即可获得项目的价值 属性.
要获取 ComboBox
和 ListBox
中项目的文本,您应该始终使用 GetItemText
方法。
该方法检查是否设置了 ComboBox
的 DisplayMember
属性,然后 returns DisplayMember
中指定的成员的字符串表示形式属性 用于您传递给方法的对象,否则为对象的 returns ToString
。
var txt = listBox1.GetItemText(listBox1.Items[e.Index]);