Reputation: 3677
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
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
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