IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Comprendre le Binding en WPF et Silverlight

Comprendre le Binding en WPF et Silverlight


précédentsommairesuivant

I. Avant propos - Introduction

I-A. Un mot sur l'auteur

Je suis Nathanael Marchand, diplômé 2009 de Polytech'Annecy-Chambéry. Actuellement chez So@t, j'occupe le poste d'Expert .Net qui regroupe des missions de consulting sur les technologies .Net, d'audit, de formation interne et externe, la veille technologique ainsi que la participation à la stratégie d'expertise So@t.
Vous pouvez me retrouver ici sur Developpez.com où j'anime et modère la partie .Net ainsi que sur Silverlight-France où j'ai participé à la création de cette communauté.
Vous pouvez également me retrouver sur des évènements comme les Tech'Days où j'anime des sessions (PAR305).

I-B. Introduction

Binding se traduit en français par le mot "liaison", il permet donc de créer une liaison entre deux éléments. On s'en sert notamment pour lier l'interface graphique aux objets qu'elle doit représenter. Ainsi du côté de l'interface graphique, je dessine un modèle d'affichage et lorsque j'applique la liaison, les champs sont remplis avec les données.

II. Le Binding, premier aperçu

Voici le code d'une application simple utilisant le binding, nous allons voir le fonctionnement.

 
Sélectionnez
using System;
using System.Collections.Generic;

namespace BindingTutorial.WpfApplication
{
	public partial class MainWindow
	{
		private string _myText;
		private List<string> _myItems;

		public String MyText
		{
			get
			{
				Trace.WriteLine("Get MyText");
				return _myText;
			}
			set
			{
				Trace.WriteLine("Set MyText");
				_myText = value;
			}
		}

		public List<String> MyItems
		{
			get
			{
				Trace.WriteLine("Get MyItems");
				return _myItems;
			}
			set
			{
				Trace.WriteLine("Set MyItems");
				_myItems = value;
			}
		}

		public MainWindow()
		{
			MyText = "Hello world!";
			MyItems = new List<string> { "Bonjour", "le", "monde" };

			InitializeComponent();
			DataContext = this;
		}
	}
}
 
Sélectionnez
<Window x:Class="BindingTutorial.WpfApplication.MainWindow"
		xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
		xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
		Title="MainWindow"
		Height="350"
		Width="525">
	<Grid>
		<Grid.RowDefinitions>
			<RowDefinition Height="Auto" />
			<RowDefinition Height="Auto" />
			<RowDefinition />
		</Grid.RowDefinitions>
		<TextBox Text="{Binding Path=MyText}" />
		<ListBox Grid.Row="1"
				 Height="100"
				 ItemsSource="{Binding Path=MyItems}" />
	</Grid>
</Window>

Du point de vue C#, on peut voir plusieurs choses : tout d'abord on expose deux propriétés (une chaîne de caractères et une collection) ensuite on s'aperçoit qu'on initialise le DataContext de la fenêtre à elle-même. C'est là qu'intervient la magie : ce DataContext est ce à quoi est liée la fenêtre. Ainsi dans un annuaire, on aurait chaque zone qui aurait pour contexte la personne dont il est question.
Côté XAML, on peut voir le binding dans la TextBox et dans la ListBox. La syntaxe est le mot Binding ainsi que ses paramètres entre accolades. Notre contexte de données (DataContext) est la fenêtre, ce qui fait que pour s'attacher à la propriété MyText de la fenêtre, WPF doit emprunter le chemin Path=MyText. Même chose pour la ListBox qui elle à besoin d'une source qui implémente l'interface IEnumerable.
Lorsque l'on lance l'application et que l'on tape du texte dans la TextBox, on s'aperçoit qu'à la perte du focus, on a le setter de la propriété MyText qui est appelé pour mettre la nouvelle valeur. On voit donc que le Binding est à double sens : l'interface peut lire mais également écrire.
Complexifions un peu la chose en ajoutant un bouton. Ce bouton nous allons le brancher de manière à ce qu'il change la valeur de la TextBox.

 
Sélectionnez
<Window x:Class="BindingTutorial.WpfApplication.MainWindow"
		xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
		xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
		Title="MainWindow"
		Height="350"
		Width="525">
	<Grid>
		<Grid.RowDefinitions>
			<RowDefinition Height="Auto" />
			<RowDefinition Height="Auto" />
			<RowDefinition Height="Auto" />
			<RowDefinition Height="Auto" />
			<RowDefinition />
		</Grid.RowDefinitions>
		<TextBox Text="{Binding MyText}" />
		<Button Grid.Row="1" Content="Click Me" Click="ChangeTextBox" />
		<ListBox Grid.Row="2"
				 Height="100"
				 ItemsSource="{Binding MyItems}" />
		<Button Grid.Row="3" Content="Click Me" Click="ChangeListBox" />
	</Grid>
</Window>
 
Sélectionnez
private void ChangeTextBox(object sender, RoutedEventArgs e)
{
	MyText = MyText + MyText;
}

private void ChangeListBox(object sender, RoutedEventArgs e)
{
	MyItems.Add(DateTime.Now.ToString());
}

Si on clique sur le premier bouton, on s'aperçoit à l'aide des outils de Debug que le texte est bien modifié mais que l'interface ne détecte pas ce changement. C'est un comportement voulu: pour que le binding fonctionne, il faut que l'objet observé prévienne les observateurs en cas de changement.
Sur le second bouton, c'est le même principe : bien qu'on ne remplace pas la collection par une autre collection, on change le contenu de la collection. Il faut que celle-ci avertisse ceux qui la scrutent.
Ce sont ces mécanismes de notifications que nous allons étudier dans la seconde partie.


précédentsommairesuivant

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2012 Nathanael Marchand. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts. Droits de diffusion permanents accordés à Developpez LLC.