How to sort column in descending order first?

Hi,

I have a sfDataGrid in Xamarin Forms and populating it through data templates dynamically binding to a dictionary (sample project attached).

The current behavior I see when I click on the columns is going through sorting states starting with ascending order as described in the documentation:

SfDataGrid.AllowTriStateSorting property to true. When this property is set, sorting in each column iterates through three sort states: ascending, descending, and unsort.

The behavior I need is that the first state for column sorting is descending. 

I tried to do programmatic sorting like this: https://help.syncfusion.com/xamarin/datagrid/sorting?cs-save-lang=1&cs-lang=csharp#programmatic-sorting

dataGrid.AllowSorting = true;

dataGrid.SortColumnDescriptions.Add (new SortColumnDescription () {
    ColumnName = "OrderID",
    SortDirection = ListSortDirection.Descending
});
But I get this error:

"Sorted column does not exist in column collection"

Any ideas on how to accomplish this use case?

Thanks!

Attachment: DataGridDemo_17a4dfa4.zip

9 Replies 1 reply marked as answer

KK Karthikraja Kalaimani Syncfusion Team May 20, 2021 05:22 AM UTC

Hi Adolfo,

We have checked the reported issue "Sorted Column does not exist in Column Collection" in the attached sample. We discovered that bound dynamic collection to the ItemSource property of the SfDataGrid. So, you have to mention the column name like the below code snippet. 

Code snippet : 
   dataGrid.AllowTriStateSorting = true;
            dataGrid.SortColumnDescriptions.Add(new SortColumnDescription()
            {
                ColumnName = $"Values[{ "OrderID" }]",
                SortDirection = Syncfusion.Data.ListSortDirection.Descending
            });  

Regards,
Karthik Raja


AD Adolfo May 20, 2021 03:04 PM UTC

Hi Karthik,

I realized that my ColumnName binding was incorrect as you pointed out having to set it to my Value[Key].
However, this is still not doing what I need.

I want initial sorting to be unaffected. My requirement is as follows:

1. Grid loads with default data sorting
2. Upon clicking on a column header do a descending sort first (state) instead of having to toggle through asc, desc, unsorted states. 

I just need to flip the order from asc -> desc to desc-> asc

Is that possible?


KK Karthikraja Kalaimani Syncfusion Team May 21, 2021 01:49 PM UTC

Hi Adolfo,

Currently, we are validating your requirement. We will update the details on or before 25th May 2021. We appreciate your patience until then.

Regards,
Karthik Raja



KK Karthikraja Kalaimani Syncfusion Team May 25, 2021 01:49 PM UTC

Hi Adolfo, 

Thanks for your patience. 

Your requirement can be achieved by writing custom comparer for the Underlying property. For more details please refer to the below code snippet and UG document. 

Code snippet : 
   dataGrid.SortColumnDescriptions.Add(new SortColumnDescription()
            {
                ColumnName = $"Values[{ "OrderID" }]",
            });
            dataGrid.SortComparers.Add(new SortComparer()
            {
                PropertyName = $"Values[{ "OrderID" }]",
                Comparer = new CustomComparer()
            });
...

    public class CustomComparer : IComparer<Object>, ISortDirection
    {
        public int Compare(object x, object y)
        {
          return SortDirection == Syncfusion.Data.ListSortDirection.Ascending ? 1 : 0;
        }

        //Gets or sets the SortDirection value
        public Syncfusion.Data.ListSortDirection SortDirection { get; set; }
    }

UG link : https://help.syncfusion.com/xamarin/datagrid/sorting?cs-save-lang=1&cs-lang=csharp

Regards,
Karthik Raja



AD Adolfo May 25, 2021 02:11 PM UTC

Thanks Karthik,

I tried your solution but I have to click the column twice to sort in descending order.
Here is what I see:

1. Click on column header: Upon clicking I see a sort arrow pointing up (ascending order) but list is not sorted
2. I click again on column header and now list is sorted in descending order as expected

Is there a way to directly sort in descending order upon first click?


KK Karthikraja Kalaimani Syncfusion Team May 26, 2021 05:43 AM UTC

Hi Adolfo, 

We have achieved your requirement by using the GridTapped event. Please refer to the below Code snippet for more details. 

Code snippet : 
 customComparer = new CustomComparer(Syncfusion.Data.ListSortDirection.Ascending);
            dataGrid.SortComparers.Add(new SortComparer()
            {
                PropertyName = $"Values[{ "OrderID" }]",
                Comparer = customComparer
            });
            dataGrid.GridTapped += DataGrid_GridTapped;
..
 private void DataGrid_GridTapped(object sender, GridTappedEventArgs e)
        {
            if (e.RowColumnIndex.ColumnIndex == 0 && e.RowColumnIndex.RowIndex == 0)
            {
                if (customComparer.SortDirection == Syncfusion.Data.ListSortDirection.Ascending)
                {
                    customComparer.SortDirection = Syncfusion.Data.ListSortDirection.Descending;
                }
                else
                {
                    customComparer.SortDirection = Syncfusion.Data.ListSortDirection.Ascending;
                }
            }
        }
....
  public class CustomComparer : IComparer<Object>, ISortDirection
    {
        public CustomComparer(Syncfusion.Data.ListSortDirection listSortDirection)
        {
            SortDirection = listSortDirection;
        }
        public int Compare(object x, object y)
        {
            var valueOfX = (((DynamicModel)x).Values["OrderID"]).ToString();
            var valueOfY = (((DynamicModel)y).Values["OrderID"]).ToString();
            int xvalue = Int16.Parse(valueOfX);
            int yvalue = Int16.Parse(valueOfY);
            if (SortDirection == Syncfusion.Data.ListSortDirection.Ascending)
            {
                if (xvalue > yvalue)
                {
                    return 0;
                }
                else if (yvalue > xvalue)
                {
                    return -1;
                }
                else
                {
                    return 1;
                }
            }
            else if (SortDirection == Syncfusion.Data.ListSortDirection.Descending)
            {
                if (xvalue < yvalue)
                {
                    return 1;
                }
                else if (yvalue > xvalue)
                {
                    return 0;
                }
                else
                {
                    return -1;
                }
            }
            else
            {
                return -1;
            }
        }

        //Gets or sets the SortDirection value
        public Syncfusion.Data.ListSortDirection SortDirection { get; set; }
    }

We hope this helps. Please let us know if you need further assistance from us. 

Regards,
Karthik Raja


Marked as answer

AD Adolfo May 26, 2021 01:07 PM UTC

Thanks again Karthik. 

In your example you're hard-coding the property value in the CustomComparer. Is it possible to pass it dynamically?

        public int Compare(object x, object y)
        {
            var valueOfX = (((DynamicModel)x).Values["OrderID"]).ToString();
            var valueOfY = (((DynamicModel)y).Values["OrderID"]).ToString();

I have more than one sortable column...


AD Adolfo May 26, 2021 04:35 PM UTC

I think I got it. I added a ColumnIndex property to the CustomComparer:

        public int ColumnIndex { get; set; }

Which I'm setting in the GridTapped event handler:

        private void DataGrid_GridTapped(object sender, GridTappedEventArgs e)
        {
            if (e.RowColumnIndex.ColumnIndex > 0 && e.RowColumnIndex.RowIndex == 0)
            {
                customComparer.ColumnIndex = e.RowColumnIndex.ColumnIndex;
                if (customComparer.SortDirection == Syncfusion.Data.ListSortDirection.Ascending)
                {
                    customComparer.SortDirection = Syncfusion.Data.ListSortDirection.Descending;
                }
                else
                {
                    customComparer.SortDirection = Syncfusion.Data.ListSortDirection.Ascending;
                }
            }
        }


KK Karthikraja Kalaimani Syncfusion Team May 27, 2021 04:36 AM UTC

​Hi Adolfo, 

Thanks for the update. We glad to know that your requirement has been achieved at your end. Please let us know if you need further assistance from us. 

Regards,
Karthik Raja

Loader.
Up arrow icon