Filtering Attributes

  • 10 minutes to read

The Filtering UI Context component can recognize attributes declared before filtering Model properties. These attributes affect the filter editor's appearance and behavior. There are two types of supported attributes:

NOTE

Filtering attributes have no effect if you declare them after clicking the 'Retrieve Fields' link in the component's smart tag menu unless you remove all previously generated editors and re-create the filter UI.

TIP

You can use filter attributes outside the scope of the Filtering UI Context component. For instance, you can select which editors appear inside an Excel-style filter using these attributes.

FilterBooleanChoice

This attribute marks Boolean properties and provides the following members:

  • EditorType - allows you to choose which editor is generated for the Boolean property:

    • Check Edit (default)
    • ComboBox Edit
    • Radio Group
    • Toggle Switch Edit
  • DefaultName, TrueName, FalseName - replaces the default 'True', 'False' and 'Default' option names for ComboBox Edit and Radio Group editors.
  • DefaultValue - allows you to prohibit filtering data by a specific Boolean value. For example, filtering by the ”InStock = false” expression makes no sense since browsing only unavailable goods makes no sense. In this scenario, the ”false” value is irrelevant and can be ignored. Note that you can do the same by handling the QueryBooleanChoiceData event.
  • DefaultValueMember - similar to the DefaultValue property, but instead of specifying the irrelevant Boolean value explicitly, you refer to a property or a method that returns this value. This member must be declared in either a base or parent ViewModel.

The code sample below illustrates how to use this attribute.


[FilterBooleanChoice(false, EditorType = BooleanUIEditorType.List, DefaultName = "Show all", TrueName = "Show only available models")]
public bool InStock { get; set; }

The figure below illustrates the result.

FilteringUI - Remove Boolean Values

FilterRange

Declare this attribute before a numeric property to change the editor type and provide borderline editor values.

  • EditorType - for filtering numeric properties you can use:

    • two Text Edits (default)
    • two Spin Edits
    • Range Trackbar
  • FromName, ToName - replaces the default 'From' and 'To' captions next to Text or Spin Edit editors.
  • Minimum, Maximum, Average - sets the numeric property's borderline values. Identical to the QueryRangeData event.
  • MinimumMember, MaximumMember, AverageMember - allows you to implement a more flexible behavior, where minimum, maximum and average values are not explicitly set, but returned by specific members declared in either a base or parent ViewModel.

[FilterRange(0, 10000, EditorType = DevExpress.Utils.Filtering.RangeUIEditorType.Spin, FromName="Min Price", ToName="Max Price")]
[DisplayFormat(DataFormatString="c0")]
public decimal Price { get; set; }

FilteringUI - New - FilterRange attr

FilterDateTimeRange

An attribute that manages editors used for filtering DateTime properties.

  • EditorType - allows you to choose from multiple editor variations. Currently, only the Default/Range value is operational. This value allows you to display two DateEdit editors.
  • Since this attribute derives from the same base class as the FilterRange attribute, it exposes the same properties: FromName, Minimum, AverageMember, etc.

FilterEnumChoice

This attribute allows you to customize editors for properties that store enumeration values. Alternatively, it makes it possible to treat non-enumeration properties as an Enum type.

For example, in the code below, a sample filtering ViewModel contains car records with the "Doors" property as one of the data fields. This is an integer property, and the Filtering UI Context generates "From" and "To" text boxes for this field by default. Create a custom "DoorsEnum" enumeration and map the "Doors" property to this enumeration by declaring the EnumDataType attribute. The Filtering UI Context now treats this property an Enum type, which allows end-users to select the required values instead of setting value ranges. Add the FilterEnumChoice attribute to customize the editor generated for this field.


//Custom enumeration
public enum DoorsEnum {
    [Display(Name = "2 Doors")]
    Door2 = 2,
    [Display(Name = "3 Doors")]
    Door3 = 3,
    [Display(Name = "4 Doors")]
    Door4 = 4,
    [Display(Name = "5 Doors")]
    Door5 = 5
}

//Filtering Model property, mapped to the custom enumeration
[FilterEnumChoice(EditorType = LookupUIEditorType.List, UseSelectAll = true, SelectAllName = "All Models")]
[EnumDataType(typeof(FilteringUiGS.DoorsEnum))]
public int Doors { get; set; }

The result is shown below.

FilteringUI - New - Int To Enum Property

The FilterEnumChoice attribute provides the following properties.

  • EditorType - allows you to choose which editor should be generated for the current filtering Model property.

  • UseSelectAll - gets or sets whether the editor should display the item that selects all the available options. The SelectAllName property allows you to replace this item's caption.

FilterLookup

An attribute that marks properties of the String, Object and other complex types. Provides the capability to load and/or initially display a specific item number.

  • EditorType supports the following editors:

  • DataSourceMember - refers to a member that returns a collection of lookup items for this editor. This member must be declared in either the base or parent ViewModel.
  • Top, MaxCount - allows you to limit the number of initially visible items and their overall amount. See the QueryLookupData event to learn more.
  • TopMember, MaxCountMember - the same as Top and MaxCount properties, but accepts the names of either base or parent ViewModel members that return the required numbers.
  • UseSelectAll, SelectAllName - specifies an item's availability and caption which allows end-users to select all lookup items.

FilteringUI - FilterLookup Trademark

FilterGroup

This attribute allows you to group filter items from two or more properties (filters), and present the result as a hierarchical checked list.

Assume that a data source contains the CategoryID and ProductName fields. For each field the Filtering UI Context generates its own filter with a regular drop-down list. Apply the FilterGroup attribute to group products by categories in the ProductName field's filter dropdown:

FilterGroups-EnabledForProduct.gif

[DevExpress.Utils.Filtering.FilterGroup("CategoryID;ProductName")]
public string ProductName { get; set; }

public int? CategoryID { get; set; }

To apply the same grouping to the CategoryID field, set the FilterGroup attribute to FilterGroup("ProductName") or FilterGroup("CategoryID;ProductName"):

[DevExpress.Utils.Filtering.FilterGroup("ProductName")]
public int? CategoryID { get; set; }
IMPORTANT

If the FilterUIContext is unbound and receives a filter model instead of a data-aware control, setting the FilterGroup attribute alone has no effect. You also need to handle the QueryGroupData filtering event to provide filter items (values).

Metadata Attributes

The example attached to the Data Annotation Attributes topic illustrates how to use Microsoft's MetadataType attribute to inherit attributes declared within a separate class. The Filtering UI Context supports the same attribute. Additionally, DevExpress provides the FilterMetadataType attribute, which has priority over the MetadataType attribute and is designed to inherit filtering attributes. Both attributes must be declared before the filtering Model's class declaration.

The following code displays a filtering Model that uses only standard attributes to customize the editor's appearance. All filtering attributes are declared in a separate class and inherited by the filtering Model marked with the FilterMetadataType attribute. Note that you do not need to duplicate filtering Model properties within your metadata class - declaring object-typed public fields is sufficient.


//The filtering Model class
[FilterMetadataType(typeof(MetadataClass))]
public class FilteringModel {
    const string Main = "Main Parameters";

    [Display(GroupName = Main)]
    public int Trademark { get; set; }

    [Display(GroupName = Main)]
    public decimal Price { get; set; }

    [Display(GroupName = Main)]
    public int Category { get; set; }

    [Display(Name = "Availability", GroupName = Main)]
    public bool InStock { get; set; }
}

//The class that contains the required filtering attributes
public class MetadataClass {
    [FilterLookup(10, ValueMember = "ID", DisplayMember = "Name", EditorType = LookupUIEditorType.List)]
    public object Trademark;

    [FilterRange(0, 170000), DataType(DataType.Currency)]
    public object Price;

    [FilterEnumChoice(EditorType = LookupUIEditorType.List)]
    [EnumDataType(typeof(VehiclesData.Category))]
    public object Category;

    [FilterBooleanChoice(false, EditorType = BooleanUIEditorType.List, DefaultName = "Show all test", TrueName = "Show only available models")]
    public object InStock;
}

You can use the MetadataBuilder to build all required metadata using the Fluent API. See the code below (and the Data Bindings and Notifications article's Meta-POCO Bindings section) for an example.


public class MetadataClass {
    public static void BuildMetadata(FilteringMetadataBuilder<FilteringModel> builder) {
        builder.Property(x => x.Category)
            .FilterEnumChoice(editorType: Mvvm.Native.FilterLookupUIEditorType.List, selectAllName: "All Categories", useSelectAll: true);
        builder.Property(x => x.Price)
            .CurrencyDataType()
            .DisplayName("PRICE")
            .FilterRange(0, 10000, editorType: Mvvm.Native.FilterRangeUIEditorType.Range);
        builder.Property(x => x.InStock)
            .FilterBooleanChoice(editorType: Mvvm.Native.FilterBooleanUIEditorType.Check, falseName: "No");
        builder.Property(x => x.Trademark)
            .FilterLookup(10, valueMember: "ID", displayMember: "Name", editorType: Mvvm.Native.FilterLookupUIEditorType.List);
    }
}

After the metadata class is ready, you need to register it. The code below demonstrates how to register the sample metadata class and set up a relationship between it and the filtering Model .


public myApplicationForm () {
     MetadataLocator.Default = MetadataLocator.Create()
         .AddMetadata(typeof(FilteringModel), typeof(MetadataClass));
     . . .
     InitializeComponent();
 }
IMPORTANT

Using the metadata builder requires that your application references the DevExpress.MVVM library.

Data Annotation Attributes

These are standard Microsoft attributes, declared in the System.ComponentModel.DataAnnotations namespace. You can use these attributes to do the following:

  • Change the generated filter editor's caption (if it has any) and place this editor to a specific group. Use the Display attribute's Name and GroupName parameters to do this.

    
    public class FilteringModel {
        const string Main = "Simple Filters";
    
        [Display(Name = "In Stock", GroupName = Main)]
        public bool InStock { get; set; }
    
        [Display(GroupName = "Another group")]
        public decimal Price { get; set; }
    }
    
  • Prohibit generating editors for specific filtering Model properties. This feature is helpful when using code-first data sources, where your data class can be used as a filtering Model directly. Such classes often contain data field properties that should not be available for filtering (for example, product IDs). To disable filtering by these properties, set the Display attribute 's AutoGenerateFilter parameter to false.

    
    [Display(AutoGenerateFilter=false)]
    public int ProductID { get; private set;}
    
  • Format editors' data using the DataType and DisplayFormat attributes. The code sample below illustrates how to apply the currency format to the 'Price' editor.

    
    [DataType(DataType.Currency), DisplayFormat(ApplyFormatInEditMode = true, NullDisplayText = "Value", DataFormatString = "C0", ConvertEmptyStringToNull = true)]
    public decimal Price { get; set; }
    

Refer to the Using Data Annotations to Customize Data Classes MSDN topic to learn more about data annotation attributes.

See Also