Possiamo definire il DataTemplate come la fusione di due concetti: Data Binding e Control Template. Grazie a questa funzionalità possiamo definire un Template per rappresentare graficamente gli elementi della fonte dati. Solo i Content e gli Items Control supportano questa modalità di Templating.
Per capire meglio il concetto facciamo un piccolo esempio modificando il primo frammento di codice XAML della lezione precedente, definendo un Data Template che indica come sarà visualizzato il contenuto della proprietà Content
.
<StackPanel x:Name="LayoutRoot"> <TextBlock Text="{Binding Name}" /> <Button Content="{Binding}"> <Button.ContentTemplate> <DataTemplate> <TextBox Text="{Binding CurrentDriver}" /> </DataTemplate> </Button.ContentTemplate> </Button> </StackPanel>
Il risultato sarà il seguente:
I template sono una delle caratteristiche più potenti di Silverlight che rendono questo framework veramente versatile. Procediamo con un altro esempio più articolato. Partiamo dal codice finale della lezione precedente ed estendiamo la classe Team
aggiungendo una proprietà per l'immagine.
public class Team : INotifyPropertyChanged { private string name = String.Empty; public string Name { get { ... } set { ... }} private string currentDriver = String.Empty; public string CurrentDriver { get { ... } set { ... } } private string imageUrl = String.Empty; public string ImageUrl { get { return imageUrl; } set { imageUrl = value; RaisePropertyChanged("ImageUrl"); } } ... public static ObservableCollection<Team> GetAll() { return new ObservableCollection<Team> { new Team { Name = "Citroen Total World Rally Team", CurrentDriver = "Sebastian Loeb", ImageUrl = "citroen_image.jpg" }, new Team { Name = "BP Ford Abu Dhabi World Rally Team", CurrentDriver = "Mikko Hirvonen", ImageUrl = "ford_image.jpg" } }; } }
Procediamo modificando, sempre in maniera dichiarativa, la rappresentazione di ogni elemento Team
all'interno della ListBox
. Perciò definiamo un apposito DataTemplate
come valore della proprietà ItemTemplate
.
<StackPanel x:Name="LayoutRoot"> <ListBox Margin="10" ItemsSource="{Binding}"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <Image Source="{Binding ImageUrl}" Height="200" Width="200" /> <StackPanel Margin="10"> <TextBlock Text="{Binding Name}" FontFamily="Verdana" FontSize="30" /> <TextBlock Text="{Binding CurrentCar}" FontFamily="Verdana" FontSize="20" /> <TextBlock Text="{Binding CurrentDriver}" FontFamily="Verdana" FontSize="20" /> </StackPanel> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> <Button .../> <Button ... /> </StackPanel>
Per completezza dobbiamo impostare la proprietà ImageUrl
anche per l'istanza di Team aggiunta a run-time, quindi modifichiamo il metodo btnAdd_Click
come mostrato di seguito.
private void btnAdd_Click(object sender, RoutedEventArgs e) { var newteam = new Team { Name = "HTML.IT Team", CurrentDriver = "Matteo Baglini", ImageUrl = "logo_html_it.png" }; teams.Add(newteam); }
Eseguiamo l'applicazione, il risultato sarà simile al seguente.
Cliccando entrambi i bottoni l'interfaccia utente verrà aggiornata e risulterà simile alla seguente: