How to refresh DataSource of a ListBox

C#.NetWinforms

C# Problem Overview


Form has one Combobox and one ListBox. When the "Add" button is clicked, I want to add the selected item from the ComboBox to the ListBox.

public partial class MyForm:Form
{
    List<MyData> data = new List<MyData>();
    private void ShowData()
    {
       listBox1.DataSource = data;
       listBox1.DisplayMember = "Name";
       listBox1.ValueMember = "Id";
    }

    private void buttonAddData_Click(object sender, EventArgs e)
    {
       var selection = (MyData)comboBox1.SelectedItem;
       data.Add(selection);
       ShowData();
    }
}

With this example, the selected item is replaced with the new selection inside ListBox. I need to add the item to the list.

What is wrong with my code?

C# Solutions


Solution 1 - C#

listbox1.DataSource property looks for value changes but by assigning the same list all the time the value won't really change.

You can use a BindingList<T>, instead of your List<T>, to automatically recognize new items added. Your ShowData() method must be called once at startup.

public partial class MyForm:Form
{
    public MyForm(){
        InitializeComponent();
        ShowData();
    }

    BindingList<MyData> data = new BindingList<MyData>();

    private void ShowData()
    {
       listBox1.DataSource = data;
       listBox1.DisplayMember = "Name";
       listBox1.ValueMember = "Id";
    }

    private void buttonAddData_Click(object sender, EventArgs e)
    {
       var selection = (MyData)comboBox1.SelectedItem;
       data.Add(selection);
    }
}

Solution 2 - C#

I would suggest to use BindingSource as it would properly update connected controls.

public partial class MyForm : Form
{
    List<MyData> data = new List<MyData>();
    BindingSource bs = new BindingSource();

    public MyForm()
    {
        IntializeComponents();
        bs.DataSource = data;

       listBox1.DisplayMember = "Name";
       listBox1.ValueMember = "Id";
       listBox1.DataSource = bs;
    }

    private void buttonAddData_Click(object sender, EventArgs e)
    {
       var selection = (MyData)comboBox1.SelectedItem;
       data.Add(selection);
       
       bs.ResetBindings(false);
    }
}

Changing controls data source on fly produces strange result sometime.

Solution 3 - C#

The listbox didn't detect that you have changed the DataSource. It will only refresh when Datasource has changed, so set DataSource to null first:

listBox1.DataSource = null;
listBox1.DataSource = data;

You could also clear the items then set the DataSource again:

listBox1.Items.Clear();
listBox1.DataSource = data;

Solution 4 - C#

Alternatively and probably the most correct way to implement this is to use the provided ObservableCollection<T>. It is designed with the sole purpose of implementing INotifyCollectionChanged.

public partial class MyForm : Form
{
    ObservableCollection<MyData> data = new ObservableCollection<MyData>();

    public MyForm()
    {
        listBox1.DataSource = data;
        listBox1.DisplayMember = "Name";
        listBox1.ValueMember = "Id";
    }

    private void buttonAddData_Click(object sender, EventArgs e)
    {
       var selection = (MyData)comboBox1.SelectedItem;
       data.Add(selection);
    }
}

Because ObservableCollection<T> implements INotifyCollectionChanged the DataSource binding will automatically update the ListBox whenever your data changes.

Solution 5 - C#

Call ShowData() when the form initializes to populate your listbox on initialization

 public Department()
        {
            InitializeComponent();
            ShowData();
        }

ShowData() Method, where BindingSource, DisplayMember and ValueMember are set

private void ShowData()
            {
                using (var uow = new UnitOfWork(new SellContext()))
                {
                    listBox1.DataSource = uow.Departments.GetAll().ToList();
                    listBox1.DisplayMember = "DepartmentName";
                    listBox1.ValueMember = "DepartmentId"; 
                    //listBox1.Invalidate();       
                }
            }

In the implementation below when a department is deleted from database the listbox refreshes with the current collection

private void button1_Click(object sender, EventArgs e)
    {
        try {
            using (var uow = new UnitOfWork(new SellContext()))
            {
                int count = uow.Departments.FindDepartmentByName(txtDeptName.Text.ToString());
                if (count>0)
                {
                    MessageBox.Show("This Department Already Exists", "SellRight", MessageBoxButtons.OK, MessageBoxIcon.Hand);
                }

                else
                {
                    department dept = new department();
                    dept.DepartmentName = txtDeptName.Text.ToString();
                    uow.Departments.Create(dept);
                    if (uow.Complete() > 0)
                    {           
                        MessageBox.Show("New Department Created", "SellRight", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        txtDeptName.Text = "";
                        ShowData();      
                    }
                    else
                    {
                        MessageBox.Show("Unable to add Department", "SellRight", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        txtDeptName.Text = "";
                        ShowData();
                    }
                }
            }                              
        }
        catch(Exception ex)
        {
            ex.ToString();
        }
    }

Solution 6 - C#

Maybe this solution has not the better performance, but after many tries and a few hours it was what it worked for me:

This line was executed on the form constructor:

listBox1.DataSource = myData;

This lines were executed after the information was modified:
listBox1.DataSource = new List<Movil>();
listBox1.DataSource = myData;

Hope it helps!

Solution 7 - C#

refreshing also works via

listbox.ItemsSource = null;
listbox.ItemsSource = data;

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionpanjoView Question on Stackoverflow
Solution 1 - C#dwonischView Answer on Stackoverflow
Solution 2 - C#gzaxxView Answer on Stackoverflow
Solution 3 - C#rajeemcariazoView Answer on Stackoverflow
Solution 4 - C#jduncanatorView Answer on Stackoverflow
Solution 5 - C#Frank OdoomView Answer on Stackoverflow
Solution 6 - C#TheKingArthasView Answer on Stackoverflow
Solution 7 - C#Pixel_95View Answer on Stackoverflow