Pages

Tuesday 26 July 2011

Filtering in MVVM architecture - Silverlight & WPF

Before you start implementing functionality for filtering data in MVVM architecture you have to find out which technologies you are going to use. There are two different ways how you can implement filtering in WPF but only one solution can be ported to Silverlight. The reason behind it is that Silverlight version of CollectionViewSource class does not support GetDefaultView method. The following example shows how you can filter data in MVVM architecture by changing the content of FilteringMethod predicate.


   1:  class MainWindowPresentationModel : INotifyPropertyChanged
   2:      {
   3:          ObservableCollection<string> _observableCollection = new ObservableCollection<string>() { "a", "bb", "ccc", "dddd", "eeeee", "ffffff", "eeeeeeee", "fffffffffffffff", "gggggggggggggggggg" };
   4:          private int _threshold = 100;
   5:          private ICollectionView _Items;
   6:          private CollectionViewSource _CollectionViewSourceItems;
   7:          public event PropertyChangedEventHandler PropertyChanged;
   8:   
   9:          public MainWindowPresentationModel(Window window)
  10:          {
  11:              FilterCommand = new RoutedCommand();
  12:              CommandBinding customCommandBinding = new CommandBinding(FilterCommand, HandleFilterCommand);
  13:              window.CommandBindings.Add(customCommandBinding);
  14:   
  15:              window.DataContext = this;
  16:              window.Show();
  17:   
  18:              Items = CollectionViewSource.GetDefaultView(_observableCollection);
  19:              Items.Filter = FilteringMethod;
  20:              Items.Refresh();
  21:   
  22:              CollectionViewSourceItems = new CollectionViewSource();
  23:              CollectionViewSourceItems.Source = _observableCollection;
  24:              CollectionViewSourceItems.View.Filter = FilteringMethod;
  25:              CollectionViewSourceItems.View.Refresh();
  26:          }
  27:   
  28:          public ICommand FilterCommand
  29:          {
  30:              get;
  31:              set;
  32:          }
  33:   
  34:          public ICollectionView Items
  35:          {
  36:              get { return _Items; }
  37:              set {
  38:                  _Items = value;
  39:                  OnPropertyChanged("Items");
  40:              }
  41:          }
  42:   
  43:          public CollectionViewSource CollectionViewSourceItems
  44:          {
  45:              get { return _CollectionViewSourceItems; }
  46:              set
  47:              {
  48:                  _CollectionViewSourceItems = value;
  49:                  OnPropertyChanged("CollectionViewSourceItems");
  50:              }
  51:          }
  52:   
  53:          private void HandleFilterCommand(object sender, ExecutedRoutedEventArgs e)
  54:          {
  55:              int result = 0;
  56:              if (int.TryParse(e.Parameter.ToString(), out result))
  57:              {
  58:                  _threshold = result;
  59:              }
  60:              Items.Refresh();
  61:              CollectionViewSourceItems.View.Refresh();
  62:          }
  63:   
  64:          public bool FilteringMethod(object input)
  65:          {
  66:              return _threshold == 0 ? true : ((string)input).Length < _threshold;
  67:          }
  68:   
  69:          private void OnPropertyChanged(string propertyName)
  70:          {
  71:              if (PropertyChanged != null)
  72:              {
  73:                  var localPropertyChanged = PropertyChanged;
  74:                  localPropertyChanged(this, new PropertyChangedEventArgs(propertyName));
  75:              }
  76:          }
  77:      }

1: <Window x:Class="WpfApplication1.MainWindow"
   2:          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:          Title="MainWindow" Height="350" Width="525">
   5:      <Grid>
   6:          <Grid.RowDefinitions>
   7:              <RowDefinition Height="Auto"/>
   8:              <RowDefinition Height="Auto"/>
   9:              <RowDefinition Height="*"/>
  10:              <RowDefinition Height="*"/>
  11:          </Grid.RowDefinitions>
  12:   
  13:          <Button Grid.Row="0" Content="Show items shorter than 5 characters" Command="{Binding FilterCommand}" CommandParameter="5" Height="30"/>
  14:          <Button Grid.Row="1" Content="Show all items" Command="{Binding FilterCommand}" CommandParameter="0"  Height="30"/>
  15:          <ListBox Grid.Row="2" ItemsSource="{Binding Items}"/>
  16:          <ListBox Grid.Row="3" ItemsSource="{Binding CollectionViewSourceItems.View}"/>
  17:      </Grid>
  18:  </Window>


   1:      public partial class App : Application
   2:      {
   3:          protected override void OnStartup(StartupEventArgs e)
   4:          {
   5:              base.OnStartup(e);
   6:   
   7:              MainWindow view = new MainWindow();
   8:              MainWindowPresentationModel model = new MainWindowPresentationModel(view);
   9:          }
  10:      }


   1:  <Application x:Class="WpfApplication1.App"
   2:               xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:               >
   5:      <Application.Resources>
   6:           
   7:      </Application.Resources>
   8:  </Application>

1 comment:

  1. Hi, nice code in Filtering in MVVM architecture.Thanks for your help....

    --Aparna
    Theosoft

    ReplyDelete