23
Oct
08

WPF: Custom sort dans la DataGrid


Ce billet, http://blogs.msdn.com/jgoldb/archive/2008/08/26/improving-microsoft-datagrid-ctp-sorting-performance.aspx,  nous explique comment obtenir de meilleures performances lors du tri de la WPF DataGrid.

Voici une variante qui vous permettra de trier une datagrid liée à un XmlDataProvider.

   1: public class XmlDataGridComparer<T> : IComparer where T : IComparable
   2: {
   3:     private readonly ListSortDirection m_sortDirection;
   4:     private readonly string m_sortMemberPath;
   5:  
   6:     public XmlDataGridComparer(DataGridColumn column)
   7:     {
   8:         m_sortMemberPath = column.GetSortMemberPath();
   9:         m_sortDirection = column.ToggleSortDirection();
  10:     }
  11:  
  12:     public int Compare(object x, object y)
  13:     {
  14:         XmlElement a = (XmlElement)x;
  15:         XmlElement b = (XmlElement)y;
  16:  
  17:         if (a == null || b == null)
  18:         {
  19:             throw new ArgumentException();
  20:         }
  21:  
  22:         T da = GetObject(a);
  23:         T db = GetObject(b);
  24:  
  25:         if (m_sortDirection == ListSortDirection.Ascending)
  26:         {
  27:             return da.CompareTo(db);
  28:         }
  29:         else
  30:         {
  31:             return db.CompareTo(da);
  32:         }
  33:     }
  34:  
  35:     private T GetObject(XmlElement element)
  36:     {
  37:         string value = element.GetElementsByTagName(m_sortMemberPath).Item(0).InnerXml;
  38:         return (T)Convert.ChangeType(value, typeof(T));
  39:     }
  40: }

 

Ce code utilise deux méthodes d'extension sur les DataGridColumn que voici:

   1: public static class DataGridColumnExtension
   2: {
   3:     /// <summary>
   4:     /// Gets the sort member path.
   5:     /// </summary>
   6:     /// <param name="column">The sorted column.</param>
   7:     /// <returns>The sort member path.</returns>
   8:     public static string GetSortMemberPath(this DataGridColumn column)
   9:     {
  10:         string sortPropertyName = column.SortMemberPath;
  11:         if (string.IsNullOrEmpty(sortPropertyName))
  12:         {
  13:             DataGridBoundColumn boundColumn = column as DataGridBoundColumn;
  14:             if (boundColumn != null)
  15:             {
  16:                 Binding binding = boundColumn.DataFieldBinding as Binding;
  17:                 if (binding != null)
  18:                 {
  19:                     if (!string.IsNullOrEmpty(binding.XPath))
  20:                     {
  21:                         sortPropertyName = binding.XPath;
  22:                     }
  23:                     else if (binding.Path != null)
  24:                     {
  25:                         sortPropertyName = binding.Path.Path;
  26:                     }
  27:                 }
  28:             }
  29:         }
  30:  
  31:         return sortPropertyName;
  32:     }
  33:  
  34:     /// <summary>
  35:     /// Toggles the sort direction.
  36:     /// </summary>
  37:     /// <param name="column">The sorted column.</param>
  38:     /// <returns>
  39:     ///     <see cref="ListSortDirection.Ascending"/> or <see cref="ListSortDirection.Descending"/>
  40:     /// depending of the previous sort direction.
  41:     /// </returns>
  42:     public static ListSortDirection ToggleSortDirection(this DataGridColumn column)
  43:     {
  44:         ListSortDirection sortDirection = ListSortDirection.Ascending;
  45:         ListSortDirection? currentSortDirection = column.SortDirection;
  46:  
  47:         if (currentSortDirection.HasValue && currentSortDirection.Value == ListSortDirection.Ascending)
  48:         {
  49:             sortDirection = ListSortDirection.Descending;
  50:         }
  51:  
  52:         column.SortDirection = sortDirection;
  53:  
  54:         return sortDirection;
  55:     }
  56: }

Il ne reste plus qu'à instancier la class XmlDataGridComparer avec le type d'object contenu dans notre colonne dans l'événement Sorting de la DataGrid :

   1: ListCollectionView lcv = (ListCollectionView)CollectionViewSource.GetDefaultView(dataGrid.ItemsSource);
   2: lcv.CustomSort = new XmlDataGridComparer<string>(e.Column)

Et voilà...



0 Responses to “WPF: Custom sort dans la DataGrid“


    There are no comments yet...Kick things off by filling out the form below.

Leave a Reply