【问题标题】:Case insensitive and diacritial marks insensitive filtering with Telerik RadGridView使用 Telerik RadGridView 进行不区分大小写和变音符号的过滤
【发布时间】:2018-10-10 06:06:27
【问题描述】:

标题几乎说明了一切。如何使用 Telerik RadGridView 进行不区分大小写和不区分变音标记的过滤?

我在 Google 上找到了许多可行的解决方案,但没有一个是简单易用的,此外,在许多情况下,它改变了 RadGridView 的 UI 行为,使其对最终用户的吸引力降低。

【问题讨论】:

    标签: c# winforms visual-studio-2015 telerik-grid


    【解决方案1】:

    多年来,我的经验和技能不断增长,所以我终于想出了一个简单易用的解决方案。它适用于 WinForms 2017 R1 或更高版本以及 Visual Studio 2015 或更高版本的 Telerik UI。

    这里是帮助类,RadGridViewHelper

    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();
            }
        }
    }
    

    用法很简单:

    RadGridViewHelper.CustomStringFiltering(radGridView);

    其中radGridView 是类RadGridView 的实例,字符串过滤行为将更改为该类。

    我在这里以问答的方式提出这个问题,因为这里鼓励It’s OK to Ask and Answer Your Own Questions - Stack Overflow Blog

    希望它对某人有所帮助并节省时间和头痛。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-23
      • 1970-01-01
      相关资源
      最近更新 更多