Telerik Radgrid filter without taking into account the accents

0

I have a Telerik Radgrid in which I want to search (filter) and that does not take into account the accents, that is, if I have as data "Truck" and "Truck", that when writing in the "Truck" filter the two results appear and vice versa.    Is there any property already included in the control that allows this to be done?.

Thank you.

    
asked by Isa 28.09.2016 в 12:49
source

3 answers

1

There is not anything native to control, but by scheduling events you can solve your problem. These are the steps:

  • In the NeedDataSource radgrid event, the accents are removed with the following method and a hidden copy is created without accents:

    public static string RemoveDiacritics(string s)  
    {  
        string normalizedString = s.Normalize(NormalizationForm.FormD);  
        StringBuilder stringBuilder = new StringBuilder();  
    
        for (int i = 0; i < normalizedString.Length; i++)  
        {  
            char c = normalizedString[i];  
            if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)  
            {  
                stringBuilder.Append(c);  
            }  
        }  
        return stringBuilder.ToString();  
    }
    
  • In the event itemCommand of radgrid , check if the column has accents, for example [RaisonSociale] , if so, take the hidden column that does not have accents [RaisonSocialeFiltre] :

    protected void RadGridClients_ItemCommand(object source, GridCommandEventArgs e)  
    {  
        if (e.CommandName == RadGrid.FilterCommandName)  
        {  
            Pair laPaire = (Pair)e.CommandArgument;  
            if (string.Compare((string)laPaire.Second, "RaisonSociale") == 0)  
            {  
                e.Canceled = true;  
    
                TextBox txtBox = (TextBox)((GridFilteringItem)e.Item)["RaisonSociale"].Controls[0];  
                FiltreOriginalClient = txtBox.Text;  
    
                GridColumn colonneCachee = ((RadGrid)source).MasterTableView.GetColumnSafe("RaisonSocialeFiltre");  
                colonneCachee.CurrentFilterFunction = (GridKnownFunction)(Enum.Parse(typeof(GridKnownFunction), Convert.ToString(laPaire.First, CultureInfo.InvariantCulture), true));  
                colonneCachee.CurrentFilterValue = Utilitaire.RemoveDiacritics(txtBox.Text);  
                ((RadGrid)source).Rebind();  
    
                GridFilteringItem filterItem = ((RadGrid)source).MasterTableView.GetItems(GridItemType.FilteringItem)[0] as GridFilteringItem;  
                filterItem.FireCommandEvent("Filter", new Pair((string)laPaire.First, "RaisonSocialeFiltre"));  
            }  
        }  
    } 
    
  • Finally, in the event ItemDataBound , the filter is returned to its original state, in this case a variable global called FiltreOriginalClient is used:

        protected void RadGridClients_ItemDataBound(object sender, GridItemEventArgs e)  
    {  
        // Utilisé pour remettre le filtre dans le textbox filtre en haut de la colonne RaisonSociale  
        if (e.Item.ItemType == GridItemType.FilteringItem)  
        {  
            if (!string.IsNullOrEmpty(((TextBox)((GridFilteringItem)e.Item)["RaisonSocialeFiltre"].Controls[0]).Text) && !string.IsNullOrEmpty(FiltreOriginalClient))  
            {  
                ((TextBox)((GridFilteringItem)e.Item)["RaisonSociale"].Controls[0]).Text = FiltreOriginalClient;  
            }  
        }  
    } 
    
  • I hope this helps you.

    Reference: ACCENT INSENSITIVE FILTERING - Filtering on a different column

        
    answered by 11.10.2016 в 19:36
    0

    The truth is that there is no property that does this in the framework, at the most you will have to do it manually you. Whether replacing the vowels of each query before making the query. Greetings

        
    answered by 28.09.2016 в 15:29
    0

    I have had this problem since time immemorial, and because my clients never demanded this functionality, I never set out to achieve this filter without taking into account the accents.

    Recently I was involved in a small project in which I said "Enough!" and implemented this functionality in the most comfortable way possible.

    The code is compatible with Telerik UI for WinForms 2017 R1 or higher, and Visual Studio 2015 or higher.

    I see that the difficulty is presented with Telerik and ASP.NET. I hope the difference is not so great with respect to Telerik and WinForms.

    Source code of the assistant class:

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Globalization;
    using System.Linq;
    using Telerik.WinControls.Data;
    using Telerik.WinControls.UI;
    
    namespace MySoftware.Helpers
    {
        internal static class RadGridViewHelper
        {
            private class CustomStringFilteringClass
            {
                private RadGridView RadGridView { get; }
                private bool _enabled;
                private ReadOnlyCollection<string> StringColumns { get; }
    
                public CustomStringFilteringClass(RadGridView radGridView)
                {
                    RadGridView = radGridView;
                    StringColumns = new ReadOnlyCollection<string>(GetStringColumns(radGridView));
                }
    
                public void Enable()
                {
                    if (_enabled) throw new InvalidOperationException("Can't call this method twice");
                    _enabled = true;
    
                    RadGridView.EnableCustomFiltering = true;
                    RadGridView.CustomFiltering += RadGridViewOnCustomFiltering;
                }
    
                private void RadGridViewOnCustomFiltering(object sender, GridViewCustomFilteringEventArgs e)
                {
                    if (RadGridView.FilterDescriptors.Count == 0) return;
    
                    var row = e.Row;
    
                    foreach (var stringColumn in StringColumns)
                    {
                        var filterDescriptors = RadGridView.FilterDescriptors.Where(
                            x => x.PropertyName == stringColumn).ToList();
                        if (filterDescriptors.Count != 1)
                        {
                            continue;
                        }
                        var filterDescriptor = filterDescriptors.First();
                        var cellValue = ((string)row.Cells[stringColumn].Value).ToLowerInvariant();
                        if (filterDescriptor.GetType() == typeof(CompositeFilterDescriptor))
                        {
                            if (!CompositeFilterEvaluateString((CompositeFilterDescriptor)filterDescriptor, cellValue,
                                RadGridView.MasterTemplate.DataView.FilterEvaluate, row))
                            {
                                e.Visible = false;
                                return;
                            }
                        }
                        else if (!FilterEvaluateString(filterDescriptor, cellValue,
                            RadGridView.MasterTemplate.DataView.FilterEvaluate, row))
                        {
                            e.Visible = false;
                            return;
                        }
                    }
    
                    var nonStringFilterDescriptors = RadGridView.FilterDescriptors.Where(
                        x => !StringColumns.Contains(x.PropertyName));
                    foreach (var filterDescriptor in nonStringFilterDescriptors)
                    {
                        if (!RadGridView.MasterTemplate.DataView.FilterEvaluate(filterDescriptor, row))
                        {
                            e.Visible = false;
                            return;
                        }
                    }
                }
    
                private static bool CompositeFilterEvaluateString(CompositeFilterDescriptor compositeFilterDescriptor,
                string cellValue, Func<FilterDescriptor, GridViewRowInfo, bool> gridFilterEvaluate, GridViewRowInfo row)
                {
                    switch (compositeFilterDescriptor.LogicalOperator)
                    {
                        case FilterLogicalOperator.And:
                            if (compositeFilterDescriptor.FilterDescriptors.Any(filterDescriptor =>
                            {
                                if (filterDescriptor.GetType() == typeof(CompositeFilterDescriptor))
                                    return !CompositeFilterEvaluateString((CompositeFilterDescriptor)filterDescriptor,
                                        cellValue, gridFilterEvaluate, row);
                                return !FilterEvaluateString(filterDescriptor, cellValue, gridFilterEvaluate, row);
                            }))
                                return false;
                            break;
                        case FilterLogicalOperator.Or:
                            if (compositeFilterDescriptor.FilterDescriptors.All(filterDescriptor =>
                            {
                                if (filterDescriptor.GetType() == typeof(CompositeFilterDescriptor))
                                    return !CompositeFilterEvaluateString((CompositeFilterDescriptor)filterDescriptor,
                                        cellValue, gridFilterEvaluate, row);
                                return !FilterEvaluateString(filterDescriptor, cellValue, gridFilterEvaluate, row);
                            }))
                                return false;
                            break;
                    }
                    return true;
                }
    
                private static bool FilterEvaluateString(FilterDescriptor filterDescriptor, string cellValue,
                    Func<FilterDescriptor, GridViewRowInfo, bool> gridFilterEvaluate, GridViewRowInfo row)
                {
                    var filterDescriptorValue = ((string) filterDescriptor.Value).ToLowerInvariant();
                    switch (filterDescriptor.Operator)
                    {
                        case FilterOperator.Contains:
                            if (CultureInfo.InvariantCulture.CompareInfo.IndexOf(cellValue, filterDescriptorValue,
                                    CompareOptions.IgnoreNonSpace) == -1)
                                return false;
                            break;
                        case FilterOperator.NotContains:
                            if (CultureInfo.InvariantCulture.CompareInfo.IndexOf(cellValue, filterDescriptorValue,
                                    CompareOptions.IgnoreNonSpace) != -1)
                                return false;
                            break;
                        case FilterOperator.StartsWith:
                            if (!CultureInfo.InvariantCulture.CompareInfo.IsPrefix(cellValue, filterDescriptorValue,
                                CompareOptions.IgnoreNonSpace))
                                return false;
                            break;
                        case FilterOperator.EndsWith:
                            if (!CultureInfo.InvariantCulture.CompareInfo.IsSuffix(cellValue, filterDescriptorValue,
                                CompareOptions.IgnoreNonSpace))
                                return false;
                            break;
                        case FilterOperator.IsEqualTo:
                            if (String.Compare(cellValue, filterDescriptorValue, CultureInfo.InvariantCulture,
                                    CompareOptions.IgnoreNonSpace) != 0)
                                return false;
                            break;
                        case FilterOperator.IsNotEqualTo:
                            if (String.Compare(cellValue, filterDescriptorValue, CultureInfo.InvariantCulture,
                                    CompareOptions.IgnoreNonSpace) == 0)
                                return false;
                            break;
                        default:
                            if (!gridFilterEvaluate.Invoke(filterDescriptor, row))
                                return false;
                            break;
                    }
                    return true;
                }
            }
    
            private static List<string> GetStringColumns(RadGridView radGridView)
            {
                var retVal = new List<string>();
                foreach (var column in radGridView.Columns)
                {
                    if (column.DataType == typeof(string))
                    {
                        retVal.Add(column.Name);
                    }
                }
                return retVal;
            }
    
            /// <summary>
            /// Enables custom string filtering on <paramref name="radGridView"/>. It is case insensitive and
            /// tolerates differences in diacritical marks. For example, in a "equals" comparision, the value
            /// 'ëMúa' is treated as its equal to 'EmÜâ'.
            /// </summary>
            /// <param name="radGridView">Instance of <see cref="RadGridView"/> in which custom string filtering
            /// will be enabled.</param>
            public static void CustomStringFiltering(RadGridView radGridView)
            {
                var customFiltering = new CustomStringFilteringClass(radGridView);
                customFiltering.Enable();
            }
        }
    }
    

    And the use is very simple:

    RadGridViewHelper.CustomStringFiltering(radGridView);

    Where radGridView is the instance of the class RadGridView to which you want to alter the behavior of text filtering.

    It is important that before calling the CustomStringFiltering method, all the columns with their appropriate data types have been added to radGridView . It is also important not to modify, add or delete the columns after calling the CustomStringFiltering method.

    The new behavior of text filtering is such that in a comparison of type "Equal to", the value ëMúa is treated as if it were equal to EmÜâ .

    Apologies for the source code in English P:

        
    answered by 24.03.2017 в 03:30