1. //publish/
Roma, 16 - 17 Maggio 2014
Data Binding
In App XAML/C#
Luca Di Fino
dev.luke2375@live.it
@luke2375
luke2375.wordpress.com
2. //publish/
Roma, 16 - 17 Maggio 2014
2
Agenda
Hard Code
Data Binding
INotifyPropertyChanged
Collection
Accesso ai dati
Converter
REST API – JSON
Blend
3. //publish/
Roma, 16 - 17 Maggio 2014
3
Hard Code
Il modo più semplice di popolare l’interfaccia (UI) della vostra app è di valorizzare le
proprietà dei controlli direttamente nello XAML
<TextBlock Text="Hello World" />
…ma non rende la vostra applicazione particolarmente dinamica
Oppure modificare le proprietà dei controlli XAML da code-behind
<TextBlock x:Name="Etichetta" />
Etichetta.Text = "Hello World";
In questo modo potete modificare la vostra interfaccia in seguito a determinati eventi
Ma questo approccio diventa presto poco gestibile, perché non c’è separazione tra i dati e
la loro presentazione
4. //publish/
Roma, 16 - 17 Maggio 2014
4
Data Binding
Il meccanismo del Data Binding vi permette di legare la vostra interfaccia ad una o
più classi nella vostra applicazione che contengono i dati
Una classe dati che agisce da source per il data binding è detta ViewModel
L’idea è di definire un legame dinamico tra le proprietà dei controlli della UI e i dati
nel ViewModel, in modo che modifiche ai dati si riflettano automaticamente
sull’interfaccia e, viceversa, che interazioni con l’interfaccia possano modificare i dati
collegati
5. //publish/
Roma, 16 - 17 Maggio 2014
5
Data Binding
1. Creiamo una classe dati
class Data
{
public string Etichetta;
public string Etichetta { get; set; }
}
2. Istanziamo un oggetto della classe e ne impostiamo i valori
Data appData = new Data( );
appData.Etichetta = "Hello World";
3. Applichiamo il binding
TextBlock1.DataContext = appData;
<TextBlock x:Name="TextBlock1" Text="{Binding Etichetta}" />
Usare le proprietà
public string Etichetta { get; set; }
è un modo compatto per definire
private string etichetta;
public string Etichetta
{
get { return etichetta; }
set { etichetta = value; }
}
senza proprietà il binding
NON FUNZIONA
6. //publish/
Roma, 16 - 17 Maggio 2014
6
Data Binding Gerarchico
Non è necessario assegnare un DataContext a tutti gli elementi
Il Data Binding è gerarchico
Assegnando il DataContext ad un elemento contenitore, tutti i contenuti faranno
riferimento a quello stesso DataContext
class HData
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Title { get; set; }
public string NickName { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string Address { get; set; }
public string City { get; set; }
}
<StackPanel x:Name="ContentPanel">
<TextBlock Text="{Binding FirstName}" />
<TextBlock Text="{Binding LastName}" />
<TextBlock Text="{Binding Title}" />
<TextBlock Text="{Binding NickName}" />
<TextBlock Text="{Binding Email}" />
<TextBlock Text="{Binding Phone}" />
<TextBlock Text="{Binding Address}" />
<TextBlock Text="{Binding City}" />
</StackPanel>
7. //publish/
Roma, 16 - 17 Maggio 2014
7
INotifyPropertyChanged
Per rendere davvero dinamica l’app gli oggetti dati che prendono parte al binding devono
implementare l’interfaccia INotifyPropertyChanged
Questa interfaccia richiede che l’oggetto pubblichi l’evento PropertyChanged
L’oggetto deve lanciare l’evento PropertyChanged ogni volta che il valore di una delle sue
proprietà pubbliche cambia
Il runtime XAML intercetta questo evento e aggiorna gli elementi della UI
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
9. //publish/
Roma, 16 - 17 Maggio 2014
10
Collection
Il Data Binding può essere applicato anche a collezioni di oggetti
public List<string> lista {get; set;}
In questo caso la collection di dati viene assegnata come ItemSource del controllo
<ListBox ItemsSource="{Binding lista}"/>
Per liste di oggetti complessi
public List<HData> listaHData {get; set;}
dobbiamo definire nello XAML un DataTemplate che definisce l’aspetto di ogni elemento
della lista
Le liste che implementano l’INotifyPropertyChanged sono le ObservableCollection
Gli elementi devono implementare a loro volta INotifyPropertyChanged
11. //publish/
Roma, 16 - 17 Maggio 2014
12
Accesso ai dati
Una volta assegnato un oggetto in binding possiamo recuperare da codice l’oggetto originale,
ad esempio l’oggetto selezionato in una lista
Agganciamo una funzione all’evento SelectionChanged della ListBox
<ListBox ItemsSource="{Binding listaHData}" DisplayMemberPath="Name"
SelectionChanged="ListBox_SelectionChanged"/>
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var OriginalObject = (HData)((ListBox)sender).SelectedItem;
}
12. //publish/
Roma, 16 - 17 Maggio 2014
13
Converter
Tramite i converter possiamo fare il binding di grandezze eterogenee
Ad esempio potremmo legare il valore di una certa proprietà alla visibilità di un elemento
IValueConverter
Convert
Converte la proprietà dell’oggetto in un nuovo formato prima di assegnarlo alla proprieta del
FrameworkElement
ConvertBack
Converte la proprietà del FrameworkElement al formato originale prima di riassegnare il valore
all’oggetto
Spesso non viene implementata
13. //publish/
Roma, 16 - 17 Maggio 2014
14
Converter
Definite la classe converter
public class BooleanToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
bool visibility = (bool)value;
return visibility ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
Visibility visibility = (Visibility)value;
return (visibility == Visibility.Visible);
}
}
La aggiungete ad un file di risorse
<conv:BooleanToVisibilityConverter x:Key="VisibilityConverter" />
Impostate il Converter all’interno del binding
Visibility="{Binding IsVisible, Converter={StaticResource BooleanToVisibilityConverter}}"
14. //publish/
Roma, 16 - 17 Maggio 2014
15
REST API
Tipicamente la vostra app consuma contenuti esposti da un servizio remoto
Es. REST API che restituiscono contenuto JSON
I dati del servizio remoto possono essere usati per popolare il vostro ViewModel
Il Binding vi permetterà di non preoccuparvi di aggiornare l’interfaccia
Ci sono dei tool che permettono di creare automaticamente la classe C# corrispondente al
dato json
http://jsonclassgenerator.codeplex.com
http://json2csharp.com/
15. //publish/
Roma, 16 - 17 Maggio 2014
16
Design Data
PROBLEMA
Utilizzando il Data Binding il designer di Visual Studio non vi mostra il layout
Siete obbligati a fare il deploy dell’app per verificare il vostro layout?
Fortunatamente ci viene in aiuto Blend
Blend permette di creare un file dati di esempio a partire da una classe o da un file XML
Questo file verrà messo in binding con la nostra interfaccia a design time, in modo da
permetterci di lavorare sul layout senza dover necessariamente fare il deploy