Search code examples
c#wpflistboxitemsource

Changing Itemsources Object doesnt change Listbox (C# WPF)


I hope my title isnt too misleading, but heres a quick explanation. As mentioned in the title im using WPF and I set the Itemsources of a Listbox to an ObservableCollection. I also made a DataTemplate for it to show the values correctly. However my problem is that when im changing the values in the ObservableCollection it doesnt show in the listbox. The question is now, what am I doing wrong?

Heres the code:

public ObservableCollection<Employee> employees;
employees = DatabaseControl.GetEmployees();
Employee_ComboBox.ItemsSource = employees;

Then im switching out the whole Collection:

private void save_Employee_Click(object sender, RoutedEventArgs e)
    {
        deactivateEmployee();
        if (isnewEmployee)
        {
            DatabaseControl.AddEmployee(employee_firstName.Text, employee_lastName.Text, employee_phoneNumber.Text, employee_city.Text, employee_address.Text);
            isnewEmployee = false;
        }
        if (updateEmployee)
        {
            DatabaseControl.UpdateEmployee(((Employee)Employee_ComboBox.SelectedItem).ID, employee_firstName.Text, employee_lastName.Text, employee_phoneNumber.Text, employee_city.Text, employee_address.Text);
            updateEmployee = false;
        }
        employees = DatabaseControl.GetEmployees();
        Employee_ComboBox.ItemsSource = employees;
    }

But this doesnt seem to work out as it should. So what am I doing wrong here? GetEmpoyees() returns an ObservableCollection btw.


Solution

  • The point of the ObservableCollection<Employee> is that when you bind to it then the UI will react when you add/remove items from it, but right now you are adding items to another instance. If you don't want to change your design too much then I would suggest having the DatabaseControl.GetEmployees() return an IList and put the result into the employees ObservableCollection

    A simple approach that works well for not too many employees, but may perform poorly if you have many thousands of employees is to clear and add all

    IList<Employee> result = DatabaseControl.GetEmployees();
    employees.Clear();
    foreach (Employee employee in result)
    {
        employees.Add(employee);
    }
    

    A more clean design IMHO would be to instead create an Employee instance outside of your DatabaseControl and then both send that to the DatabaseControl and add it to the employees collection.

    Also - you may want to consider using a ViewModel with an ICommand Save and a property ObservableCollection<Employee> {get; private set;} and binding to those from your view.