New to Telerik UI for WinForms? Download free 30-day trial

Changing Default Editors

RadFilterView is built of different filter view group elements. The control uses a FilterViewCategoriesFactory that creates the necessary category element considering the property data type:

  • FilterViewNumericCategoryElement: used for numeric types. It generates two RadSpinEditorElements allowing you to specify a range of numeric values. A RadTrackBarElement is also created providing a different user experience for defining a numeric range.
  • FilterViewDateTimeCategoryElement: used for DateTime properties. It generates two RadDateTimePickerElements allowing you to specify a date range.
  • FilterViewBooleanCategoryElement: used for boolean fields. Two RadCheckBoxElements are created allowing you to easily filter by True/False values.
  • FilterViewTextCategoryElement: default category element. It generates a set of check boxes for each string value.

RadFilterView offers a convenient API for customizing the automatically generated editor elements for a certain group. The default category element can be customized either by utilizing the FilterViewCategoriesFactory or by handling the CategoryCreating event.

Using the CategoryCreating Event

Replace FilterViewBooleanCategoryElement with FilterViewTextCategoryElement

For the boolean fields in the applied DataSource, RadFilterView generates a FilterViewBooleanCategoryElement. It contains a group of two check boxes, true/false:

WinForms RadFilterView FilterViewBooleanCategoryElement

The CategoryCreating event gives you the possibility to replace the default FilterViewBooleanCategoryElement with another one, e.g. FilterViewTextCategoryElement with radio buttons:


private void RadFilterView_CategoryCreating(object sender, FilterViewCategoryCreatingEventArgs e)
{
    if (e.Category.PropertyName == "Discontinued")
    {
        FilterViewTextCategoryElement textCategory = new FilterViewTextCategoryElement();
        textCategory.PropertyName = e.Category.PropertyName;
        textCategory.ItemType = FilterViewTextCategoryItemType.RadioButton;
        e.Category = textCategory;
    }
}

WinForms RadFilterView FilterViewTextCategoryElement

Change the default ItemType for FilterViewTextCategoryElement

By default, the FilterViewTextCategoryElement auto-generates a set of check boxes for each string value. You can switch to creating a set of radio buttons and thus allowing only a single text value to be selected:


private void RadFilterView1_CategoryCreating(object sender, FilterViewCategoryCreatingEventArgs e)
{
    if (e.Category.PropertyName == "ProductName")
    {
        FilterViewTextCategoryElement textCategory = e.Category as FilterViewTextCategoryElement; 
        textCategory.ItemType = FilterViewTextCategoryItemType.RadioButton; 
    }
}

WinForms RadFilterView Default ItemType

Customize FilterViewDateTimeCategoryElement

Another case is to replace the default editor controls with more appropriate ones. For example, the FilterViewDateTimeCategoryElement generates two RadDateTimePicker controls:

WinForms RadFilterView Customize FilterViewDateTimeCategoryElement

You may want to replace them with two RadCalendar controls. The following example demonstrates how to do it:

WinForms RadFilterView Replace RadCalendar

public class FilterViewCalendarCategoryElement : FilterViewDateTimeCategoryElement
{

    RadCalendar minValueCalendar;
    RadCalendar maxValueCalendar;

    public FilterViewCalendarCategoryElement(string propertyName) : base(propertyName)
    {

    }

    protected override void CreateChildElements()
    {
        base.CreateChildElements();
        this.MinValueDateTimePicker.Visibility = ElementVisibility.Collapsed;
        this.MaxValueDateTimePicker.Visibility = ElementVisibility.Collapsed;
        this.minValueCalendar = new RadCalendar();
        minValueCalendar.AllowMultipleSelect = false;
        this.minValueCalendar.SelectedDate = this.minValue;
        RadHostItem minHost = new RadHostItem(this.minValueCalendar);
        minHost.MinSize = new Size(0, 150);
        this.minValueCalendar.SelectionChanged += Calendar_SelectionChanged;
        this.minValueCalendar.Margin = new Padding(2);
        this.EditorsStack.Children.Insert(1, minHost);
        this.minValueCalendar.SelectedDate = this.minValue;

        this.maxValueCalendar = new RadCalendar();
        maxValueCalendar.AllowMultipleSelect = false;
        this.maxValueCalendar.SelectedDate = this.maxValue;
        this.maxValueCalendar.SelectionChanged += Calendar_SelectionChanged;
        RadHostItem maxHost = new RadHostItem(this.maxValueCalendar);
        maxHost.MinSize = new Size(0, 150);
        maxHost.StretchHorizontally = true;
        this.maxValueCalendar.Margin = new Padding(2);
        this.EditorsStack.Children.Add(maxHost);
    }

    protected override void DisposeManagedResources()
    {
        base.DisposeManagedResources();
        this.minValueCalendar.SelectionChanged -= Calendar_SelectionChanged;
        this.maxValueCalendar.SelectionChanged -= Calendar_SelectionChanged;
    }
    public override void CreateItems(ICollection<object> values)
    {
        base.CreateItems(values);
        this.minValueCalendar.SelectionChanged -= Calendar_SelectionChanged;
        this.maxValueCalendar.SelectionChanged -= Calendar_SelectionChanged;
        minValueCalendar.SelectedDate = this.minValue;
        minValueCalendar.FocusedDate = this.minValue;
        maxValueCalendar.SelectedDate = this.maxValue;
        maxValueCalendar.FocusedDate = this.maxValue;
        this.minValueCalendar.SelectionChanged += Calendar_SelectionChanged;
        this.maxValueCalendar.SelectionChanged += Calendar_SelectionChanged;
    }

    private void Calendar_SelectionChanged(object sender, EventArgs e)
    {
        this.ItemFilterChanged(null);
    }

    protected override DateTime? GetMinEditorValue()
    {
        return this.minValueCalendar.SelectedDate;
    }

    protected override DateTime? GetMaxEditorValue()
    {
        return this.maxValueCalendar.SelectedDate;
    }

    protected override void SetMinEditorValue(DateTime? newValue)
    {
        base.SetMinEditorValue(newValue);
        if (newValue != null)
        {
            this.minValueCalendar.SelectedDate = (DateTime)newValue;
            this.minValueCalendar.FocusedDate = this.minValueCalendar.SelectedDate;
        }
    }

    protected override void SetMaxEditorValue(DateTime? newValue)
    {
        base.SetMaxEditorValue(newValue);
        if (newValue != null)
        {
            this.maxValueCalendar.SelectedDate = (DateTime)newValue;
            this.maxValueCalendar.FocusedDate = this.maxValueCalendar.SelectedDate;
        }
    }
}

Then, apply the custom category element in the CategoryCreating event:


private void RadFilterViewCategoryCreating(object sender, FilterViewCategoryCreatingEventArgs e)
{
    if (e.Category is FilterViewDateTimeCategoryElement)
    {
        FilterViewCalendarCategoryElement calendarCategory = new FilterViewCalendarCategoryElement(e.Category.PropertyName); 
        e.Category = calendarCategory;
    }
} 

It is possible to either use the CategoryCreating event or a custom FilterViewCategoriesFactory to replace one of the default category elements with your custom one.

Using a Custom Factory

Create a derivative of the FilterViewCategoriesFactory element and override its CreateCategory method. This is the default logic for generating the category elements considering the property data type. It is possible to plug into the creation process and adjust it according to any custom requirements:

public class CustomFilterViewCategoriesFactory : Telerik.WinControls.UI.FilterView.FilterViewCategoriesFactory
{
    public override BaseFilterViewCategoryElement CreateCategory(string propertyName, Type propertyType, string displayName = "")
    {
        if (TelerikHelper.IsNumericType(propertyType))
        {
            return new FilterViewNumericCategoryElement(propertyName, propertyType, displayName);
        }
        else if (propertyType == typeof(DateTime))
        {
            return new FilterViewDateTimeCategoryElement(propertyName, propertyType, displayName);
        }
        else if (propertyType == typeof(bool))
        { 
            return new FilterViewBooleanCategoryElement(propertyName, propertyType, displayName);
        }

        return new FilterViewTextCategoryElement(propertyName, propertyType, displayName);
    }
}

Then, apply the custom factory:


this.radFilterView1.CategoriesFactory = new CustomFilterViewCategoriesFactory();