The goal of this article is to show how to get the filtered items from a GridView (here we will use Telerik RadGridView, but it should be the same for any Grid).
This case is really useful if you need to apply some calculation on a filtered subset of the Data you’re displaying, while you’re still having access to the full collection for other calculations.
The View:
<Window x:Class="Telerik_FilteredGridValues_Collection.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" mc:Ignorable="d" Title="MainWindow" Height="600" Width="600"> <Grid> <StackPanel Orientation="Vertical"> <TextBlock Text="{Binding TextValue}" /> <telerik:RadGridView x:Name="grid" ItemsSource="{Binding FilteredItems2}"></telerik:RadGridView> <Button Content="Ok" Command="{Binding OkCommand}" Click="ButtonBase_OnClick" /> </StackPanel> </Grid> </Window>
The code-behind:
using System; using System.Collections.Generic; using System.Linq; using System.Windows; using Telerik_FilteredGridValues_Collection.ViewModel; namespace Telerik_FilteredGridValues_Collection { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); DataContext = new MainVM(); } private void ButtonBase_OnClick(object sender, RoutedEventArgs e) { //This works as well, but not MVVM... var test = grid.Items.Cast<Person>(); } } }
The View-Model:
using Microsoft.Practices.Prism.Mvvm; using System.Collections.ObjectModel; using System.Windows.Input; using Telerik.Windows.Data; namespace Telerik_FilteredGridValues_Collection.ViewModel { public class MainVM : BindableBase { private string _textValue; public string TextValue { get { return _textValue; } set { if (value != _textValue) { _textValue = value; OnPropertyChanged(() => TextValue); } } } private ObservableCollection<Person> _items; public ObservableCollection<Person> Items { get { return _items ?? (_items = new ObservableCollection<Person>()); } set { if (value != _items) { _items = value; OnPropertyChanged(() => Items); } } } //Doesn't work with Telerik !! //private ICollectionView _filteredItems; //public ICollectionView FilteredItems //{ // get { return _filteredItems; } // set { _filteredItems = value; } //} //Works with Telerik !! private QueryableCollectionView _filteredItems2; public QueryableCollectionView FilteredItems2 { get { return _filteredItems2; } set { _filteredItems2 = value; } } private ICommand _okCommand; public ICommand OkCommand { get { return _okCommand ?? (_okCommand = new Microsoft.Practices.Prism.Commands.DelegateCommand(OkPressed)); } } public MainVM() { TextValue = "This is a test of Filtered Values in a Telerik GridView."; Items.Add(new Person { Name = "Steeve", Age = 33 }); Items.Add(new Person { Name = "Claire", Age = 37 }); Items.Add(new Person { Name = "Jimmy", Age = 32 }); Items.Add(new Person { Name = "Pascal", Age = 52 }); //Doesn't work with Telerik ! //FilteredItems = CollectionViewSource.GetDefaultView(Items); //Works with Telerik! FilteredItems2 = new QueryableCollectionView(Items); } private void OkPressed() { foreach (var filteredItem in FilteredItems2) { //Here we have our filtered items from the Grid } } } public class Person { public string Name { get; set; } public int Age { get; set; } } }
BindableBase is part of the NuGet package Prism.MVVM. It’s simply an implementation of INotifyPropertyChanged.
The concept is to get a “View” of the represented Data on screen.
So as you can see in this code, ICollectionView (System.ComponentModel which could be a ListCollectionView for example) should work with any Grid, but it seems that the Telerik controls can have some issues. But they work perfectly with a QueryableCollectionView (from Telerik.Windows.Data).
Happy coding!