use IComparer for Sorting/Grouping/Filtering

7 posts, 0 answers
  1. Alexander
    Alexander avatar
    78 posts
    Member since:
    Apr 2013

    Posted 02 Jul 2014 Link to this post

    Hi,
    is it somehow possible to specify a custom IComparer (or IComparer<string>) which shall be used for sorting all or selected columns?
    Ideally, it should also be applied to sorting groups and sorting the filter items.
    I would prefer an generic solution where I don't have to apply it to every column (e.g. via some Style that is applied to every column).

    I want that
    - empty values (null, "") are at the end (when sorting Ascending), and
    - use a natural sort order for strings (e.g. "M4" < "M12")

    In the custom sorting example (http://www.telerik.com/help/wpf/gridview-sorting-custom.html)
    - you change the ItemsSource of the grid, which destroys the binding (however, in my case the ItemsSource may change)
    - you have to know the underlying data structure to get the properties
    - you assume that you use a first level property for the DataMemberBinding
    - and it applies only to sorting, but not grouping and filtering.

    Thank you in advance.
    Alex
  2. Alexander
    Alexander avatar
    78 posts
    Member since:
    Apr 2013

    Posted 03 Jul 2014 in reply to Alexander Link to this post

    For the sorting, I found a usable workaround: I create my own SortDescriptor, override the CreateSortKeyExpression
    method and add it manually to the SortDescriptors in the OnSorting event. To enable sorting on combobox columns that have no SortMemberPath, I have to set IsCustomSortingEnabled = true - then the OnSorting event is called.

    However, for the Grouping there seems not to be a similar workaround: Altough it is simple to write a similar custom GroupDescriptor, there is no IsCustomGroupingEnabled property. So, the Grouping event is never called for my ComboBoxColumns - except if I specify a GroupMemberPath pointing to some string...

    Alex
  3. Alexander
    Alexander avatar
    78 posts
    Member since:
    Apr 2013

    Posted 03 Jul 2014 in reply to Alexander Link to this post

    For the grouping, I have found a solution in the mean time. I created a user defined column type for the combobox column, where I override the CanGroup method to return true. Now I can use my custom GroupDescriptor in the Grouping event.

    However, I'm still struggling with the filtering. I have several problems:

    When I use the CreateSortKeyExpression or the CreateGroupKeyExpression, I simply convert the bound member of the column to some sortable type (some wrapped string to allow for natural sorting). But in the CreateFilterExpression, the complete filter code is generated. If I convert my member values to SortString, the comparison obviously fails, as the distinct values are no SortStrings. How can I convert the distinct values to SortStrings?

    Additionally, the filtering control always shows only IsEqual and IsNotEqual as FilterOperators. How can I allow additional operators (which should be usable for string operations...)?
  4. Alexander
    Alexander avatar
    78 posts
    Member since:
    Apr 2013

    Posted 03 Jul 2014 in reply to Alexander Link to this post

    Ok, found a solution:
    in the custom ComboBoxColumn, I override FilteringDisplayFunc to generate an SortString for all elements.

    Alex
  5. Dimitrina
    Admin
    Dimitrina avatar
    3769 posts

    Posted 04 Jul 2014 Link to this post

    Hello Alex,

    You can check some sample code on our Custom Sorting with IComparable WPF Demo. It demonstrates using the IComparable interface.
    Using a Generic Sort Descriptor is also an option.

    As to your question on the available filtering operators, may I ask you what the DataType of the bound property it?
    The list of filter operations depends on the DataType property of the column. For example, the filter operations "StartsWith", "EndsWith, "IsEmpty, "IsNotEmpty... " will not be available for columns of Integer or DateTime types. You can also refer to the Basic Filtering article where all the information on how the filtering works is explained in details.

    Regards,
    Didie
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     
  6. Alexander
    Alexander avatar
    78 posts
    Member since:
    Apr 2013

    Posted 09 Jul 2014 in reply to Dimitrina Link to this post

    Thanks for the answer.

    The demo did not help me, as it only specifies the default sorting for the whole object, but not by column - I would have prefered some "IComparer" (not IComparable) for the member. For the generic sort descriptor, I would have to know the details of the item type and have to manually generate the sort desscriptors.

    Instead, I created my own SortDescriptor and overrided the CreateSortKeyExpression:

    class CustomColumnSortDescriptor : ColumnSortDescriptor
    {
        protected override Expression CreateSortKeyExpression(ParameterExpression parameterExpression)
        {
            var expression = base.CreateSortKeyExpression(parameterExpression);
            expression = SortKeyHelper.CreateSortStringExpression(expression);
            return expression;
        }
    }

    and added it manually in the Sorting event to the SortDescriptors of the grid. There was only a small problem that even if I said
    e.Cancel = true;
    in the sorting event, the GridView tried to replace my SortDescriptor with a default one. However, luckily you provide a CollectionChanging event for the SortDescriptors, which I could cancel so my custom sort descriptor stays in the collection. However - this is only a workaround - is there any way to stop the GridView from generating it's own sort descriptors?

    Regarding the data type: I am using all kinds of data, from strings to numbers to objects (e.g. in ComboBoxColumns). My problem was that I was using the GroupMemberPath for strings, too, converting them to a SortString - which was not really necessary. So for the string columns, I now see the advanced filter options. For the other columns, however, the filter operators are somewhat useless (if I want to exclude or include some specific value, I can use the discrete values...) - I would like to hide these fields completely for these columns...

    Alex
  7. Dimitrina
    Admin
    Dimitrina avatar
    3769 posts

    Posted 10 Jul 2014 Link to this post

    Hello Alex,

    I tested adding the custom SortDescriptor like so:
    private void clubsGrid_Sorting(object sender, GridViewSortingEventArgs e)
    {
        e.Cancel = true;
        clubsGrid.SortDescriptors.Add(new CustomColumnSortDescriptor());
    }

    Then, I checked the descriptors in the clubsGrid.SortDescriptors collection and the added one was there (without any default SortDescriptors added). If you do something differently, may I ask you to open a new support ticket and attach there a sample project which we can check locally?

    As to your second question, you can subscribe for the FilterOperatorsLoading event of RadGridView which allows you to remove the available filter operators. Please refer to this help article for a reference.

    Regards,
    Didie
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     
Back to Top