0
votes

I have a form which has two ComboBoxes. I'd like to use the second (child) ComboBox to display a list of child objects based on user selection of an item from the first.

When the form is instantiated, I databind both controls to private List<Widget>s like so:

private List<ParentWidget> _parentList;
private List<ChildWidget> _childList;

public FormExample()
{
    InitializeComponent();

    _parentList = GetParentWidgets();
    _childList = new List<ChildWidget>();

    cmbParent.DisplayMember = "WidgetName";
    cmbParent.ValueMember = "ID";
    cmbParent.DataSource = _parentList;

    cmbChild.DisplayMember = "WidgetName";
    cmbChild.ValueMember = "ID";
    cmbChild.DataSource = _childList;
}

When the parent selected index is changed, I then populate _childList with the appropriate objects.

The problem is the child ComboBox never shows any of the objects in the collection. It works if I populate the collection with at least one ChildWidget before databinding it, but I'd like it to start empty.

If I understand correctly from another answer, this is failing because the empty list does not contain any properties to bind to. However I am binding to a specific class (Widget) rather than a generic object. Is this not sufficient for the databinding?

2

2 Answers

1
votes

When using binding, you should better use the BindingList<> instead, your problem is the List<> does not support notifying changes, so when the data is changed, the control does not know about it and update accordingly. You can use the BindingList<> instead like this:

private BindingList<ParentWidget> _parentList;
private BindingList<ChildWidget> _childList;

That means you have to change the return type of the method GetParentWidgets() to BindingList<ParentWidget>, or you can also use the constructor of a BindingList<> like this:

_parentList = new BindingList<ParentWidget>(GetParentWidgets());
0
votes

What I would do is listening to the valueChanged event of the parent comboBox and when the event fire I would do the databinding on the child combo.

cmbParent.SelectedValueChanged += OnParentSelectedValueChanged;

private void OnParentSelectedValueChanged(object sender, EventArgs e)
{
    this.UpdateChildList(); // Update the data depending on the value in the parent combo

    cmbChild.DisplayMember = "WidgetName"; // I guess you can still do this in the constructor
    cmbChild.ValueMember = "ID"; // I guess you can still do this in the constructor

    cmbChild.DataSource = _childList;   
}