DataGrid Sort not updating automatically
-
Hi, We are doing some grid evaluations for a project. I am trying out the DataGrid from Microsoft (the WPF Toolkit). We have it bound to an IOBservableCollection, and are simulating lots of updates to the data. The grid refresshes fine in most case. But if I have the grid sorted ona column, and I change the value of the column in the data, the grid data udpates but it does not re-apply the sort. It just shows the column as sorted but the values. I think this is because a property change on an individual item does not fire a collection changed event in the ObservableCollection. If I fire a collectionChanged event manually the grid does update. I can also make it sort by replacing the object itself. But both these appraches are very CPU expensive. So what is teh recommended way to reapply the sort on the grid on a data update? thanks and regards, Bijesh
-
Hi, We are doing some grid evaluations for a project. I am trying out the DataGrid from Microsoft (the WPF Toolkit). We have it bound to an IOBservableCollection, and are simulating lots of updates to the data. The grid refresshes fine in most case. But if I have the grid sorted ona column, and I change the value of the column in the data, the grid data udpates but it does not re-apply the sort. It just shows the column as sorted but the values. I think this is because a property change on an individual item does not fire a collection changed event in the ObservableCollection. If I fire a collectionChanged event manually the grid does update. I can also make it sort by replacing the object itself. But both these appraches are very CPU expensive. So what is teh recommended way to reapply the sort on the grid on a data update? thanks and regards, Bijesh
Bijesh wrote:
I think this is because a property change on an individual item does not fire a collection changed event in the ObservableCollection.
Right - only changes to the collection, not changes to items in the collection. For change notifications on items, you can implement INotifyPropertyChanged[^] on the item class(es).
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
Bijesh wrote:
I think this is because a property change on an individual item does not fire a collection changed event in the ObservableCollection.
Right - only changes to the collection, not changes to items in the collection. For change notifications on items, you can implement INotifyPropertyChanged[^] on the item class(es).
Mark Salsbery Microsoft MVP - Visual C++ :java:
Hi Mark, Thanks for the response. WE have implemented the INotifyPropertyCHanged on the item class. But unfortunately the grid does not look like it is updating the sorting on the event. I guess ideally it should handle the PropertyChanged event and check whether the changed column is being sorted on and then update the sorting, but it isn't. I also tested this on the DAtaGrid sample from here: http://blogs.msdn.com/vinsibal/archive/2008/10/22/wpf-datagrid-and-the-wpftoolkit-have-released.aspx[^] ..and got the same result. If I manually edit onthe grid it re-sorts because it fires a CollectionChanged event there I Think. But if I directly edit thte data in code it updates the value on the grid but does to update the sorting..
-
Hi Mark, Thanks for the response. WE have implemented the INotifyPropertyCHanged on the item class. But unfortunately the grid does not look like it is updating the sorting on the event. I guess ideally it should handle the PropertyChanged event and check whether the changed column is being sorted on and then update the sorting, but it isn't. I also tested this on the DAtaGrid sample from here: http://blogs.msdn.com/vinsibal/archive/2008/10/22/wpf-datagrid-and-the-wpftoolkit-have-released.aspx[^] ..and got the same result. If I manually edit onthe grid it re-sorts because it fires a CollectionChanged event there I Think. But if I directly edit thte data in code it updates the value on the grid but does to update the sorting..
I would ask on the toolkit site and/or post it as an omitted feature. Mark
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
I would ask on the toolkit site and/or post it as an omitted feature. Mark
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
Thanks I will do that. If you have any opinion on what is the best way to refresh a grid, or refresh a collection please let me know, thanks.. Bijesh
The control should really do that itself. Off the top of my head, things to try: 1) DataGrid.InvalidateProperty() 2) detach and re-attach the collection ( X| ) The control's not officially released so it would be nice to catch stuff like this before it goes into the .NET framework :)
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
The control should really do that itself. Off the top of my head, things to try: 1) DataGrid.InvalidateProperty() 2) detach and re-attach the collection ( X| ) The control's not officially released so it would be nice to catch stuff like this before it goes into the .NET framework :)
Mark Salsbery Microsoft MVP - Visual C++ :java:
From what I've tried so far, gettng the efault view of the collection is what work, but the performance is not great. detaching and attaching, seems very wrong, but I might go for it, as it has the advantage that I can effectively suspend the grid, do a batch of updates to the underlying data and then refresh the grid, rather than have the grid continuously update itself.. Again thanks for the responses... Bijesh
modified on Tuesday, June 23, 2009 8:40 AM
-
Hi, We are doing some grid evaluations for a project. I am trying out the DataGrid from Microsoft (the WPF Toolkit). We have it bound to an IOBservableCollection, and are simulating lots of updates to the data. The grid refresshes fine in most case. But if I have the grid sorted ona column, and I change the value of the column in the data, the grid data udpates but it does not re-apply the sort. It just shows the column as sorted but the values. I think this is because a property change on an individual item does not fire a collection changed event in the ObservableCollection. If I fire a collectionChanged event manually the grid does update. I can also make it sort by replacing the object itself. But both these appraches are very CPU expensive. So what is teh recommended way to reapply the sort on the grid on a data update? thanks and regards, Bijesh
OK - this is odd. I knocked up a quick sample application and sorted on a column - then I started changing the values in the sorted column and it refreshed and changed the sort order in every case. Here's the sample code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Media.Media3D;
using System.ComponentModel;
using System.Collections.ObjectModel;namespace ModelVisualTest
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
private ObservableCollection<Person> _people;
public Window1()
{
InitializeComponent();
}private void BuildModel() { \_people = new ObservableCollection<Person>(); \_people.Add(new Person() { Forename = "Peter", Surname = "O'Hanlon", Age = 30 }); \_people.Add(new Person() { Forename = "Josh", Surname = "Walton", Age = 29 }); \_people.Add(new Person() { Forename = "William", Surname = "Hill", Age = 28 }); \_people.Add(new Person() { Forename = "Joseph", Surname = "Brannagan", Age = 36 }); dataGrid1.ItemsSource = \_people; } private void Window\_Loaded(object sender, RoutedEventArgs e) { BuildModel(); }
}
public class Person : INotifyPropertyChanged
{
private string _forename;
public string Forename
{
get { return _forename; }
set
{
if (_forename != value)
{
_forename = value;
OnChanged("Forename");
}
}
}
private string _surname;
public string Surname
{
get { return _surname; }
set
{
if (_surname != value)
{
_surname = value;
OnChanged("Surname");
}
}
}
private int _age;
public int Age
{
get { return _age; }
set
{
if (_age != value)
{
_age = value;
OnChanged("Age");
}
}
}
#region INotifyPropertyChanged Memberspublic event PropertyChangedEventHandler PropertyChanged; protected virtual void OnChanged(string p) { PropertyChangedEv
-
OK - this is odd. I knocked up a quick sample application and sorted on a column - then I started changing the values in the sorted column and it refreshed and changed the sort order in every case. Here's the sample code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Media.Media3D;
using System.ComponentModel;
using System.Collections.ObjectModel;namespace ModelVisualTest
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
private ObservableCollection<Person> _people;
public Window1()
{
InitializeComponent();
}private void BuildModel() { \_people = new ObservableCollection<Person>(); \_people.Add(new Person() { Forename = "Peter", Surname = "O'Hanlon", Age = 30 }); \_people.Add(new Person() { Forename = "Josh", Surname = "Walton", Age = 29 }); \_people.Add(new Person() { Forename = "William", Surname = "Hill", Age = 28 }); \_people.Add(new Person() { Forename = "Joseph", Surname = "Brannagan", Age = 36 }); dataGrid1.ItemsSource = \_people; } private void Window\_Loaded(object sender, RoutedEventArgs e) { BuildModel(); }
}
public class Person : INotifyPropertyChanged
{
private string _forename;
public string Forename
{
get { return _forename; }
set
{
if (_forename != value)
{
_forename = value;
OnChanged("Forename");
}
}
}
private string _surname;
public string Surname
{
get { return _surname; }
set
{
if (_surname != value)
{
_surname = value;
OnChanged("Surname");
}
}
}
private int _age;
public int Age
{
get { return _age; }
set
{
if (_age != value)
{
_age = value;
OnChanged("Age");
}
}
}
#region INotifyPropertyChanged Memberspublic event PropertyChangedEventHandler PropertyChanged; protected virtual void OnChanged(string p) { PropertyChangedEv
-
OK - this is odd. I knocked up a quick sample application and sorted on a column - then I started changing the values in the sorted column and it refreshed and changed the sort order in every case. Here's the sample code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Media.Media3D;
using System.ComponentModel;
using System.Collections.ObjectModel;namespace ModelVisualTest
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
private ObservableCollection<Person> _people;
public Window1()
{
InitializeComponent();
}private void BuildModel() { \_people = new ObservableCollection<Person>(); \_people.Add(new Person() { Forename = "Peter", Surname = "O'Hanlon", Age = 30 }); \_people.Add(new Person() { Forename = "Josh", Surname = "Walton", Age = 29 }); \_people.Add(new Person() { Forename = "William", Surname = "Hill", Age = 28 }); \_people.Add(new Person() { Forename = "Joseph", Surname = "Brannagan", Age = 36 }); dataGrid1.ItemsSource = \_people; } private void Window\_Loaded(object sender, RoutedEventArgs e) { BuildModel(); }
}
public class Person : INotifyPropertyChanged
{
private string _forename;
public string Forename
{
get { return _forename; }
set
{
if (_forename != value)
{
_forename = value;
OnChanged("Forename");
}
}
}
private string _surname;
public string Surname
{
get { return _surname; }
set
{
if (_surname != value)
{
_surname = value;
OnChanged("Surname");
}
}
}
private int _age;
public int Age
{
get { return _age; }
set
{
if (_age != value)
{
_age = value;
OnChanged("Age");
}
}
}
#region INotifyPropertyChanged Memberspublic event PropertyChangedEventHandler PropertyChanged; protected virtual void OnChanged(string p) { PropertyChangedEv
Hi Pete, Just tried out your sample. If I understood correctly you are manually editing the values? That works fine for me too. BEcause I think a manual edit ends up firing a collectionChanged event and this takes care of resorting the grid. This is probably fine performance-wise too as a manual edit is not doing to happen numerous times a second. My issue is with updates being done on the data programatically to a sorted column, do not seem to readjust the sorting. This seems like a generic requirement and it should do it automatically, or atleast provide an option to have it done automatically. Why would we want to have a grid that appears to be sorted but it actually not? Bijesh