I am trying to bind a ListBox Control in C# Winforms in .NET 4.5 to a list of objects that have a nested property that I wish to use for a DisplayMember. It sort of works except that when I set the DisplayMember to the nested property the listbox only shows one item even though there are two items in the list that it is bound to. If I comment out the code for setting the DisplayMember the listBox shows two items. Is this a bug in the framework? I would like to avoid adding another property or overriding ToString() if I can since I am implementing MVP and would like to keep my view logic isolated to my view. Here is some example code below.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
var bindingSource = new BindingSource();
var listOfMyItems = new BindingList<MyItem>
{
new MyItem { Number = 1, NestedItem = new NestedItem { Name = "name1", Note = "note1" } },
new MyItem { Number = 2, NestedItem = new NestedItem { Name = "name2", Note = "note2" } },
};
bindingSource.DataSource = listOfMyItems;
listBox1.DataSource = bindingSource;
//comment out the line below and the listBox1 will show 2 items
listBox1.DisplayMember = "NestedItem.Name";
}
}
public class NestedItem
{
public string Name { get; set; }
public string Note { get; set; }
}
public class MyItem
{
public NestedItem NestedItem { get; set; }
public int Number { get; set; }
}
It seems that setting
DisplayMember
to "NestedItem.Name" only displayingNestedItem.Name
property ofSelectedItem
-I tested this, if SelectedItem changed, the Name displayed also changed accordingly-. The easiest work around is to add another property for DisplayMember :Then set the
DisplayMember
:Not elegant, but still easier than using property descriptior as suggested here or here.
UPDATE :
Following is a quick test I did. Add a button to toggle
listBox1's DisplayMember
.Onclick
event handler :when
DisplayMember
set to "Number" you can choose any item in list -not necessarily the first item-, then click the button again. You'll see thatSelectedItem's NestedItem.Name
displayed.