Advanced custom filters in DataFilter (in unbound mode)

Thread is closed for posting
2 posts, 1 answers
  1. Answer
    Daní
    Daní avatar
    303 posts
    Member since:
    Feb 2008

    Posted 24 Jan 2011 Link to this post

    Requirements

    RadControls version 2010 Q3 SP1

    .NET version

    Visual Studio version 2010

    programming language

    browser support

    all browsers supported by RadControls


    PROJECT DESCRIPTION
    My users was complaining the had to concatenate many OR filters of the same property to perform a multiselection filter. They wanted to be able to select several values in an only filter.

    I decided to implement this feature, so I developped a custom control, MultiOptionFilter that I would use in conjunction with FilterTemplateEditorSlector. Whenever a FilterOperator was set to "IsEqualsTo" or "IsNotEqualsTo" I would show my custom control with a multi selection list. User might choice several options and it would be translated to an OR fitler with all selected values. But I found a big problem:

    The MultiOptionFilter received as DataContext a SimpleFilterViewModel instance. SimpleFilterViewModel is a sort of wrapper of FilterDescriptio. It declares a Value (object) property that allows developper set the filter value. Whenever SimpleFilterViewModel.Value changes an event is raised to allow update the filter. The issue is that despite Value is object typed, SimpleFilterViewModel perfomrs a tyoe correctness check whenever you set this property. As my control allows multi selection, I need to set SimpleFilterViewModel to a collection and the type correctness check does not allow it. SimpleFilterViewModel keeps a reference of the inner FilterDescriptor, but it was'nt public. I thought if SimpleFilterViewModel.FilterDescriptor was public, I could solve this issue using type extensions. I contacted Telerik team in this forum thread MultiSelection Filter thread and thanks to Ross I coulf get FilterDescriptor property public. Now I worte the next extension class for the FilterDescriptor type:

    public static class FilterDescriptorExtensions
        {
            private static Dictionary<FilterDescriptor, object> _values = new Dictionary<FilterDescriptor, object>();
     
            public static void SetDirtyValue(this FilterDescriptor filter, object value)
            {
                _values[filter] = value;
            }
            public static bool TryGetDirtyValue(this FilterDescriptor filter, out object value)
            {
                return _values.TryGetValue(filter, out value);
            }
            public static void Release(this FilterDescriptor filter)
            {
                _values.Remove(filter);
            }
            public static void ReleaseAll()
            {
                _values.Clear();
            }
        }

    With these extesions, I could bypass the type correctness check performed by SimpleFilterViewModel in Value's property. That was great, but i needed to notify filter changes to update the filter result. So I created an interface that my ViewModel classes should to implement to use the MultiOptionFilter control.

    public interface IMultiOptionFilterSource
        {
            IEnumerable Source { get; }
     
            ICommand MultiOptionFilterChangedCommand { get; }
        }

    This interfaces has two properties. Source allows MultiOptionFilter control to get all the avaialable options. MultiOptionFilterChangedCommand allow MultiOptionFilter control notifies the inner view model that the selected options have changed.

    I'm attaching a demo project with an example.

    As you can see, this approch can be usefull for any advanced filter scenario you can imagine
  2. Daní
    Daní avatar
    303 posts
    Member since:
    Feb 2008

    Posted 27 Jan 2011 Link to this post

    I forgot to attach the demo project, so here is

    Edited: I'm uploading a new version that solves several issues and adds some features.

    Edited2: A new update. Now nesting filters keep current selection on first nested child.
Back to Top