2
votes

I've seen a bunch of posts regarding databinding to databases but none of them have helped with databinding to an existing object in memory. I've also looked at several stack overflow posts where people have said the following code should've bound the properties on my combo box:

        projectData = new ProjectData();

        this.parentTypeComboBox.DataSource = projectData.MobList;
        this.parentTypeComboBox.DisplayMember = "MobType";
        this.parentTypeComboBox.ValueMember = "MobType";

My data object has public getters/setters for it's various properties and I've added the INotifyPropertyChanged interface on the classes but do not attach any listeners to the event as of now. From what I've read this should've been all I had to do to get the control to bind to my data object. Any idea why I'm not seeing my combo box get populated with data when my object list changes?

Project data class:

public class ProjectData : INotifyPropertyChanged
{
    public static string PROJECT_OUTPUT_DIRECTORY = "..\\";
    private List<Mob> _mobList;

    public List<Mob> MobList
    {
        get { return _mobList; }
        set { _mobList = value; OnPropertyChanged("MobList"); }
    }

    public ProjectData()
    {
        MobList = new List<Mob>();
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }      
}

Mob Class:

//Snippet mob of class
public partial class Mob : IEquatable<Mob>, INotifyPropertyChanged
{
    public Mob()
    {
        dataAttributeField = new List<MobDataAttribute>();
    }

    private List<MobDataAttribute> dataAttributeField;

    private string mobTypeField;

    private string parentTypeField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("DataAttribute")]
    public List<MobDataAttribute> DataAttribute
    {
        get
        {
            return this.dataAttributeField;
        }
        set
        {
            this.dataAttributeField = value;
            OnPropertyChanged("DataAttribute");
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string MobType
    {
        get
        {
            return this.mobTypeField;
        }
        set
        {
            this.mobTypeField = value;
            OnPropertyChanged("MobType");
        }
    }
}
1
EDIT/UPDATE I ended up using a BindingList for my list which actually does allow the control to automatically update when something is added to the list. I still set the datasource/memeber/value but now my control is being updated automatically.SonicD007
^ By attaching a method to the ListChanged event: void MobList_ListChanged(object sender, ListChangedEventArgs e) { this.parentTypeComboBox.DataSource = projectData.MobList; this.parentTypeComboBox.DisplayMember = "MobType"; this.parentTypeComboBox.ValueMember = "MobType"; }SonicD007

1 Answers

1
votes

Using this projectData = new ProjectData(); the MobList is an empty list yet.

If you didn't populate data, you should populate your data to list to show it in ComboBox.

Remember that every time you populate data, you should update DataSource property of your ComboBox:

this.comboBox1.DataSource = parent.Childs;

If you are bound to a data source that does not implement the IBindingList interface, such as an ArrayList, the bound control's data will not be updated when the data source is updated. For example, if you have a combo box bound to an ArrayList and data is added to the ArrayList, these new items will not appear in the combo box.

Here is a sample:

public partial class SampleForm : Form
{
    public SampleForm()
    {
        InitializeComponent();
    }

    private void SampleForm_Load(object sender, EventArgs e)
    {
        //Initialize parent and populate its Childs
        var parent = new Parent()
        {
            ParentName = "Parent 1",
            Childs = new List<Child>{
                new Child(){ChildName= "Child1"},
                new Child(){ChildName= "Child2"}
            }
        };

        this.comboBox1.DataSource = parent.Childs;
        this.comboBox1.DisplayMember = "ChildName";
        this.comboBox1.ValueMember = "ChildName";

    }

}

public class Parent
{
    public Parent()
    {
        Childs = new List<Child>();
    }
    public string ParentName { get; set; }
    public List<Child> Childs { get; set; }
}

public class Child
{
    public string ChildName { get; set; }
}

Screenshot:

enter image description here