Binding for Dummies (ep. 3)

Nei primi due episodi di Binding for Dummies (ep. 1 ed ep. 2) abbiamo visto cosa è il binding, come implementarlo e come far si che le modifiche al nostro modello ad oggetti vengano riportate in modo automatico all’interfaccia grafica tramite l’implementazione dell’interfaccia INotifyPropertyChanged.

Passiamo ora a vedere come implementare il binding quando si tratta di collezioni di oggetti. Se fino ad ora questo approccio non vi ha convinto (perché in effetti aumenta il livello di complicazione generale) da adesso non potrete più farne a meno.

Ipotizziamo di avere una lista di oggetti da visualizzare nella UI. Senza il binding avreste dovuto aggiungere n ListBoxItem e valorizzarli da XAML uno per uno. Ma in questo modo dovreste conoscere in anticipo il numero di elementi della lista. Inoltre dovreste replicare il layout di ogni singolo elemento (immaginate ad un elemento complesso che abbia una immagine, un titolo e una descrizione) e scrivere due volte lo stesso codice è sempre un errore. Oppure avreste potuto dare un nome ad ogni elemento della lista (ogni immagine, ogni titolo, ecc.) e valorizzarli dal code behind all’interno di un ciclo for each della vostra lista. Oppure da codice avreste potuto, per ogni elemento della vostra lista, creare un ListBoxItem con tutte le sue proprietà (immagine, testo, ecc.) ed aggiungerlo alla ListBox. Non vedremo nessuna di queste cose perché portano via davvero molto tempo, ma potreste esercitarvi con tutte queste ipotesi perché si impara sempre qualcosa.

Invece vediamo direttamente come il binding si preoccupi di tutto. Tutto quello che dovete fare è creare la vostra lista, indicarla come ItemSource della ListBox ed infine definire il template del singolo elemento. Vediamo come, partendo da un semplice caso.

Creiamo una lista di stringhe nel nostro modello ad oggetti
public List<string> lista {get; set;}
Nel costruttore della classe stanziamo la lista e riempiamola di tre elementi
public Data ()
{
this.lista = new List<string> { “elemento 1”, “elemento 2”, “elemento 3” };
}
Il DataSource del contenitore padre (in questo caso ContentPanel) deve essere già bindato al nostro modello ad oggetti
ContentPanel.DataContext = data;
A questo punto nello XAML della ListBox valorizziamo la proprietà ItemsSource, che indica la sorgente degli elementi della ListBox
<ListBox ItemsSource=”{Binding lista}”>
La ListBox creerà automaticamente un ListBoxItem per ogni elemento della nostra lista ed ognuno di questi elementi avrà il layout indicato dalla proprietà DataTemplate dell’ItemTemplate in questo modo
<ListBox ItemsSource=”{Binding lista}”>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text=”{Binding}”/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
In questo caso il Template è molto semplice e nel binding non viene indicato nessun campo perché è tutto l’oggetto stringa ad essere bindato al Text della TextBlock.

E se avessimo una lista di oggetti custom? Creiamo una classe CustomObject
class CustomObject
{
public string Name { get; set; }
public string Description { get; set; }
public string Colore { get; set; }
public int Numero { get; set; }
}
e riempiamola nel costruttore
this.listaOggetti = new List<CustomObject>
{
new CustomObject{Name = “Nome 1”, Colore= “red”, Description = “kjsahdfasbhdfòlahòs”, Numero = 1},
new CustomObject{Name = “Nome 2”, Colore= “blue”, Description = “kjsahdfasbhdfòlahòs”, Numero = 2},
new CustomObject{Name = “Nome 3”, Colore= “green”, Description = “kjsahdfasbhdfòlahòs”, Numero = 3},
new CustomObject{Name = “Nome 4”, Colore= “orange”, Description = “kjsahdfasbhdfòlahòs”, Numero = 4},
new CustomObject{Name = “Nome 5”, Colore= “yellow”, Description = “kjsahdfasbhdfòlahòs”, Numero = 5}
            };
Possiamo a questo punto decidere cosa bindare alla TextBlock dell’ItemTemplate, per esempio Name
<ListBox ItemsSource=”{Binding listaOggetti}”>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text=”{Binding Name}”/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

Oppure possiamo creare un template più complesso
<ListBox ItemsSource=”{Binding listaOggetti}”>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation=”Horizontal”>
<Rectangle Height=”50″ Width=”100″ Fill=”{Binding Colore}” />
<StackPanel>
<TextBlock Text=”{Binding Name}” FontSize=”24″/>
<TextBlock Text=”{Binding Description}” FontSize=”18″/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
dove abbiamo bindato non solo le proprietà del testo, ma anche il colore. Potete mettere i binding tutte le proprietà dei vostri oggetti grafici, ed adattarli al vostro contenuto. E potete selezionare quali proprietà dei vostri oggetti custom mettere in binding.

Ma soprattutto potete cambiare l’interfaccia in modo semplice oppure definire due interfacce diverse da mostrare in alternativa (una vista con molti dettagli e una vista con solo i thumbnails per esempio).

Come al solito, trovate il codice di questo episodio qui http://1drv.ms/1hk5jE9.

Nel prossimo episodio vedremo che esiste una lista particolare (ObservableCollection) che implementa l’interfaccia INotifyPropertyChanged e che permette di riflettere i cambiamenti del vostro modello ad oggetti anche operando sulle liste.

Annunci

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...