Introduction

Présent en WPF mais absent en Silverlight 2, le binding d'élément à élément est maintenant disponible avec la version 3 de Silverlight.

L'application de démonstration est disponible en ligne ici.

I. Binding simple

Pour illustrer un binding simple nous allons animer au rectangle au sein d'un Canvas. Pour cela nous utiliserons deux Sliders qui permettront de modifier les propriétés Canvas.Left et Canvas.Top du rectangle.

L'expression du binding en Silverlight 3 nous permet maintenant de lier des propriétés d'éléments graphiques entre eux grâce à l'ajout de la propriété ElementName. Dans le code suivant nous lions la propriété attachée Canvas.Left à la propriété Value du Slider donc le nom est SliderH.

 
Sélectionnez
Canvas.Left="{Binding Value, ElementName=SilderH}"

Le code complet :

 
Sélectionnez
<StackPanel Orientation="Horizontal" Grid.Row="0">
  <Slider Minimum="0" Maximum="200" x:Name="SilderH" Width="200" Margin="5"/>
  <TextBlock Text="{Binding Value, ElementName=SilderH, Mode=OneWay}" />
</StackPanel>

<StackPanel Orientation="Horizontal" Grid.Row="1">
  <Slider Minimum="0" Maximum="200" x:Name="SilderV" Width="200" Margin="5"/>
  <TextBlock Text="{Binding Value, ElementName=SilderV, Mode=OneWay}" />
</StackPanel>

<Canvas Grid.Row="3" Margin="20">
  <Rectangle Width="50"
             Height="50"
             Fill="Blue"
             Canvas.Left="{Binding Value, ElementName=SilderH}"
             Canvas.Top="{Binding Value, ElementName=SilderV}">
  </Rectangle>
</Canvas>
binding2.png
binding1.png

II. Binding sur une projection

Une des nouveautés de Silverlight 3 est la possibilité de simuler des effets 3D en utilisant des projections. Une propriété Projection à été rajouté à la classe UIElement permettant de manipuler facilement ces effets.

La classe PlaneProjection permet de simuler des transformations suivant les axes X, Y et Z :

487px-3D_coordinate_system_svg


Bien évidemment, nous ne résistons pas à l'envie d'ajouter une projection à un rectangle et de lier les propriétés de cette projection à des Sliders.

Nous créons donc trois Sliders que nous lions aux propriétés RotationX, RotationY et RotationZ du PlaneProjection.

 
Sélectionnez
<StackPanel Orientation="Horizontal" Grid.Row="0">
  <Slider Minimum="0" Maximum="200" Value="{Binding RotationX, ElementName=Projector, Mode=TwoWay}"
          x:Name="SilderX" Width="200" Margin="5"/>
  <TextBlock Text="{Binding Value, ElementName=SilderX}" />
</StackPanel>

<StackPanel Orientation="Horizontal" Grid.Row="1">
  <Slider Minimum="0" Maximum="200" Value="{Binding RotationY, ElementName=Projector, Mode=TwoWay}"
          x:Name="SilderY" Width="200" Margin="5"/>
  <TextBlock Text="{Binding Value, ElementName=SilderY}" />
</StackPanel>

<StackPanel Orientation="Horizontal" Grid.Row="2">
  <Slider Minimum="0" Maximum="200" Value="{Binding RotationZ, ElementName=Projector, Mode=TwoWay}"
          x:Name="SilderZ" Width="200" Margin="5"/>
  <TextBlock Text="{Binding Value, ElementName=SilderZ}" />
</StackPanel>

<Canvas Grid.Row="3" Margin="20">
  <Rectangle Width="50"
             Height="50"
             Fill="Red">
    <Rectangle.Projection>
      <PlaneProjection x:Name="Projector"/>
    </Rectangle.Projection>
  </Rectangle>
</Canvas>

Transformation suivant l'axe Z :

binding4.png
binding3.png

III. Binding en utilisant un converter

Si les deux propriétés que vous voulez liée ne sont du même type vous pouvez utiliser un converter. Prenons par exemple le cas d'une Combobox contenant une liste de couleur (liste de String). Nous voudrions lier la couleur de remplissage d'un rectangle (propriété Fill) avec la valeur de la Combobox. Cela n'est pas possible directement car la couleur du rectangle est de type Brush et les éléments de la Combobox de type String.

Nous allons donc créer un converter (très simpliste pour notre exemple) qui va convertir une chaine de caractère en Brush.

Code du converter
Sélectionnez
public class StringToColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value != null)   
           {
               string colorString = value.ToString();
               if (!string.IsNullOrEmpty(colorString))   
               {
                   switch (colorString)
                   {
                       case "Rouge"  :
                           return new SolidColorBrush(Colors.Red);
                       case "Vert":
                           return new SolidColorBrush(Colors.Green);
                       default:
                           return new SolidColorBrush(Colors.Black);
                   }
               }
           }
        return new SolidColorBrush(Colors.Black);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}


Pour l'utiliser nous le déclarons en tant que ressource au sein de notre page :

Déclaration du converter
Sélectionnez
<UserControl.Resources>
  <local:StringToColorConverter x:Key="stringToColorConverter"/>
</UserControl.Resources>


Il suffit ensuite de spécifier d'utiliser ce converter dans le binding entre l'élément sélectionné de la Combobox et la couleur de remplissage du rectangle :

 
Sélectionnez
<ComboBox x:Name="ComboCouleurs" Width="100" Margin="10" >
  <System:String>Rouge</System:String>
  <System:String>Vert</System:String>
</ComboBox>
<Rectangle Height="50"
           Width="50"
           Fill="{Binding SelectedItem, 
                                    ElementName=ComboCouleurs, 
                                    Converter={StaticResource stringToColorConverter}}"/>

Le résultat en image :

binding5.png
binding6.png

Sources

Téléchargez les sources de la solution donnée en exemple.

Remerciements

J'adresse ici tous mes remerciements à l'équipe de rédaction de "developpez.com" pour le temps qu'ils ont bien voulu passer à la correction et à l'amélioration de cet article.

Contact

Si vous constatez une erreur dans le tutorial, dans les sources, dans la programmation ou pour toutes informations, n'hésitez pas à me contacter par le forum.