26

Jan

LongListSelector: qualche problemino con la proprietà SelectedItem

LongListSelector-JumpList

Conoscete il controllo LongListSelector? Si tratta di quel controllo presente nel Silverlight Toolkit che vi permette di raggruppare gli item di una collezione e avere una jump list che vi permette di saltare velocemente da una categoria all’altra. Un esempio di applicazione nativa che fa uso di questo controllo è l’hub People: i contatti sono raggruppati per iniziale e, con un tap, potete saltare direttamente da una lettera all’altra.

Ora che abbiamo focalizzato il contesto, veniamo al problema: esattamente come le ListBox tradizionali, il controllo espone una proprietà SelectedItem, che contiene l’oggetto correntemente selezionato. Come potete immaginare, si tratta di una proprietà fondamentale, dato che vi serve per gestire le interazioni dell’utente con la lista.

Per un motivo che ancora non sono riuscito a comprendere, la proprietà SelectedItem, al contrario di quanto avviene in tutti gli altri controlli standard di Silverlight, non è una dependency property. Questo significa che non potete metterla in binding con una proprietà: o meglio, potete farlo ma, al variare della proprietà, il controllo non si aggiornerà per riflettere il cambiamento. Il risultato sarà quindi che, soprattutto se state usando il pattern MVVM, non sarete in grado di usare correttamente il LongListSelector, data l’impossibilità di recuperare il valore della proprietà SelectedItem.

La soluzione è quella di trasformare noi stessi tale proprietà in una dependancy property, estendendo il LongListSelector. Vediamo come fare:

  • Aggiungiamo un nuovo item al nostro progetto di tipo Code File e diamogli un nome a piacimento (nel mio caso, l’ho chiamato LongListSelector.cs).
  • Incolliamo il seguente codice sorgente:
public class LongListSelector : Microsoft.Phone.Controls.LongListSelector
      {
      public LongListSelector()
      {
      SelectionChanged += LongListSelector_SelectionChanged;
      }

      void LongListSelector_SelectionChanged(object sender, SelectionChangedEventArgs e)
      {
      SelectedItem = base.SelectedItem;
      }

      public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem", typeof(object), typeof(LongListSelector),
      new PropertyMetadata(null, OnSelectedItemChanged));

      private static void OnSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
      {
      var selector = (LongListSelector)d;
      selector.SelectedItem = e.NewValue;
      }

      public new object SelectedItem
      {
      get { return GetValue(SelectedItemProperty); }
      set { SetValue(SelectedItemProperty, value); }
      }

Si tratta nè più nè meno che la sintassi standard di una dependancy property: in questo caso, ci agganciamo all’evento SelectionChanged per variare il valore della proprietà SelectedItem.

  • Ora siamo pronti per usare la nostra variante nella nostra applicazione: quello che dovremo fare, semplicemente, è far puntare il namespace del LongListSelector non più a quello standard del toolkit ma al nostro file che abbiamo creato. Nel nostro XAML, avremo dichiarato un namespace di questo tipo:
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"

e, di conseguenza, da qualche parte avremo inserito il controllo LongListSelector in questo modo:

Quello che dovremo fare sarà sostituire il namespace toolkit con il namespace che punta invece al nostro file LongListSelector.cs e il gioco è fatto! Adesso il binding funzionerà correttamente e potrete gestire la selezione di un item come siete abituati a fare con il controllo ListBox.

Qui sotto trovate il link per scaricare il file da aggiungere al vostro progetto.

by Il blog di Matteo Pagani on 1/26/2012
Post archive