Solution: Natural Sort on column

2 posts, 0 answers
  1. TonyG
    TonyG avatar
    239 posts
    Member since:
    Feb 2006

    Posted 23 Apr 2012 Link to this post

    A few threads have been posted over the years to ask about natural sorting, which is clicking a column header to go Ascending, Descending, then back to the default unsorted mode on the third click. I looked around for a tri-state or three-state toggle and didn't find any info.  Very helpful but incomplete info is found here and here, so I thought I'd provide C# code to help anyone else looking to do this. Some threads refer to MasterGridViewTemplate.AllowNaturalSort but that property no longer exists. My code is adapted from the second forum posting referenced. It looks like the library has changed since Sean wrote his code.

    Telerik.WinControls.Data.SortDescriptor.Direction is of type System.ComponentModel.ListDirection, and that enum only has two values. So the Boolean _sorted is used - if the grid is sorted in ascending or descending order, then use the sort order, but  if we click past descending order, set _sorted to false (natural sort!) and clear the SortDescriptors.

    Of course clearing SortDescriptors means this only works with single column sorting. Maybe someone will follow-up here with a solution that works with multiple columns.

    HTH

    using System.ComponentModel;
    bool _sorted = false;
    ListSortDirection _previousGridColumnSortDirection;
    private void radGridView1_SortChanging(object sender, GridViewCollectionChangingEventArgs e)
    {
        try
        {
            Telerik.WinControls.Data.SortDescriptor sortField;
            // Only proceed if we are changing an existing sorting (not starting a new one) 
      
            // Make sure we have an item
            if (e.NewItems != null && e.NewItems.Count > 0)
            {
                sortField = (Telerik.WinControls.Data.SortDescriptor)e.NewItems[0];
                if (e.Action == Telerik.WinControls.Data.NotifyCollectionChangedAction.ItemChanging)
                {
                    // If the current SortOrder is Ascending, and the previous SortOrder
                    // was Descending, then clear the sorting.
                    if (_sorted)
                    {
                        if (sortField.Direction == ListSortDirection.Ascending &&
                            _previousGridColumnSortDirection == ListSortDirection.Descending)
                        {
                            _sorted = false;
                            radGridView1.MasterGridViewTemplate.SortDescriptors.Clear();
                        }
                        //Save the SortOrder for the next iteration
                        _previousGridColumnSortDirection = sortField.Direction;
                    }
                    else
                    {
                        _sorted = true;
                        _previousGridColumnSortDirection = sortField.Direction;
                    }
                }
                if (e.Action == Telerik.WinControls.Data.NotifyCollectionChangedAction.Add)
                {
                    _sorted = true;
                    _previousGridColumnSortDirection = sortField.Direction;
                }
            }
      
        }
        catch
        {
        }
    }
  2. Julian Benkov
    Admin
    Julian Benkov avatar
    1135 posts

    Posted 26 Apr 2012 Link to this post

    Hello Tony,

    Thank you for writing.

    We have added your suggestion to our system as a feature request. If we have a number of customers requiring this feature, we will increase its priority it in our TO DO list and we will do our best to implement it for one of the next major releases. Please follow this link, where you can add your vote for it and also subscribe to its status updates.

    Currently, you can use this implementation to support the desired behavior:
    this.radGridView1.GridBehavior = new CustomGridBehavior();
     
    class CustomGridBehavior : BaseGridBehavior
    {
        Point downPoint;
     
        protected override bool OnMouseDownLeft(MouseEventArgs e)
        {
            downPoint = e.Location;
            return base.OnMouseDownLeft(e);
        }
     
        public override bool OnMouseUp(MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                RadElement element = GridControl.ElementTree.GetElementAtPoint(e.Location);
                GridHeaderCellElement cell = element as GridHeaderCellElement;
                if (cell == null && element != null)
                {
                    cell = element.FindAncestor<GridHeaderCellElement>();
                }
                if (cell != null && e.Location.X > cell.ControlBoundingRectangle.X + 3 && e.Location.X < cell.ControlBoundingRectangle.Right - 3)
                {
                    if (cell.ColumnInfo.SortOrder == RadSortOrder.Ascending)
                    {
                        cell.ColumnInfo.SortOrder = RadSortOrder.Descending;
                    }
                    else if (cell.ColumnInfo.SortOrder == RadSortOrder.Descending)
                    {
                        cell.ColumnInfo.SortOrder = RadSortOrder.None;
                    }
                    else
                    {
                        cell.ColumnInfo.SortOrder = RadSortOrder.Ascending;
                    }
                    return true;
                }
     
            }
            return base.OnMouseUp(e);
        }
    }

     I hope this helps.

    Thank you for your time and cooperation. Your Telerik points have been updated.

    Kind regards,

    Julian Benkov
    the Telerik team
    RadControls for WinForms Q1'12 release is now live! Check out what's new or download a free trial >>
Back to Top