Binding to nested property only showing first item

2019-05-26 02:17发布

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

1条回答
放我归山
2楼-- · 2019-05-26 02:51

It seems that setting DisplayMember to "NestedItem.Name" only displaying NestedItem.Name property of SelectedItem -I tested this, if SelectedItem changed, the Name displayed also changed accordingly-. The easiest work around is to add another property for DisplayMember :

public class MyItem
{
    public NestedItem NestedItem { get; set; }
    public int Number { get; set; }
    public String NestedItemName { get { return NestedItem.Name; } }
}

Then set the DisplayMember :

listBox1.DisplayMember   = "NestedItemName";

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 :

listBox1.DisplayMember = (listBox1.DisplayMember == "Number") ? "NestedItem.Name" : "Number";

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 that SelectedItem's NestedItem.Name displayed.

查看更多
登录 后发表回答