CustomComparer usage

I'm using blazor server side 19.3 

I tried to add in one of your sample, a custom comparer for a datagrid where I use a datamanager but it's never called

How can I add a custom comparer in a datagrid with Datamanager ?


Attachment: DataGrid_4a9bab24.zip

5 Replies

MS Monisha Saravanan Syncfusion Team January 3, 2022 10:35 AM UTC

Hi Walter Martin, 
Thanks for contacting Syncfusion support. 
We understand your requirement to perform sort action for specific column in custom way and we would like to inform you that SortComparer property works only with local data (i.e.) only when data is bound using DataSource property of Grid. Because while using SfDataManager, we will generate the sorting queries based on the sort settings and send that queries from Grid component to service or DataManager to perform the DataOperation in server side, so it is not possible to send queries for SortComparer to server side. Hence custom sort comparer with SfDataManager is not feasible. Kindly refer the below documentation (note section) in which we had already discussed about your requirement. 


Please get back to us for further details. 

Regards, 
Monisha S 



WM Walter Martin January 3, 2022 11:05 AM UTC

I received your support for another request ( Filtering data by RegExp | Blazor Forums | Syncfusion) where you suggested to use the "customadaptor" to solve my specific problem where a column contains data like 

1

2

1NA

1TER

....

and where I needed to filter only the "numeric" data.

using your suggestion and the customadaptor, the filter is working fine but then the sorting is not working because the column data is a string type so even if I filter only "numeric" values they are showed not in the correct order.

The only solution I think is to use a custom comparer converting the data to interger type after filtering only the "numeric" values but how can do this job if the custom comparer can't be used ?

Thanks



VN Vignesh Natarajan Syncfusion Team January 4, 2022 07:57 AM UTC

Hi Walter, 
 
Thanks for the update.   
 
Query: “I think is to use a custom comparer converting the data to interger type after filtering only the "numeric" values but how can do this job if the custom comparer can't be used ? 
 
We understand that you want to sort the column with number value first among themselves followed by alphanumeric values. As mentioned in the previous update SortComparer feature cannot be used while using SfDataManager to bind datasource.  
 
In this forum also F169715, we have provided a custom solution to achieve your requirement of filtering the alphanumeric value displayed as string. In Similar way we suggest you to handle the sort operation in a custom way in CustomAdaptor Read method.  
 
While sorting a column in Grid, CustomAdaptor’s Read/ReadAsync method will triggered with corresponding action details. We can find the column name and sorting direction details in DataManagerRequest class. Here we suggest you perform sorting action on your own.  
 
Refer the below code example.  
 
// Implementing custom adaptor by extending the DataAdaptor classpublic class CustomAdaptor : DataAdaptor{    // Performs data Read operation    public override object Read(DataManagerRequest dmstring key = null)    {         IEnumerable<Order> DataSource = Orders;        if (dm.Search != null && dm.Search.Count > 0)        {            // Searching            DataSource = DataOperations.PerformSearching(DataSource, dm.Search);        }        if (dm.Sorted != null && dm.Sorted.Count > 0)        {            //will be triggered when sorting action is initiated.            if (dm.Sorted[0].Name == "CustomerID")            {                //handle your custom operation on your own to retunr the list in your custom order.                 ……..            }            else            {                // Sorting                DataSource = DataOperations.PerformSorting(DataSource, dm.Sorted);            }        }        if (dm.Where != null && dm.Where.Count > 0)        {            foreach(var filter in dm.Where[0].predicates)            {                //for CustomerID column                if (filter.value == "NATER" || filter.value == "NAPA" || filter.value == "NA" || filter.value == "PA")                {                    DataSource = DataOperations.PerformFiltering(DataSource, dm.Where, dm.Where[0].Operator);                }                else if (filter.value == "TER")                {                    DataSource = DataSource.Where(e => Regex.Replace(e.CustomerID, @"[\d-]"string.Empty).Equals(filter.value));                }                else if (filter.value == "Digits")                {                    DataSource = DataSource.Where(e => Regex.Matches(e.CustomerID, @"[a-zA-Z]").Count == 0);                }                else if(filter.Field == null && filter.predicates[0].Field == "OrderDate")                {                    //for OrderDate column                    DataSource = DataSource.Where(e=> (e.OrderDate <= (DateTime)filter.predicates[1].value && e.OrderDate>=((DateTime)filter.predicates[0].value)));                }                else                {                    //for other columns - OrderID, Freight                    DataSource = DataOperations.PerformFiltering(DataSource, dm.Where, dm.Where[0].Operator);                }            }        }        int count = DataSource.Cast<Order>().Count();        if (dm.Skip != 0)        {            //Paging            DataSource = DataOperations.PerformSkip(DataSource, dm.Skip);        }        if (dm.Take != 0)        {            DataSource = DataOperations.PerformTake(DataSource, dm.Take);        }        DataResult DataObject = new DataResult();        if (dm.Aggregates != null// Aggregation        {            DataObject.Result = DataSource;            DataObject.Count = count;            DataObject.Aggregates = DataUtil.PerformAggregation(DataSource, dm.Aggregates);             return dm.RequiresCounts ? DataObject : (object)DataSource;        }        return dm.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource;    }}
 
We have found some general links for your reference.  
 
 
So we request you to handle the custom sort action using CustomAdaptor dm.Sort properties and return the sorted list to display in Grid. Please get back to us if you have further queries.  
 
Regards, 
Vignesh Natarajan 



WM Walter Martin January 4, 2022 11:11 AM UTC

Thanks for your suggestion, I supposed to use this way but I didn't know how the Read method actually works

This is the perfect solution for any type of string content in "Numfatt" value


            if (dm.Sorted != null && dm.Sorted.Count > 0)

            {

                if (dm.Sorted[0].Name == "Numfatt")

                {

                    int maxlen = DataSource.Max(x => x.Numfatt.Length);

                    if (dm.Sorted[0].Direction == "ascending")

                        DataSource = DataSource.OrderBy(c => c.Numfatt.Length).ThenBy(c => c.Numfatt.PadLeft(maxlen, '0')).ToList();

                    else

                        DataSource = DataSource.OrderByDescending(c => c.Numfatt.Length).ThenByDescending(c => c.Numfatt.PadLeft(maxlen, '0')).ToList();

                }

                else

                {

                    // Sorting

                    DataSource = DataOperations.PerformSorting(DataSource, dm.Sorted);

                }

            }



MS Monisha Saravanan Syncfusion Team January 5, 2022 11:39 AM UTC

Hi Walter, 

Thanks for your update.  

We  would like to inform you that CustomAdaptor’s Read/ReadAsync method is used to bind data to Grid component and perform data operations like filtering, sorting, searching, etc. During initial rendering, CustomAdaptor Read/ReadAsync method will be triggered with Grid initial settings and bind corresponding data to Grid by performing the skip and take value.   

Similarly, during the data operation like filtering, sorting, searching, paging is performed on DataGrid, it triggers Read/ReadAsync method along with corresponding action details as a queries. For example when we perform sorting on a column, we will send the corresponding column Name and Directions (Ascending or Descending) to the Read/ReadAsync method with DataManagerRequest class. By using the datamanager details, we have separate methods like PerformSorting, PerformFiltering to sort / filter the column with the default settings. Inside the PerformSorting method, we will generate the LINQ query to sort the column in specified direction and execute the operation.  

Hence the string value is sorted with default string configuration. We request you to achieve your requirement using your custom solution. Kindly get back to us if you have any queries. 

Regards, 
Monisha S 


Loader.
Up arrow icon