Default Sort is not re-applied when itemsource changes

Dec 17, 2008 at 7:42 AM
Edited Dec 17, 2008 at 1:27 PM
The sorting is set in xaml: 
="{StaticResource strQueueHeaderCreatedOn}" 
                        SortDirection="Ascending" />

The ItemSource is a simple binding to a dependency property ObservableCollection. "OC"

The problem scenario:
1 - Assign an empty OC to the dependency property
2 - Assign an filled OC to the dependeny property

The default sort is not being applied as would be expected. If you skip step 1 and assign a filled OC then the default sorting will be correctly applied. Apparently the sort descriptors are only applied on the first assigned itemsource. (edit: this was wrong, found out later that my first list was sorted by chance. No sort is ever done by setting this property)

My workaround was to assign the empty OC and then manage the list with 'clear' and 'add'. However, that didnt work either. If you assign an empty OC as ItemSource then the sortdescriptors are also not correctly applied.

Given these two problems, i'll dive into the WPFToolkit sorting and make it refresh descriptors on ItemSource changes.

Anyone else having these issues and a non code solution?
Dec 17, 2008 at 9:51 AM
Edited Dec 17, 2008 at 9:53 AM
In DataGrid.cs the following code can be found:


/// <summary>
///     Coercion callback for ItemsSource property
/// </summary>
/// <remarks>
///     SortDescriptions and GroupDescriptions are supposed to be
///     cleared in PropertyChangedCallback or OnItemsSourceChanged
///     virtual. But it seems that the SortDescriptions are applied
///     to the new CollectionView due to new ItemsSource in
///     PropertyChangedCallback of base class (which would execute
///     before PropertyChangedCallback of this class) and before calling
///     OnItemsSourceChanged virtual. Hence handling it in Coercion callback.
/// </remarks>
private static object OnCoerceItemsSourceProperty(DependencyObject d, object baseValue)
      DataGrid dataGrid = (DataGrid)d;
      if (baseValue != dataGrid._cachedItemsSource && dataGrid._cachedItemsSource != null)
      return baseValue;

Removing this code, fixes the issue of the sort not being re-applied. I understand the reason behind the need to remove sort descriptore when the ItemSource points to a different datatype where they would not work. But i would consider that a special case instead of removing this default sorting behavior. Perhaps make a property on datagrid that 'RemoveSortDescriptorsOnItemSourceChanged' or similar. Then modify the above code to lookup the desired behavior instead of the current implementation.

My datagrids are always showing the same data, but in master detail views switching of item sources is a must.

Im still looking into the first problem, where the column default sort descriptors are not applied
Dec 17, 2008 at 1:25 PM
Apparently doing SortDirection="Ascending" on the DataGridTextColumn has no effect except styling. This is as far as i can see not implemented yet. Please proof me wrong, but i have now fixed it by using a CollectionViewSource and putting the sort description there.

         <scm:SortDescription PropertyName="CreatedOn" Direction="Ascending" />

This will do the actual sorting, and the SortDirection="Ascending" on the DataGridTextColumn will apply the correct style to indicate the sort state of the column to the user.

Preferred way of doing this would be to have the datagrid apply the SortDirection, the first time the ItemSource is changed. Implementation could take place in the OnCoerceItemsSourceProperty when the 'dataGrid._cachedItemsSource' is null.

I have it 'working' but i would really like to see more support in the base code for sorting.

Thanks for reading my ramblings,
  Jan Izaak Oosthoek.