Filtrare una collezione con CollectionViewSource in Silverlight 4.0

di Alessio Leoncini, in Silverlight 4.0,

In alcuni script precedenti abbiamo visto come l'engine di data binding di Silverlight sia molto flessibile e comodo nella gestione dei dati.
Per semplificare maggiormente la gestione delle collezioni di dati sul client è stata introdotta la classe CollectionViewSource che ci permette di gestire i dati in binding con i controlli, senza la necessità di modificare la collezione di dati originali.

Per utilizzare la classe CollectionViewSource è sufficiente assegnare la collezione di dati alla proprietà Source: automaticamente viene valorizzata la proprietà View con un oggetto di tipo ICollectionView che possiamo utilizzare come sorgente dati per un ItemsControl.

Grazie ad ICollectionView abbiamo a disposizione una serie di funzionalità come la navigazione tra i dati, la sincronia tra elemento corrente della collezione ed elemento selezionato di un ItemsControl, la paginazione (lato client ovviamente), il raggruppamento, l'ordinamento ed il filtro dei dati.

Possiamo utilizzare l'oggetto direttamente da markup:

<UserControl.Resources>
  <local:Cars x:Key="cars" />

  <CollectionViewSource Source="{Binding Source={StaticResource cars}}"
                        x:Key="carsVs"
                        Filter="CollectionViewSource_Filter">
  </CollectionViewSource>
</UserControl.Resources>
<StackPanel>
  <TextBox x:Name="txb1"
            TextChanged="TextBox_TextChanged" />
  <ListBox ItemsSource="{Binding Source={StaticResource carsVs}}"
            DisplayMemberPath="Name" />
</StackPanel>

Nel codice di esempio rendiamo disponibile la collezione sorgente come risorsa dello UserControl, la collezione Cars; di seguito definiamo la CollectionViewSource in cui specifichiamo come Source la collezione Cars come risorsa statica stessa. Già con questo semplice codice possiamo già utilizzare la CollectionViewSource ed associarla nell'espressione di binding del ListBox sottostante.

Per sfruttare ciò che CollectionViewSource può darci in più andiamo a gestirne l'evento Filter nel code behind, ed inseriamo una TextBox con un metodo gestore dell'evento TextChanged: durante l'inserimento dei caratteri vogliamo che nella ListBox vengano visualizzati solo gli elementi il cui nome inizia per la lettera digitata. Ecco il codice dell'evento Filter:

private void CollectionViewSource_Filter(object sender, System.Windows.Data.FilterEventArgs e)
{
  if (txb1 != null)
  {
    Car item = e.Item as Car;
    if (item.Name.StartsWith(txb1.Text))
    {
      e.Accepted = true;
    }
    else
    {
      e.Accepted = false;
    }
  }
}

L'evento viene scatenato alla modifica della sorgente dati e viene eseguito per ogni elemento della collezione: nel codice è sufficiente definire ciò che rispetta o meno la regola di filtro valorizzando opportunamente la proprietà Accepted.
Infine, per scatenare la rivalutazione della collezione, è sufficiente chiamare il metodo Refresh di View nel metodo gestore dell'evento TextChanged:

private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
  CollectionViewSource carsVs = this.Resources["carsVs"] as CollectionViewSource;
  carsVs.View.Refresh();
}

Con questo semplice codice abbiamo aggiunto la funzionalità di filtro lato client ad una lista.



Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi