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

QueryableCollectionView

QueryableCollectionView enables а collection to have the functionalities of sorting, filtering, grouping, and paging.

This article descibes the features and provides examples on the QueryableCollectionView (QCV) usage.

The QCV requires an IEnumerable source for the data and it works with three major properties to enable sorting, filtering and grouping. The GroupDescriptors, FilterDescriptors, and SortDescriptors. For paging, check the Paging section of this article.

Defining and Using QueryableCollectionView

The following example shows a basic QueryableCollectionView definintion without any sorting, filtering, grouping or paging applied.

Defining a collection item model

public class DataInfo 
{ 
    public int Value { get; set; } 
    public string GroupKey { get; set; } 
} 

Defining QueryableCollectionView and populating it with data

public MainWindow() 
{      
    InitializeComponent(); 
    var source = new ObservableCollection<DataInfo>(); 
    for (int i = 0; i < 3; i++) 
    { 
        for (int k = 0; k < 3; k++) 
        { 
            source.Add(new DataInfo() { Value = k, GroupKey = "G" + i }); 
        } 
    } 
    var qcv = new QueryableCollectionView(source); 
    this.DataContext = qcv; 
} 

Defining RadGridView and consuming the collection view

<telerik:RadGridView ItemsSource="{Binding}"/> 

RadGridView populate with QueryableCollectionView

WPF RadGridView populate with QueryableCollectionView

Sorting

The SortDescriptors collection of the view allows you to define a set of SortDescriptor objects. The SortDescriptor class provides Member and SortDirection properties that are used to define the property name being used as the sorting criteria and the sort direction (ascending or descending).

Defining a SortDescriptor

var qcv = new QueryableCollectionView(source); 
qcv.SortDescriptors.Add(new SortDescriptor() { Member = "Value", SortDirection = ListSortDirection.Descending });             

RadGridView sorted with QueryableCollectionView SortDescriptors

WPF RadGridView sorted with QueryableCollectionView SortDescriptors

Generic sorting is supported too, using the SortDescriptor<TElement, TKey> class.

Using generic sort descriptor

var qcv = new QueryableCollectionView(source); 
qcv.SortDescriptors.Add(new SortDescriptor<DataInfo, int>()  
{ 
    SortingExpression = info => info.Value, 
    SortDirection = ListSortDirection.Descending  
}); 

Filtering

The FilterDescriptors collection of the view allows you to define a set of FilterDescriptor objects. The FilterDescriptor class provides Member, Operator, and Value properties that are used to define the filtering criteria.

Defining a FilterDescriptor

var qcv = new QueryableCollectionView(source); 
qcv.FilterDescriptors.Add(new FilterDescriptor() 
{ 
    Member = "Value", 
    Operator = FilterOperator.IsLessThanOrEqualTo, 
    Value = 1 
}); 

RadGridView filtered with QueryableCollectionView FilterDescriptors

WPF RadGridView filtered with QueryableCollectionView FilterDescriptors

Generic filtering is supported too, using the FilterDescriptor<Element> class.

Using generic filter descriptor

var qcv = new QueryableCollectionView(source); 
qcv.FilterDescriptors.Add(new FilterDescriptor<DataInfo>() 
{ 
    FilteringExpression = info => info.Value <= 1 
}); 

Grouping

The GroupDescriptors collection of the view allows you to define a set of GroupDescriptor objects. The GroupDescriptor class provides Member and SortDirection properties that are used to define the property name being used as the grouping criteria and the sort direction of the groups (ascending or descending).

Defining a GroupDescriptor

var qcv = new QueryableCollectionView(source); 
qcv.GroupDescriptors.Add(new GroupDescriptor() 
{ 
    Member = "GroupKey", 
    SortDirection = ListSortDirection.Descending 
}); 

RadGridView grouped with QueryableCollectionView GroupDescriptors

WPF RadGridView grouped with QueryableCollectionView GroupDescriptors

Generic grouping is supported too, using the GroupDescriptor<TElement, TKey, TSortingKey> class.

Using generic group descriptor

var qcv = new QueryableCollectionView(source); 
qcv.GroupDescriptors.Add(new GroupDescriptor<DataInfo, string, string>() 
{ 
    GroupingExpression = info => info.GroupKey, 
    SortDirection = ListSortDirection.Descending 
}); 

Paging

The QueryableCollectionView class provides an out-of-the-box ability to apply paging.

To make full use of the paging functionality, you can utilize the following API:

  • PageSize—Specifies the number of items to display on a page.
  • PageIndex—This property retrieves the index of the current page.
  • IsPageChanging—Property of type __bool_ that indicates if a page index change is in process.
  • CanChangePage—Specifies if the PageIndex value can change.
  • IsPaged—This property indicates whether paging is applied to the QueryableCollectionView instance.
  • ShouldRefreshOrDeferOnPageSizeChange—Indicates whether this instance should call the RefreshOrDefer method when the PageSize property changes. Its default value of true. This is a virtual property, which means that you can override it and set it to false in a new class that derives from QueryableCollectionView. Then, you can work with this new custom QueryableCollectionView collection.

The QueryableCollectionView exposes the following two events when it comes to the paging functionality:

  • PageChanging—This event occurs when the PageIndex property is changing. The event arguments are of the type PageChangingEventArgs, which provides information about the new page index. PageChangingEventArgs derives from the CancelEventArgs class and allows you to cancel the changing of the page index. To do so, set the Cancel property to true in the added handler for the PageChanging event.
  • PageChanged—This event will occur when the PageIndex property is changed. The event arguments are of the type EventArgs.

QueryableCollectionView provides several methods for moving through the pages. These methods target the general functionality that a paging API should have, which is moving to the first/last and to the next/previous page. This is achieved by utilizing the following methods:

  • MoveToFirstPage—Sets the first page as the current one. Returns a bool value that indicates if this operation was successful or not.
  • MoveToLastPage—Sets the last page as the current one. Returns a bool value that indicates if this operation was successful or not.
  • MoveToNextPage—Sets the next page as the current one. Returns a bool value that indicates if this operation was successful or not.
  • MoveToPreviousPage—Sets the previous page as the current one. Returns a bool value that indicates if this operation was successful or not.

Using QueryableCollectionView in XAML

QueryableCollectionViewSource is an abstraction of QueryableCollectionView that internally uses it. It allows you to take advantage of QueryableCollectionView and its features in XAML.

QueryableCollectionViewSource can be defined as a resource in XAML and allows you to provide it with a collection using its Source property. If the Source is an object of type QueryableCollectionView, the QueryableCollectionViewSource sync its descriptors directly with it. If the Source is another collection type, it is wrapped into a QueryableCollectionView which is used by the view source internally.

QueryableCollectionViewSource provides the same descriptor collections like QueryableCollectionView—GroupDescriptors, SortDescriptors, and FilterDescriptors. To access the underlying QueryableCollectionView object use the View property of the view source.

The following example shows how to setup basic view model and use QueryableCollectionViewSource with RadGridView.

Defining the view model

public class MainViewModel 
{ 
    public ObservableCollection<DataInfo> Items { get; set; } 
    public MainViewModel() 
    { 
        Items = new ObservableCollection<DataInfo>(); 
        for (int i = 0; i < 3; i++) 
        { 
            for (int k = 0; k < 3; k++) 
            { 
                Items.Add(new DataInfo() { Value = k, GroupKey = "G" + i  }); 
            } 
        } 
    } 
} 

See the first example from the beginning of this article for the definition of the DataInfo class.

Defining QueryableCollectionViewSource in XAML

<Window.Resources> 
    <local:MainViewModel x:Key="viewModel" /> 
    <telerik:QueryableCollectionViewSource x:Key="qcvSource" Source="{Binding Source={StaticResource viewModel}, Path=Items}"/> 
</Window.Resources> 

Consuming the QueryableCollectionViewSource's view in XAML

<telerik:RadGridView ItemsSource="{Binding Source={StaticResource qcvSource}, Path=View}" /> 

To use grouping, sorting, and filtering set the corresponding descriptors of the view source object.

Adding descriptors in XAML

<Window.Resources> 
    <local:MainViewModel x:Key="viewModel" /> 
    <telerik:QueryableCollectionViewSource x:Key="qcvSource" Source="{Binding Source={StaticResource viewModel}, Path=Items}"> 
        <telerik:QueryableCollectionViewSource.SortDescriptors> 
            <telerik:SortDescriptor Member="Value" SortDirection="Descending" /> 
        </telerik:QueryableCollectionViewSource.SortDescriptors> 
        <telerik:QueryableCollectionViewSource.GroupDescriptors> 
            <telerik:GroupDescriptor Member="GroupKey" SortDirection="Descending" /> 
        </telerik:QueryableCollectionViewSource.GroupDescriptors> 
        <telerik:QueryableCollectionViewSource.FilterDescriptors> 
            <telerik:FilterDescriptor Member="Value" Operator="IsLessThanOrEqualTo" Value="1"/> 
        </telerik:QueryableCollectionViewSource.FilterDescriptors> 
    </telerik:QueryableCollectionViewSource> 
</Window.Resources> 

RadGridView populated using QueryableCollectionViewSource

WPF RadGridView populated using QueryableCollectionViewSource

See Also

In this article