Filtered event does not fire when field filter descriptor operator is changed

2 posts, 0 answers
  1. Brice Mason
    Brice Mason avatar
    7 posts
    Member since:
    Jan 2010

    Posted 30 Jul 2010 Link to this post

    Hello,

    I have a small code sample which demonstrates when the operator is changed in the field filter descriptor, the RadGridView Filtered event does not fire. The grid data updates appropriately however. 

    Here is the MainPage xaml:

    <UserControl x:Class="GridFilter.MainPage"
        xmlns:telerikGrid="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.GridView"
        mc:Ignorable="d"
        d:DesignHeight="300" d:DesignWidth="400">
     
        <Grid x:Name="LayoutRoot" Background="White">
            <telerikGrid:RadGridView x:Name="SampleGrid" />
        </Grid>
    </UserControl>

    and here is the code behind:

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Windows.Controls;
    using Telerik.Windows.Controls;
    using Telerik.Windows.Data;
     
    namespace GridFilter
    {
        public partial class MainPage : UserControl
        {
            public MainPage()
            {
                InitializeComponent();
     
                // fill the sample grid with data
                SampleGrid.ItemsSource = GetSampleData();
     
                SampleGrid.Filtered += new EventHandler<Telerik.Windows.Controls.GridView.GridViewFilteredEventArgs>(OnGridFiltered);
            }
     
     
     
     
            private void OnGridFiltered(object sender, Telerik.Windows.Controls.GridView.GridViewFilteredEventArgs e)
            {
                Debug.WriteLine("Filtered event fired");
            }
     
     
     
     
            private List<SampleItem> GetSampleData()
            {
                List<SampleItem> sample = new List<SampleItem>();
     
                for( int i = 0; i < 25; i++ ) {
                    sample.Add( new SampleItem() {
                        FirstName = "First Name " + i,
                        LastName  = "Last Name " + i
                    } );
                }
     
                return sample;
            }
        }
     
     
     
        public class SampleItem
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }
        }
    }

    Here are the steps to reproduce:

    1. Click the LastName column filter, select a distinct value filter item (filter event fires)
    2. Click the LastName column filter, de-select the distinct value filter item from above (filter event fires)
    3. Select Ends with for the first field filter descriptor and enter a value of 5
    4. Select Ends with for the second field filter descriptor and enter a value of 2
    5. Click Filter (filter event fires)
    6. Change the operator in the field filter descriptor from And to Or (the grid updates, filter event does NOT fire)
    7. Click Filter button (filter event still does NOT fire)

    I am using Telerik controls 2010.1.603.1030 in a Silverlight 3 project.

    Thanks,

    Brice Mason
  2. Rossen Hristov
    Admin
    Rossen Hristov avatar
    2478 posts

    Posted 02 Aug 2010 Link to this post

    Hello Brice Mason,

    The Filtered event can't fire for this particular case. If you notice, the FilterDescriptor's that you get in the event arguments are "fake". For example, when you change the Value of a FieldFilter, the actual FilterDescirptor that is attached to grid stays right there and only changes it's value. But we create two fake descriptors in order to fire the event and have a "Removed" and "Added" arguments.

    When the operator between the two filters is changed, the actual descriptors are not altered and that is why we do not fire the event.

    But there is a very easy way to detect what is really going one. The first time someone filter a column a class called ColumnFilterDescriptor is added to RadGridView.FilterDescriptors collection.

    Now, this class ColumnFilterDescritptor derives from the CompositeFilterDescriptor class which means that it is used to compose one or more child filters. In the case of the ColumnFilterDescriptor, it has only two child filters -- one for the upper part with the Distinct Values and one for the lower part with the two Field Filters.

    So, the ColumnFilterDescriptor class has a property called FieldFilter, which is a CompositeFilterDescriptor as well, since it holds the two field filters together by combining them with a LogicalOperator. This logical operator is the thing that you need to listen for.

    Here is how you can easily do this:

    using System.Windows.Controls;
    using System.Collections.Generic;
    using Telerik.Windows.Data;
    using System.Linq;
    using System.Collections;
    using System.Diagnostics;
    using Telerik.Windows.Controls.GridView;
     
    namespace RadGridView_SL4_AR_1
    {
        public partial class MainPage : UserControl
        {
            public MainPage()
            {
                InitializeComponent();
     
                this.clubsGrid.FilterDescriptors.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(FilterDescriptors_CollectionChanged);
            }
     
            void FilterDescriptors_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
            {
                switch (e.Action)
                {
                    case System.Collections.Specialized.NotifyCollectionChangedAction.Add:
                        if (e.NewItems.Count == 1)
                        {
                            // This is the top-level filter that is added to the grid.
                            // There is one such filter per column. It holds all the info
                            // about the distinct value and the filed filter.s
                            var cfd = e.NewItems[0] as ColumnFilterDescriptor;
                             
                            if (cfd != null && cfd.Column == this.clubsGrid.Columns[0])
                            {
                                // This is the child filter responsible for the two field filters.
                                // It is a CompositeFilterDescriptor as well since it hold the two
                                // field filters together. It's operator is the thing that you change
                                // and you do not get the filtered event.
                                cfd.FieldFilter.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(FieldFilter_PropertyChanged);
                            }
                        }
                        break;
                }
            }
     
            void FieldFilter_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
            {
                if (e.PropertyName == "LogicalOperator")
                {
                    FieldFilterDescriptor ffd = (FieldFilterDescriptor)sender;
                    Debug.WriteLine("The FieldFilter for the first column has changed its logical operator to " + ffd.LogicalOperator);
                }
            }
     
            private void clubsGrid_Filtered(object sender, Telerik.Windows.Controls.GridView.GridViewFilteredEventArgs e)
            {
                Debug.WriteLine(string.Format("Filtered, Added={0}, Removed={1}", e.Added.Count(), e.Removed.Count()));
            }
        }
    }

    I have prepared a sample project with a reference implementation that you can tailor to your specific needs.

    Here is the basic hierarchy in ASCII art:

                  ColumnFilterDescriptor (assosicated with a particular column)
                           |
            ---------------------------
            |                         |
    DistinctValuesFilter         FieldFilter (this has the operator)
            |                         |
     --------------              -------------
     |    |       |              |           |
    DV1  DV2 ... DVN             F1           F2

    The whole idea of the ColumnFilterDescriptor is explained in my blog post. Let me know if there are problems.

    All the best,
    Ross
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  3. DevCraft banner
Back to Top