How to bind a ComboBox to a generic List with deep DisplayMember and ValueMember properties?

Adolfo Perez picture Adolfo Perez · Apr 15, 2011 · Viewed 12.6k times · Source

I am trying to bind a generic list like List Parents to a ComboBox.

    public Form1()
    {
        InitializeComponent();
        List<Parent> parents = new List<Parent>();
        Parent p = new Parent();
        p.child = new Child();
        p.child.DisplayMember="SHOW THIS";
        p.child.ValueMember = 666;
        parents.Add(p);
        comboBox1.DisplayMember = "child.DisplayMember";
        comboBox1.ValueMember = "child.ValueMember";
        comboBox1.DataSource = parents;
    }
}
public class Parent
{
    public Child child { get; set; }
}
public class Child
{
    public string DisplayMember { get; set; }
    public int ValueMember { get; set; }
}

When I run my test app I only see: "ComboBindingToListTest.Parent" displayed in my ComboBox instead of "SHOW THIS". How can I bind a ComboBox to a Generic List through one level or deeper properties e.g. child.DisplayMember??

Thanks in Advance, Adolfo

Answer

essedbl picture essedbl · Apr 15, 2011

I don't think you can do what you ar attempting. The design above shows that a Parent can only have one child. Is that true? Or have you simplified the design for the purpose of this question.

What I would recommend, regardless of whether a parent can have multiple children, is that you use an anonymous type as the Data Source for the combo box, and populate that type using linq. Here is an example:

private void Form1_Load(object sender, EventArgs e)
{
    List<Parent> parents = new List<Parent>();
    Parent p = new Parent();
    p.child = new Child();
    p.child.DisplayMember = "SHOW THIS";
    p.child.ValueMember = 666;
    parents.Add(p);

    var children =
        (from parent in parents
            select new
            {
                DisplayMember = parent.child.DisplayMember,
                ValueMember = parent.child.ValueMember
            }).ToList();

    comboBox1.DisplayMember = "DisplayMember";
    comboBox1.ValueMember = "ValueMember";
    comboBox1.DataSource = children;     
}