Xaphann
Xaphann

Reputation: 3677

WPF ObservableCollection not updating DataGrid when creating a new ObservableCollection

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?

Upvotes: 4

Views: 5847

Answers (2)

Celso L&#237;vero
Celso L&#237;vero

Reputation: 726

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"); }
    }

}

Upvotes: 4

Pedro Silva
Pedro Silva

Reputation: 717

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.

Upvotes: 3

Related Questions