Coding4Fun: una nuova libreria di Microsoft per lo sviluppo di applicazioni per Windows Phone 7 – Parte 1: i controlli (2° parte)
Posted by qmatteoq in Windows Phone Tutorials on Friday 04 February 2011 at 10:00 AM
Riprendiamo la carrellata dei controlli disponibili nella libreria per Windows Phone 7 targata Coding4Fun iniziata nel post precente.
RoundButton e RoundToggleButton
Raggruppo questi due controlli in unico paragrafo, dato che sono praticamente identici, solo con due funzioni diverse. Si tratta infatti due semplici pulsanti, con un layout “arrotondato” che li rende simili ai pulsanti che vengono inseriti all’interno di una ApplicationBar. La differenza è che RoundButton è un pulsante tradizionale, mentre RoundToggleButton può essere utilizzato al posto del controllo CheckBox per dare la possibilità di selezionare più elementi.
Vediamo un esempio di XAML in cui sono inseriti entrambi i tipi di controlli:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel>
<TextBlock Text="Round Buttons"></TextBlock>
<StackPanel Orientation="Horizontal" Margin="0, 20, 0, 40">
<controls:RoundButton Content="Button 1" x:Name="button1" Click="button1_Click" ImagePath="/Images/appbar.check.rest.png"></controls:RoundButton>
<controls:RoundButton Content="Button 2" x:Name="button2" Click="button2_Click" ImagePath="/Images/appbar.check.rest.png"></controls:RoundButton>
</StackPanel>
<TextBlock Text="Round Toggle Buttons"></TextBlock>
<StackPanel Orientation="Horizontal" Margin="0, 20, 0, 20">
<controls:RoundToggleButton Content="Toggle Button 1" x:Name="ToggleButton1" ImagePath="/Images/appbar.check.rest.png"></controls:RoundToggleButton>
<controls:RoundToggleButton Content="Toggle Button 2" x:Name="ToggleButton2" ImagePath="/Images/appbar.check.rest.png"></controls:RoundToggleButton>
</StackPanel>
<Button Content="Click me" x:Name="ClickMe" Click="ClickMe_Click"></Button>
</StackPanel>
</Grid>
Come vedete, i due controlli si comportano esattamente come dei normali bottoni. La differenza è che:
- ai RoundButton abbiamo associato due eventi Click, dato che il loro scopo è quello di essere utilizzati come dei pulsanti tradizionali.
- anche i RoundToggleButton espongono l’evento Click, che però in questo caso non abbiamo usato. Come detto in precedenza, questo controllo può essere usato al posto dei checkbox, dato che consente una selezione multipla. Come vedremo tra poco, sfrutteremo perciò nel code behind questa caratteristica per determinare, tramite la pressione del pulsante ClickMe, quali bottoni sono stati selezionati.
Una cosa interessante è che entrambi i controlli supportano la proprietà ImagePath, che permette di impostare una immagine da visualizzare all’interno del pulsante. Ovviamente, è importante selezionare una immagine adatta allo scopo, che possa essere contenuta all’interno del pulsante.
Ecco il code behind:
public partial class RoundButton : PhoneApplicationPage
{
public RoundButton()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Button 1 clicked", "Coding 4 Fun", MessageBoxButton.OK);
}
private void button2_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Button 2 clicked", "Coding 4 Fun", MessageBoxButton.OK);
}
private void ClickMe_Click(object sender, RoutedEventArgs e)
{
if (ToggleButton1.IsChecked == true && ToggleButton2.IsChecked == true)
MessageBox.Show("Both buttons are checked", "Coding 4 Fun", MessageBoxButton.OK);
else if (ToggleButton1.IsChecked == true)
MessageBox.Show("Toggle Button 1 is checked", "Coding 4 Fun", MessageBoxButton.OK);
else if (ToggleButton2.IsChecked == true)
MessageBox.Show("Toggle Button 2 is checked", "Coding 4 Fun", MessageBoxButton.OK);
}
}
Anche qui il codice è molto semplice:
- Ai due RoundButton abbiamo associato due eventi che, al click, mostrano un MessageBox.
- Alla pressione del pulsante ClickMe abbiamo associato un evento che verifica se i RoundToggleButton sono selezionati o meno tramite la proprietà IsChecked e mostra un MessageBox diverso a seconda del contesto.
Quando usare questi controlli? RoundButton può andare a sostiture un Button nel caso in cui abbiamo bisogno di inserire diversi pulsanti all’interno di una stessa view e non abbiamo molto spazio. E’ fondamentale però che le etichette siano brevi, altrimenti il risultato finale non sarà molto gradevole. I RoundToggleButton invece possono essere utilizzati, ad esempio, in una pagina di Settings, al posto dei checkbox o del controllo ToggleSwitch presente nel Silverlight Toolkit.
MemoryCounter
Se ricordate il mio post dedicato a come recuperare alcune informazioni sul device da codice, esiste un modo per tenere sotto controllo la memoria in uso, grazie a due parametri che ci vengono messi a disposizione: uno che ci restituisce la memoria correntemente utilizzata e uno invece la memoria massima utilizzata dall’applicazione nel suo ciclo di vita.
Questo controllo non fa altro che visualizzare questi due valori nella vostra applicazione in automatico, senza che sia necessario da parte vostra scrivere una riga di codice. Se ricordate, infatti, nell’esempio mostrato nel post avevamo instanziato uno SchedulerTimer per far si che il quantitativo di memoria utilizzato venisse aggiornato ogni secondo. Questo controllo si occupa in automatico di gestire questo aspetto, mostrandovi in tempo reale lo stato della memoria.
Inserire il controllo nello XAML è molto semplice:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel>
<StackPanel Orientation="Horizontal">
<Button Content="Add memory" x:Name="AddMemory" Click="AddMemory_Click"></Button>
<Button Content="Remove memory" x:Name="RemoveMemory" Click="RemoveMemory_Click"></Button>
</StackPanel>
<controls:MemoryCounter></controls:MemoryCounter>
</StackPanel>
</Grid>
Come vedete, basta inserire un controllo di tipo MemoryCounter, il quale mostrerà in automatico due valori: il primo rappresenta la memoria in uso, il secondo la memoria massima utilizzata. Gli altri due pulsanti sono stati inseriti per darvi la possibilità di vedere il controllo in azione in tempo reale. Vediamo il code behind:
public partial class MemoryView : PhoneApplicationPage
{
List<Byte[]> _memory = new List<Byte[]>();
public MemoryView()
{
InitializeComponent();
}
private void AddMemory_Click(object sender, RoutedEventArgs e)
{
_memory.Add(new Byte[1024 * 1024]);
}
private void RemoveMemory_Click(object sender, RoutedEventArgs e)
{
if (_memory.Count > 0)
_memory.RemoveAt(_memory.Count - 1);
GC.Collect();
}
Quando la pagina viene istanziata creiamo una List di byte array: alla pressione del pulsante Add Memory, aggiungiamo alla collezione un byte array della dimensione di 1 MB. Quando premiamo il pulsante Remove memory, invece, eliminiamo l’ultimo oggetto inserito nella lista e forziamo il Garbage Collector ad entrare in azione, liberando perciò 1 MB dalla memoria.
Questo controllo non è pensato per gli utenti, ma per gli sviluppatori: non nasce per essere inserito in bella vista all’interno delle nostre applicazioni, ma per uso interno degli sviluppatori per valutare l’utilizzo di memoria e debuggare eventuali anomalie. Vi ricordo infatti che le guidelines impongono delle norme ben precise per quanto riguarda il consumo di memoria, che non può superare i 90 MB su device con meno di 512 MB di RAM.
TimeSpanPicker
Se ricordate, il Silverlight Toolkit ha introdotto due controlli, DatePicker e TimePicker, per consentire la selezione di date e ore all’interno della nostra applicazione. TimeSpanPicker è un controllo derivato da questi due che vi da la possibilità di selezionare un intervallo di tempo: risulta molto utile se, ad esempio, dovete implementare nella vostra applicazione un timer la cui durata deve essere selezionabile dall’utente. Nella mia applicazione Speaker Timer ho utilizzato proprio questo controllo per consentire la selezione della durata prevista per la sessione.
Il suo utilizzo è lo stesso dei controlli TimePicker e DatePicker che vi ho spiegato in questo post: l’unica differenza è che il valore ritornato non è un DateTime ma un TimeSpan (che rappresenta per l’appunto un intervallo temporale). Vediamo ora una semplice applicazione con un pulsante che, quando premuto, mostra in un MessageBox il valore impostato nel TimeSpanPicker.
Attenzione! Per poter utilizzare questo controllo, il namespace da dichiarare è diverso da quello che contiene tutti gli altri controlli, ovvero:
xmlns:controls="clr-namespace:Coding4Fun.Phone.Controls.Toolkit;assembly=Coding4Fun.Phone.Controls.Toolkit"
Ecco lo XAML:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel>
<controls:TimeSpanPicker x:Name="TimePicker"></controls:TimeSpanPicker>
<Button Content="Show Timespan" x:Name="ShowTimespan" Click="ShowTimespan_Click"></Button>
</StackPanel>
</Grid>
Ecco invece il code behind:
public partial class TimeSpanPickerView : PhoneApplicationPage
{
public TimeSpanPickerView()
{
InitializeComponent();
}
private void ShowTimespan_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show(TimePicker.Value.Value.ToString(), "Coding 4 Fun", MessageBoxButton.OK);
}
}
Come vedete, non facciamo altre che recuperare tramite l’attributo Value (che è un Nullable TimeSpan, ovvero un TimeSpan che può assumare valore null) il valore selezionato nel controllo e mostrarlo a video sfruttando un MessageBox.
PerformanceProgressBar
La ProgressBar, come ben sappiamo, è uno dei controlli nativi di Silverlight che viene utilizzato per notificare all’utente che la nostra applicazione sta caricando dei dati. La ProgressBar può operare in modalità “tradizionale” o “indeterminate”. Nel primo caso, la barra mostra lo stato di avanzamento del caricamento: quando è piena, vuol dire che il caricamento è completato. Questa modalità viene utilizzata quando stiamo caricando dei dati e siamo in grado di stabilirne la dimensione e lo stato di avanzamento preciso. La modalità indeterminate invece viene utilizzata quando non siamo in grado di fare questa stima, ma vogliamo limitarci ad avvisare l’utente che stiamo caricando qualcosa. Questa modalità è ampiamente usata in tutte le applicazioni native del telefono: quando vediamo dei puntini spostarsi dal lato sinistro a quello destro dello schermo per poi sparire stiamo guardando una ProgressBar la cui proprietà IsIndeterminate è a true.
La PerformanceProgressBar è una variante della ProgressBar che si comporta esattamente allo stesso modo, solo che offre performance nettamente migliori della ProgressBar standard quando viene utilizzata la modalità Indeterminate: questo perchè tale variante utilizza dei thread separati per gestire e renderizzare l’animazione, al contrario di quella standard che fa uso dello stesso thread che gestisce la UI (bloccando quindi gli altri controlli che vogliono interagire con la UI fino a che questa è in funzione).
Riguardo al suo utilizzo non c’è molto da dire, dato che si utilizza esattamente come una ProgressBar, in quanto sono esposte le stesse proprietà e gli stessi eventi. Ecco un esempio di semplice applicazione che attiva e disattiva la visualizzazione di una PerformanceProgressBar tramite la pressione di due pulsanti.
Ecco lo XAML:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel>
<controls:PerformanceProgressBar x:Name="ProgressBar"></controls:PerformanceProgressBar>
<StackPanel Orientation="Horizontal" Margin="0, 30, 0, 0" HorizontalAlignment="Center">
<Button Content="Start" x:Name="Start" Click="Start_Click"></Button>
<Button Content="Stop" x:Name="Stop" Click="Stop_Click"></Button>
</StackPanel>
</StackPanel>
</Grid>
Ed ecco il code behind:
public partial class PerformanceProgressBarView : PhoneApplicationPage
{
public PerformanceProgressBarView()
{
InitializeComponent();
}
private void Start_Click(object sender, RoutedEventArgs e)
{
ProgressBar.IsIndeterminate = true;
}
private void Stop_Click(object sender, RoutedEventArgs e)
{
ProgressBar.IsIndeterminate = false;
}
}
Come vedete, quello che andiamo a fare è semplicemente agire sulla proprietà IsIndeterminate del controllo, impostandola a true quando vogliamo visualizzarlo o a false quando vogliamo nasconderlo.
Attenzione! Solitamente, per la gestione delle ProgressBar si agisce su due parametri: IsIndeterminate e Visibility. Questo perchè, quando la proprietà IsIndeterminate è a false, l’animazione non è più visibile ma lo spazio occupato dal controllo sì, “sporcando” perciò la nostra pagina. Per evitare questo inconveniente perciò, al termine del caricamento è buona norma impostare la proprietà Visibility a Visibility.Collapsed (come vedremo nel post successivo parlando dei Converters, la proprietà Visibility non è di tipo booleano). Ricordatevi sempre però di impostare prima anche la proprietà IsIndeterminate a false! Se vi limitate a nasconderla, infatti, l’animazione di caricamento continuerà ad essere eseguita, andando ad impattare sulle performance della vostra applicazione.
In conclusione
Con questo post abbiamo chiuso la panoramica dei controlli inclusi nella libreria Coding4Fun: nel prossimo post vedremo invece tutte le altre utility (behaviors, converters, ecc.) presenti nel toolkit. Qui sotto trovate il link per scaricare il progetto di esempio completo di tutti i controlli analizzati sia nel post precedente che in questo.

Recent Comments