This article has been localized into Italian by the community.
Il controllo ItemControl
WPF ha un ampio range di controlli utilizzabili per visualizzare una lista di dati. Son disponibili in diverse forme e moduli e possono variare in complessità e in base a quanto lavoro possono svolgere. La variante più semplice è l'ItemControl, il quale è piuttosto un markup a loop di quanto è necessario applicare a tutti gli stili e template, ma in molti casi è quanto necessario.
Un semplice esempio di ItemsControl
Iniziamo con un semplice esempio, dove riempiamo il controllo ItemControl con un insieme di elementi. Questo dovrebbe mostrarci la semplicità dell'ItemControl:
<Window x:Class="WpfTutorialSamples.ItemsControl.ItemsControlSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib"
Title="ItemsControlSample" Height="150" Width="200">
<Grid Margin="10">
<ItemsControl>
<system:String>ItemsControl Item #1</system:String>
<system:String>ItemsControl Item #2</system:String>
<system:String>ItemsControl Item #3</system:String>
<system:String>ItemsControl Item #4</system:String>
<system:String>ItemsControl Item #5</system:String>
</ItemsControl>
</Grid>
</Window>
Come si può notare, non c'è nulla che mostri come utilizzare il controllo per ripetere gli elementi, invece di inserire manualmente, ad esempio 5 controlli TextBlock - l'ItemsControl di base è completamente privo di formattazione.Se si clicca su uno degli elementi, non appare niente, perchè non c'è alcun concetto legato all'elemento selezionato.
Collegare i dati con l'ItemsControl
Naturalmente l'ItemControl non è inteso da essere utilizzato con gli elementi definiti in configurazione, come già detto nel primo esempio. Come molti altri cotnrolli in WPF, l'ItemControl è pensato per il collegamento dinamico con i dati, dove si utilizza un template per definire tramite il codice grazie a classi possa essere rappresentato all'utente.
Per dimostrare questo, è stato preparato un esempio dove si vuole mostrare una TODO list all'utente, per visualizzare al programmatore quanto il tutto sia flessibile una volta definiti in nostri personali template. E' stato utilizzato il controllo ProgressBar per mostrare la percentuale corrente di completamento. Di seguito, prima del codice, poi un'immagine e infine una spiegazione di tutto questo:
<Window x:Class="WpfTutorialSamples.ItemsControl.ItemsControlDataBindingSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ItemsControlDataBindingSample" Height="150" Width="300">
<Grid Margin="10">
<ItemsControl Name="icTodoList">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="0,0,0,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Title}" />
<ProgressBar Grid.Column="1" Minimum="0" Maximum="100" Value="{Binding Completion}" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window>
using System;
using System.Windows;
using System.Collections.Generic;
namespace WpfTutorialSamples.ItemsControl
{
public partial class ItemsControlDataBindingSample : Window
{
public ItemsControlDataBindingSample()
{
InitializeComponent();
List<TodoItem> items = new List<TodoItem>();
items.Add(new TodoItem() { Title = "Complete this WPF tutorial", Completion = 45 });
items.Add(new TodoItem() { Title = "Learn C#", Completion = 80 });
items.Add(new TodoItem() { Title = "Wash the car", Completion = 0 });
icTodoList.ItemsSource = items;
}
}
public class TodoItem
{
public string Title { get; set; }
public int Completion { get; set; }
}
}
La parte più importante di quest'esempio è il template che abbiamo specificato dentro il controllo ItemsControl, usando un tag DataTemplate, dentro il controllo ItemsControl.ItemTemplate. Abbiamo aggiunto una Grid, per creare due colonne: nella prima abbiamo un TextBlock che mostrerà il titolo dell'elemento TODO, e nella seconda colonna, abbiamo un controllo di tipo ProgressBar, il cui valore è legato alla proprietà Completion.
Il template ora rappresenta un elemento TodoItem, che dichiariamo nel file del codice, dove ne istanziamo anche un numero che verranno aggiunti alla lista. Alla fine la lista è assegnata alla proprietà ItemsSource per l'ItemsControl, che svolgerà il resto del lavoro per noi. Ciascun elemento nella lista è mostrato utilizzando il template, così come si può vedere dall'immagine.
La proprietà ItemsPanelTemplate
Negli esempi sopra illustrati, tutti gli elementi sono organizzati da sopra a sotto, con ciascun elemento che occupa un'intera riga. Questo accade perchè l'ItemsControl gestice di default, tutti gli elementi in un StackPanel allineato verticalmente. E' molto semplice cambiare questa configurazione, dal momento che l'ItemsControl consente di cambiare il tipo di panel da utilizzare per mostrare i tutti gli elementi. Di seguito un esempio:
<Window x:Class="WpfTutorialSamples.ItemsControl.ItemsControlPanelSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib"
Title="ItemsControlPanelSample" Height="150" Width="250">
<Grid Margin="10">
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding}" Margin="0,0,5,5" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<system:String>Item #1</system:String>
<system:String>Item #2</system:String>
<system:String>Item #3</system:String>
<system:String>Item #4</system:String>
<system:String>Item #5</system:String>
</ItemsControl>
</Grid>
</Window>
Abbiamo specificato che l'ItemsControl dovrebbe usare un WrapPanel come template, dichiarandone uno nella proprietà ItemsPanelTemplate e per divertimento, abbiamo convertito l'ItemTemplate in modo che le stringhe diventino dei pulsanti. Si può usare qualunque tipo di pannello WPF, ma alcuni son più utili di altri.
Un altro buon esempio è il panel UniformGrid, dove si può definire un numero di colonne, in modo da avere i vari elementi mostrati ordinatamente in colonne di uguale larghezza:
<Window x:Class="WpfTutorialSamples.ItemsControl.ItemsControlPanelSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib"
Title="ItemsControlPanelSample" Height="150" Width="250">
<Grid Margin="10">
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="2" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding}" Margin="0,0,5,5" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<system:String>Item #1</system:String>
<system:String>Item #2</system:String>
<system:String>Item #3</system:String>
<system:String>Item #4</system:String>
<system:String>Item #5</system:String>
</ItemsControl>
</Grid>
</Window>
ItemsControl con barre scorrevoli
Una volta iniziato a utlizzare i controlli ItemsControl, è facile occorrere in un frequente problema: di default, l'ItemsControl non ha barre scorrevoli, e questo significa che se il contenuto non può essere contenuto, viene tagliato. Questo può essere visto prendendo il primo esempio da questo articolo e ridimensionando la finestra:
WPF consente però facilmente di risolverlo facilmente. Ci sono diverse possibili soluzioni, per esempio si può alterare il template usato dall'ItemsControl per includere un controllo ScrollViewer, ma la soluzione più semplice è semplicemente includere un ScrollViewer attorno all'ItemsControl. Di seguito un esempio:
<Window x:Class="WpfTutorialSamples.ItemsControl.ItemsControlSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib"
Title="ItemsControlSample" Height="150" Width="200">
<Grid Margin="10">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<ItemsControl>
<system:String>ItemsControl Item #1</system:String>
<system:String>ItemsControl Item #2</system:String>
<system:String>ItemsControl Item #3</system:String>
<system:String>ItemsControl Item #4</system:String>
<system:String>ItemsControl Item #5</system:String>
</ItemsControl>
</ScrollViewer>
</Grid>
</Window>
Si è impostato l'opzione di visibilità in Auto, in modo da renderle visibili solo quando necessarie. Come si può vedere dall'immagine, ora si può scorrere l'intero elenco di elementi.
Riassumendo
L'ItemsControl è utile quando si vuole un controllo completo di come i dati devono essere visualizzati, e quando non serve che il contenuto sia selezionabile. Se si vuole che l'utente possa selezionare gli elementi dell'elenco, sarebbe meglio utilizzare uno degli altri controlli, per esempio ListBox o ListView. Saranno descritti nei prossimi capitoli.