Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF ObservableCollection not updating DataGrid when creating a new ObservableCollection

Tags:

c#

mvvm

wpf

I have a DataGrid that is bound to an ObservableCollection in the ViewModel. This is a search results DataGrid. The problem is that after I update the search results ObservableCollection the actual DataGrid is not updated.

Before I get down voted to nothing, please note this is NOT about data in the columns (that bind works perfectly) it is about clearing and then placing completely new data into ObservableCollection that is not updating the DataGrid. So linking to something like this will not help as my properties are working correctly

Background:

The ObservableCollection is declared in the ViewModel like this;

public ObservableCollection<MyData> SearchCollection { get; set; }

The search DataGrid that is bound to my search ObservableCollection like this;

<DataGrid  ItemsSource="{Binding SearchCollection}" />

In the ViewModel I have a search method like this;

var results =
      from x in MainCollection
      where x.ID.Contains(SearchValue)
      select x;
 SearchCollection = new ObservableCollection<MyData>(results);

The method fires correctly and produces the desired results. Yet the DataGrid is not updated with the new results. I know the ViewModel has the correct data because if I put a button on the Page and in the click event put this code;

private void selectPromoButton_Click(object sender, System.Windows.RoutedEventArgs e)
{
    var vm = (MyViewModel)DataContext;
    MyDataGrid.ItemsSource = vm.SearchCollection;
}

The DataGrid now correctly shows the results.

I know I could put some event in the code behind of the Page but wouldn't that defeat MVVM? What is the correct MVVM way to handle this?

like image 247
Xaphann Avatar asked Oct 18 '25 22:10

Xaphann


2 Answers

Try to implement INotifyPropertyChanged in your modelview

example:

public abstract class ViewModelBase : INotifyPropertyChanged {

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
    }

    protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)
    {
        var handler = PropertyChanged;
        handler?.Invoke(this, args);
    }
}

public class YourViewModel : ViewModelBase {

    private ObservableCollection<MyData> _searchCollection ;

    public ObservableCollection<MyData> SearchCollection 
    {
        get { return _searchCollection; }
        set { _searchCollection = value; OnPropertyChanged("SearchCollection"); }
    }

}
like image 180
Celso Lívero Avatar answered Oct 20 '25 12:10

Celso Lívero


The problem is that your are resetting your SearchCollection property rather than updating the collection. Observable collection raises the correct change events when items in the list are added, deleted, or updated. But not when the collection property itself is changed.

In your SearchCollection setter, you can fire a PropertyChanged event. Just like any other property when it changes. Also make sure your DataGrid ItemsSource binding is one-way not one-time.

<DataGrid  ItemsSource="{Binding SearchCollection, Mode=OneWay}" />

Or you can change the members of the collection (clearing the old results and adding new ones). That should also update the DataGrid as you expect.

From your code sample, I would go with the first option.

like image 22
Pedro Silva Avatar answered Oct 20 '25 12:10

Pedro Silva



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!