walterhuang
walterhuang

Reputation: 632

How to bind a list count to a label

I have a DataGridView binding to a list and a label showing number of records. I run into the same problem Khash had. (so I steal his title). Any add or delete operations on the grid won't update the label.

enter image description here

Based on Sung's answer, a facade wrapper, I create my custom list inheriting BindingList and implementing INotifyPropertyChanged.

public class CountList<T> : BindingList<T>, INotifyPropertyChanged
{    
    protected override void InsertItem(int index, T item)
    {
        base.InsertItem(index, item);
        OnPropertyChanged("Count");
    }

    protected override void RemoveItem(int index)
    {
        base.RemoveItem(index);
        OnPropertyChanged("Count");
    }

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

However, this will throw an exception when binding.

Cannot bind to the property or column Count on the DataSource. Parameter name: dataMember

Below is my binding code:

private CountList<Person> _list;

private void Form1_Load(object sender, EventArgs e)
{
    _list = new CountList<Person>();
    var binding = new Binding("Text", _list, "Count");
    binding.Format += (sender2, e2) => e2.Value = string.Format("{0} items", e2.Value);
    label1.DataBindings.Add(binding);
    dataGridView1.DataSource = _list;
}

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Any suggestions will be appreciated. Thank you.

Upvotes: 2

Views: 4612

Answers (1)

In fact, it is much simpler than you think!

Microsoft already has created the BindingSource control, so, you need to use it and then handle the BindingSource event to update the label:

    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    private BindingSource source = new BindingSource();

    private void Form1_Load(object sender, EventArgs e)
    {
        var items = new List<Person>();
        items.Add(new Person() { Id = 1, Name = "Gabriel" });
        items.Add(new Person() { Id = 2, Name = "John" });
        items.Add(new Person() { Id = 3, Name = "Mike" });
        source.DataSource = items;
        gridControl.DataSource = source;
        source.ListChanged += source_ListChanged;

    }

    void source_ListChanged(object sender, ListChangedEventArgs e)
    {
        label1.Text = String.Format("{0} items", source.List.Count);
    }

Upvotes: 5

Related Questions