On the RadDataGrid, I want to make the default text comparison on the built-in composite filter case insensitive

2 Answers 83 Views
DataGrid
Christopher
Top achievements
Rank 2
Iron
Iron
Christopher asked on 09 May 2022, 04:31 PM | edited on 09 May 2022, 09:47 PM

I read the topics on creating a custom DataGridTextFilterControl that is case insensitive and that works. But I want the text filter with the multiple clauses ANDed or ORed together (the text filters in the CompositeFilterDescriptor) to be case insensitive as well. 

I don't see a way to create a DataGridTypedFilter or a composite filter, since they're all internal.

There should be a way to set the case insensitive option lower in the object hierarchy, but I can't find it.

What is the purpose of the ApplyFilter command, which fires when you click "Filter" on the filter popup, if it provides no information about the filter that is about to be applied? It looks like I need a handle to the FilterDescriptor that is about to be applied and then I could dig down into the CompositeFilterDescriptor and set the IsCaseSensitive property before it's applied.

Any hints or options that I've missed?

Also, I'm Binding to a DataTable with AutoGenerateColumns=true, so setting up the filtering via XAML on a per column basis is not a solution for us.

2 Answers, 1 is accepted

Sort by
0
Accepted
Christopher
Top achievements
Rank 2
Iron
Iron
answered on 11 May 2022, 04:09 PM

An even easier solution was to use the FilterDescriptors CollectionChanged event. I put this in a utility class, so all you have to do is call:

myRadDataGrid.MakeCaseInsensitive();
Here is the code:

        public static void MakeCaseSensitive(this RadDataGrid dataGrid)
        {
            dataGrid.FilterDescriptors.CollectionChanged -= FilterDescriptorsOnCollectionChanged;
        }
        public static void MakeCaseInsensitive(this RadDataGrid dataGrid)
        {
            dataGrid.FilterDescriptors.CollectionChanged += FilterDescriptorsOnCollectionChanged;
        }

        private static void FilterDescriptorsOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (sender is FilterDescriptorCollection fcc)
            {
                foreach (var fd in fcc)
                {
                    if (fd is CompositeFilterDescriptor cfd)
                    {
                        foreach (var fds in cfd.Descriptors)
                        {
                            if (fds is TextFilterDescriptor tfd)
                            {
                                tfd.IsCaseSensitive = false;
                            }
                        }
                    }
                }
            }
        }

0
Christopher
Top achievements
Rank 2
Iron
Iron
answered on 10 May 2022, 02:09 AM | edited on 10 May 2022, 02:27 PM
Figured it out. When the ApplyFilter Command is triggered, the FilterDescriptors are only applied to the RadDataGrid after the DefaultCommand is executed. So if you check after the DefaultCommand, then you can change the descriptors. In my case, I wanted all text fields to be Case Insensitive and the DataGridTextFilterControl returns a CompositeFilterDescriptor which can contain multiple FilterDescriptors chained together with AND and/or OR.

So, I created a custom Command to intercept the DataGridCommandId.ApplyFilter and, after calling the DefaultCommand, I walk the _radDataGrid's FilterDescriptors property.

This may not be the final version of my solution (it has no error checking and may need a few special cases), but it served as a proof-of-concept:

    public class ApplyFilterUserCommand : DataGridCommand
    {
        private RadDataGrid _radDataGrid;
        public ApplyFilterUserCommand(RadDataGrid radDataGrid)
        {
            this._radDataGrid = radDataGrid;
            Id = DataGridCommandId.ApplyFilter;
        }
        
        public override bool CanExecute(object parameter)
        {
            return true;
        }

        public override void Execute(object parameter)
        {
            this.Owner.CommandService.ExecuteDefaultCommand(DataGridCommandId.ApplyFilter, parameter);

            if (_radDataGrid.FilterDescriptors != null)
            {
                foreach (var fd in _radDataGrid.FilterDescriptors)
                {
                    if (fd is CompositeFilterDescriptor cfd)
                    {
                        foreach (var fds in cfd.Descriptors)
                        {
                            if (fds is TextFilterDescriptor tfd)
                            {
                                tfd.IsCaseSensitive = false;
                            }
                        }
                    }
                }
            }
        }
    }

Tags
DataGrid
Asked by
Christopher
Top achievements
Rank 2
Iron
Iron
Answers by
Christopher
Top achievements
Rank 2
Iron
Iron
Share this question
or