Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. WPF
  4. DataGrid Sort not updating automatically

DataGrid Sort not updating automatically

Scheduled Pinned Locked Moved WPF
questioncsharpcsswpfannouncement
10 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    Bijesh
    wrote on last edited by
    #1

    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

    M P 2 Replies Last reply
    0
    • B 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

      M Offline
      M Offline
      Mark Salsbery
      wrote on last edited by
      #2

      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:

      B 1 Reply Last reply
      0
      • M Mark Salsbery

        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:

        B Offline
        B Offline
        Bijesh
        wrote on last edited by
        #3

        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..

        M 1 Reply Last reply
        0
        • B Bijesh

          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..

          M Offline
          M Offline
          Mark Salsbery
          wrote on last edited by
          #4

          I would ask on the toolkit site and/or post it as an omitted feature. Mark

          Mark Salsbery Microsoft MVP - Visual C++ :java:

          B 1 Reply Last reply
          0
          • M Mark Salsbery

            I would ask on the toolkit site and/or post it as an omitted feature. Mark

            Mark Salsbery Microsoft MVP - Visual C++ :java:

            B Offline
            B Offline
            Bijesh
            wrote on last edited by
            #5

            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

            M 1 Reply Last reply
            0
            • B Bijesh

              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

              M Offline
              M Offline
              Mark Salsbery
              wrote on last edited by
              #6

              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:

              B 1 Reply Last reply
              0
              • M Mark Salsbery

                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:

                B Offline
                B Offline
                Bijesh
                wrote on last edited by
                #7

                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

                1 Reply Last reply
                0
                • B 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

                  P Offline
                  P Offline
                  Pete OHanlon
                  wrote on last edited by
                  #8

                  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 Members

                  public event PropertyChangedEventHandler PropertyChanged;
                  
                  protected virtual void OnChanged(string p)
                  {
                    PropertyChangedEv
                  
                  B 2 Replies Last reply
                  0
                  • P Pete OHanlon

                    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 Members

                    public event PropertyChangedEventHandler PropertyChanged;
                    
                    protected virtual void OnChanged(string p)
                    {
                      PropertyChangedEv
                    
                    B Offline
                    B Offline
                    Bijesh
                    wrote on last edited by
                    #9

                    Hmm that is really odd.. Thanks for posting the code sample. I'll try it out at the earliest.. (unfortunately had to get into some other work for now)

                    1 Reply Last reply
                    0
                    • P Pete OHanlon

                      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 Members

                      public event PropertyChangedEventHandler PropertyChanged;
                      
                      protected virtual void OnChanged(string p)
                      {
                        PropertyChangedEv
                      
                      B Offline
                      B Offline
                      Bijesh
                      wrote on last edited by
                      #10

                      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

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups