QueryableCollectionView
QueryableCollectionView enables а collection to have the functionalities of sorting, filtering and grouping.
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.
Defining and Using QueryableCollectionView
The following example shows a basic QueryableCollectionView definintion without any sorting, filtering or grouping applied.
Example 1: Defining a collection item model
public class DataInfo
{
public int Value { get; set; }
public string GroupKey { get; set; }
}
Example 2: 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;
}
Example 3: Defining RadGridView and consuming the collection view
<telerik:RadGridView ItemsSource="{Binding}"/>
Figure 1: 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).
Example 4: Defining a SortDescriptor
var qcv = new QueryableCollectionView(source);
qcv.SortDescriptors.Add(new SortDescriptor() { Member = "Value", SortDirection = ListSortDirection.Descending });
Figure 2: RadGridView sorted with QueryableCollectionView SortDescriptors
Generic sorting is supported too, using the SortDescriptor<TElement, TKey>
class.
Example 5: 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.
Example 6: Defining a FilterDescriptor
var qcv = new QueryableCollectionView(source);
qcv.FilterDescriptors.Add(new FilterDescriptor()
{
Member = "Value",
Operator = FilterOperator.IsLessThanOrEqualTo,
Value = 1
});
Figure 3: RadGridView filtered with QueryableCollectionView FilterDescriptors
Generic filtering is supported too, using the FilterDescriptor<Element>
class.
Example 7: 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).
Example 8: Defining a GroupDescriptor
var qcv = new QueryableCollectionView(source);
qcv.GroupDescriptors.Add(new GroupDescriptor()
{
Member = "GroupKey",
SortDirection = ListSortDirection.Descending
});
Figure 4: RadGridView grouped with QueryableCollectionView GroupDescriptors
Generic grouping is supported too, using the GroupDescriptor<TElement, TKey, TSortingKey>
class.
Example 9: Using generic group descriptor
var qcv = new QueryableCollectionView(source);
qcv.GroupDescriptors.Add(new GroupDescriptor<DataInfo, string, string>()
{
GroupingExpression = info => info.GroupKey,
SortDirection = ListSortDirection.Descending
});
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.
Example 10: 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 Example 1 from the beginning of this article for the definition of the DataInfo class.
Example 11: 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>
Example 12: 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.
Example 13: 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>