Search code examples
c#datagridviewcheckedlistbox

Bind list to DataGridView not displaying anything and wiping out objects every time I click save


I am trying to bind a class list to a DataGridView on my WinForms application. Currently the bind code doesn't do anything. I have debugged through it and the source is correct contains the list with the correct item. But I don't see the rows in the DataGridView.

How do I display whats in the list onto my DataGridView? Also currently every time I click save it clears my class object, however I want to keep the previous values I put in the constructor. If there is already a country that exists I want a user pop up box to state whether they want to over write this or not - is this possible/ how can I best achieve this?

CountryWithDates.cs

 class CountryWithDates
{
    public string country;
    public DateTime firstDate;
    public DateTime furtherDate;
    public DateTime rolldownDate;
    public DateTime endDate;
}

On save click:

  private void Save_Click(object sender, EventArgs e)
    {

        List<CountryWithDates> countryDates = new List<CountryWithDates>();

        for (int i = 0; i < Countries_LB.Items.Count; i++)
        {
            if (Countries_LB.GetItemChecked(i))
            {         
                countryDates.Add(new CountryWithDates(){country = Countries_LB.Items[i].ToString(),
                    firstMarkdownDate = DateTime.Parse(firstDatePicker.Text),
                    furtherMarkdownDate = DateTime.Parse(furtherDatePicker.Text),
                    rolldownMarkdownDate = DateTime.Parse(rolldownDatePicker.Text),
                    endMarkdownDate = DateTime.Parse(endMarkdownPicker.Text)});
            }

        }


//THIS DOESNT DO ANYTHING - I WANT TO BIND THE SOURCE TO THE GRIDVIEW but i dont see the output in the data gridview on the form when i click save
            var bindingList = new BindingList<CountryWithDates>(countryDates);
            var source = new BindingSource(bindingList, null);
            gv_Countries.DataSource = source;

        }

Solution

  • You should create public Porperties in your class and not public Fields:

    class CountryWithDates
    {
        //Following the naming rule is good. I'll leave it to you.
        public string country { get; set; }
        public DateTime firstDate { get; set; }
        public DateTime furtherDate { get; set; }
        public DateTime rolldownDate { get; set; }
        public DateTime endDate { get; set; }
    
        public CountryWithDates() { }
    
        public override string ToString()
        {
            return country;
        }
    }
    

    This way you can bind a list of CountryWithDates objects to the CheckedListBox:

    var lst = new List<CountryWithDates>();
    
    //Add new objects ...
    //lst.Add(new CountryWithDates { country = "Country 1", firstDate ... });
    
    checkedListBox1.DataSource = null;
    checkedListBox1.DataSource = lst;
    

    To get and update the checked items from the list, create a new BindingSource, and bind it to the DataGridView, you just need to do:

    checkedListBox1.CheckedItems
        .Cast<CountryWithDates>()
        .ToList()
        .ForEach(item =>
        {
            item.firstDate = firstDatePicker.Value;
            item.furtherDate = furtherDatePicker.Value;
            item.rolldownDate = rolldownDatePicker.Value;
            item.endDate = endMarkdownPicker.Value;
        });
    dataGridView1.DataSource = null;
    var bs = new BindingSource(checkedListBox1.CheckedItems.Cast<CountryWithDates>(), null);
    dataGridView1.DataSource = bs;