This is a migrated thread and some comments may be shown as answers.

Solution: Natural Sort on column

1 Answer 140 Views
GridView
This is a migrated thread and some comments may be shown as answers.
TonyG
Top achievements
Rank 1
TonyG asked on 24 Apr 2012, 02:07 AM

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
    {
    }
}

1 Answer, 1 is accepted

Sort by
0
Julian Benkov
Telerik team
answered on 26 Apr 2012, 03:06 PM
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 >>
Tags
GridView
Asked by
TonyG
Top achievements
Rank 1
Answers by
Julian Benkov
Telerik team
Share this question
or