Continuiamo a parlare di DataBinding in WPF ed andiamo per gradi.
Abbiamo visto che è possibile bindare due controlli tra di loro utilizzando la proprietà ElementName della struttura di Binding. Iniziamo a vedere come è possibile bindare una lista di elementi in una listview.
Creiamo la listview
[code language="xml"]
<ListView ItemsSource="{StaticResource mySource}">
</ListView>
[/code]
Utilizzando “ItemsSource” informiamo la nostra ListView che deve utilizzare come sorgente dati, la risorsa statica mySource.
Per dichiarare la risorsa statica è sufficiente includere questo tag nel tag Window.Resources
[code language="xml"]
<Window.Resources>
<!-- Dichiarazione di una reference ad una classe scritta in c# -->
<local:mySource x:Key="mySource"/>
</Window.Resources>
[/code]
Attraverso questa definizione, la classe locale mySource verrà instanziata e resa disponibile a tutti gli oggetti all’interno della finestra che stiamo progettando come risorsa statica.
Dobbiamo dichiarare anche “local”. Local è un riferimento ad uno spazio dei nomi per WPF.
Includiamo quindi la definizione di local nel tag Window:
[code language="xml"]
xmlns:local="clr-namespace:miniSample1"
[/code]
Definiamo la classe mySource, creando una semplice classe C# in questo modo:
[code language="C#"]
public class mySource : ObservableCollection<string>
{
public mySource()
{
this.Add("Customer1");
this.Add("Customer1");
this.Add("Customer1");
this.Add("Customer1");
this.Add("Customer1");
}
}
[/code]
La nostra sorgente dati eredita da ObservableCollection, una classe base che ci mette a disposizione una serie di funzioni di ordinamento e raggruppamento per i nostri dati. Il dato sarà composto da una semplice stringa.
Abbiamo ottenuto una lista di stringhe all’interno di una listview e fin qui nulla di nuovo a parte la sintassi di WPF. Possiamo tuttavia modificare a piacimento il look dei nostri controlli e quindi possiamo rendere gradevole e leggermente più complessa la nostra lista.
Per cominciare aggiungiamo un po’ di dati, modificando la nostra sorgente dati, in modo da avere qualcosa in più da bindare.
[code language="C#"]
public class mySourceItem
{
private string _title = string.Empty;
private string _description = string.Empty;
public string Title
{
get
{ return _title; }
set
{ _title = value; }
}
public string Description
{
get
{ return _description; }
set
{ _description = value; }
}
public mySourceItem(string title, string description)
{
_title = title;
_description = description;
}
}
public class mySource : ObservableCollection<mySourceItem>
{
public mySource()
{
this.Add(new mySourceItem("Customer1", "Customer1 Description"));
this.Add(new mySourceItem("Customer2", "Customer2 Description"));
this.Add(new mySourceItem("Customer3", "Customer3 Description"));
this.Add(new mySourceItem("Customer4", "Customer4 Description"));
this.Add(new mySourceItem("Customer5", "Customer5 Description"));
}
}
[/code]
Abbiamo creato una DataEntity che contiene due proprietà. La sorgente dati sarà una collection di DataEntity. Se colleghiamo questa collection alla nostra listview otterremo soltanto un elenco di questo tipo: “minisample1.mySourceItem”. Questo accade perché listview non sa come estrarre i dati dalla nostra collection e quindi invoca in metodo ToString() di ogni singolo elemento. Dobbiamo quindi istruire la listview su come visualizzare il nostro elemento.
[code language="xml"]
<ListView ItemsSource="{StaticResource mySource}">
<!-- DataTemplate : Definiamo l'aspetto dei nostri dati -->
<ListView.ItemTemplate>
<DataTemplate>
<!-- Binding : Visualizziamo come contenuto l'intero oggetto {Binding} (La sorgente dati è una collection di stringhe ) -->
<TextBlock FontSize="24" FontFamily="Calibri" Text="{Binding Path=Title}" />
<TextBlock FontSize="24" FontFamily="Calibri" Text="{Binding Path=Description}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
[/code]
All’interno del tag DataTemplate definiamo come ogni singolo elemento deve essere visualizzato.
Definiamo il look dei nostri elementi con i normali tag WPF, in questo caso TextBlock, e definiamo dove ogni proprietà deve essere utilizzata attraverso la struttura {Binding Path=<proprietà>}.