Le data binding est une des fonctionnalités les plus puissantes de Silverlight et WPF. Il n'est plus nécessaire de passer du temps à faire du code pour la synchronisation des données. Cela contribue à la séparation de la partie visuelle de la partie métier.
Fonctionnement
En beta 1, le data binding est implémenté sur tout les objets qui héritent de FrameworkElement. Les propriétés de ce contrôle peuvent être liées à un objet source spécifiée lors du binding ou être liées au contexte de binding en cours. Le binding en cours est stockée par la propriété DataContext.
1 <UserControl x:Class="Ucaya.SilverlightTest.Page"
2 xmlns="http://schemas.microsoft.com/client/2007"
3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4 xmlns:sys="clr-namespace:System;assembly=mscorlib"
5 Width="400" Height="300">
6 <UserControl.Resources>
7 <sys:String x:Name="src">Binding source</sys:String>
8 </UserControl.Resources>
9 <StackPanel x:Name="LayoutRoot" Background="White">
10 <TextBlock x:Name="tb1" Text="{Binding Source={StaticResource src}}"/>
11 <TextBlock x:Name="tb2" Text="{Binding Length, Source={StaticResource src}}"/>
12 </StackPanel>
13 </UserControl>
Ici, le TextBlock tb1 a sa propriété Text bindée à l'objet src qui se trouve dans les ressources. N'ayant pas spécifié de chemin dans la binding, c'est l'objet lui même qui est lié.
Le TextBlock tb2 est lié à la propriété Length de la source.
1 <UserControl x:Class="Ucaya.SilverlightTest.Page"
2 xmlns="http://schemas.microsoft.com/client/2007"
3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4 xmlns:sys="clr-namespace:System;assembly=mscorlib"
5 Width="400" Height="300">
6 <UserControl.Resources>
7 <sys:String x:Name="src">Binding source</sys:String>
8 </UserControl.Resources>
9 <Grid x:Name="LayoutRoot" Background="White">
10 <ListBox x:Name="lb" ItemsSource="{Binding Source={StaticResource src}}">
11 <ListBox.ItemTemplate>
12 <DataTemplate>
13 <TextBlock x:Name="tb" Text="{Binding }"/>
14 </DataTemplate>
15 </ListBox.ItemTemplate>
16 </ListBox>
17 </Grid>
18 </UserControl>
La ListBox est bindée de la même manière que dans l'exemple 1. La string étant énumérable, la ListBox instancie un ItemTemplate par valeur de l'énumération.
Le TextBlock à sa propriété Text bindée au contexte de binding en cours fourni par la ListBox. Comme dans l'exemple 1, n'ayant pas fourni de chemin de binding, c'est directement la source du binding qui est liée.
Modes de binding
La synchronisation des valeurs peut se faire de différente manière.
OneTime
La donnée est recopiée de la source vers le contrôle une seule fois lorsque le binding est créé.
OneWay
La donnée est mise à jour dans le sens source vers contrôle à chaque fois que la valeur de la source change. Pour que le binding soit notifié du changement, l'objet source du binding doit implémenter l'interface INotifyPropertyChanged pour les propriétés et INotifyCollectionChanged pour les collections.
TwoWay
La donnée est mise à jour dans le sens source vers contrôle à chaque fois que la valeur de la source change (sous réserve de l'implémentation de INotifyPropertyChanged ou INotifyCollectionChanged) et dans le sens contrôle vers source quand la valeur du contrôle change.
Conversion des données
Il arrive que les données sources ne puissent être converties directement entre les propriétés d'un contrôle et les valeurs de la source. C'est là qu'interviennent les classes de conversion. Elles permettent par exemple de convertir un string en Uri, un string en ImageSource ou encore de formatter un double en string avec 2 nombres après la virgule. Ces convertisseurs sont des classes qui implémentent l'interface IValueConverter.
Implémentation d'un convertisseur effectuant un string.Format. Affiche une valeur en pourcentage.
Xaml:
<UserControl x:Class="Ucaya.SilverlightTest.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:sle="clr-namespace:SLExtensions.Data;assembly=SLExtensions"
Width="400" Height="300">
<UserControl.Resources>
<sys:Double x:Key="src">0.333333</sys:Double>
<sle:StringFormatConverter x:Key="formater"/>
<sys:String x:Key="formatString">{0:p}</sys:String>
</UserControl.Resources>
<StackPanel x:Name="LayoutRoot" Background="White">
<TextBlock x:Name="tb1"
Text="{Binding Converter={