Accueil > Silverlight, Silverlight 3 > [SL3] : TextBox UpdateSourceTrigger PropertyChanged connu sur WPF

[SL3] : TextBox UpdateSourceTrigger PropertyChanged connu sur WPF

Fréquemment les développeur WPF utilisent un attribut du Binding permettant d’appliquer le Binding sur la source de donnée au changement de la propriétée de la cible.


<TextBox x:Name="MyTextBox" Text="{Binding Path=LastName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

Ainsi à chaque fois que la DP Text change on met à jour la source qui n’est autre que la propriétée LastName (de votre ViewModel par exemple). Une solution simple rapide et efficace !

Le problème est que celà n’existe pas encore au sein de Silverlight 3 (certainement dans la version 4 : croisons les doigts !)

Une première solution est de s’abonner à l’évènement TextChanged de la TextBox et de valider le Binding (comme nous devrions le faire si nous spécifions UpdateSourceTrigger=Explicit). Cela donnerai ceci :

Coté XAML


<Window x:Class="WpfApplication1.Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<TextBox x:Name="MyTextBox" Text="{Binding Path=LastName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</Window>

Coté Code-Behind


public partial class Window1 : Window
 {
 public Window1()
 {
 InitializeComponent();

 MyTextBox.TextChanged += new TextChangedEventHandler(OnTextChanged);
 }

 private void OnTextChanged(object sender, TextChangedEventArgs e)
 {
 BindingExpression be = MyTextBox.GetBindingExpression(TextBox.TextProperty);
 be.UpdateSource();
 }
 }

Ceci est fonctionnel mais celà peut devenir rapidement fastidieux si vous avez plusieurs TextBox dans votre écran… Une des solution étant d’utiliser les propriétées attachée pour réaliser ce traitement.

Nous allons donc réaliser une propriété attachée qui définira si l’on souhaite activer la validation du binding au changement de valeur de la textbox :


/// <summary>
 /// Classe fournissant une propriété attachée permettant d'ajouter la fonctionnalité d'UpdateSourceTrigger à PropertyChanged
 /// </summary>
 public class TextBoxTextUpdateSourceTrigger
 {
 #region DP
 /// <summary>
 /// Définit la dependency property attachée UpdateOnPropertyChanged
 /// </summary>
 public static readonly DependencyProperty UpdateOnPropertyChangedProperty =
 DependencyProperty.RegisterAttached(
 "UpdateOnPropertyChanged",
 typeof(Boolean),
 typeof(TextBoxTextUpdateSourceTrigger),
 new PropertyMetadata(OnUpdateOnPropertyChanged));

 /// <summary>
 /// Obtient la valeur de la propriété UpdateOnPropertyChanged
 /// </summary>
 /// <param name="sender">Objet attaché à la propriété</param>
 /// <returns>Valeur courante de la propriété</returns>
 public static Boolean GetUpdateOnPropertyChanged(DependencyObject sender)
 {
 return (Boolean)sender.GetValue(UpdateOnPropertyChangedProperty);
 }

 /// <summary>
 ///  Définit la valeur de la propriété UpdateOnPropertyChanged
 /// </summary>
 /// <param name="sender">Objet attaché à la propriété</param>
 /// <param name="value">Nouvelle valeur à inscrire</param>
 public static void SetUpdateOnPropertyChanged(DependencyObject sender, Boolean value)
 {
 sender.SetValue(UpdateOnPropertyChangedProperty, value);
 }
 #endregion

 #region Handlers
 private static void OnUpdateOnPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
 {
  TextBox textBox = null;
 textBox = sender as TextBox;

 if ((Boolean)e.OldValue) //ancienne valeur de PropertyChanged => true on se désabonne pour evider les effets de bord
 {
 textBox.TextChanged -= OnTextChanged;
 }

 if ((Boolean)e.NewValue)//nouvelle valeur de PropertyChanged => true on s'abonne à l'évènement TextChanged
 {
 textBox.TextChanged += OnTextChanged;
 }
 }

 private static void OnTextChanged(object sender, TextChangedEventArgs e)
 {
 TextBox textBox = sender as TextBox;

 if (textBox != null)
 {
 BindingExpression be = textBox.GetBindingExpression(TextBox.TextProperty);

 if (be != null)
 {
 be.UpdateSource();
 }
 }
}
 #endregion
 }

Enfin afin d’utiliser cette fonctionnalité, rien de plus simple :


<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ust="clr-namespace:WpfApplication1">

<TextBox x:Name="MyTextBox"
Text="{Binding Path=LastName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ust:TextBoxTextUpdateSourceTrigger.UpdateOnPropertyChanged="True"/>
</Window>

Et le tour est joué 🙂

Publicités
Catégories :Silverlight, Silverlight 3
  1. Aucun commentaire pour l’instant.
  1. No trackbacks yet.

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion /  Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion /  Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion /  Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion /  Changer )

Connexion à %s

%d blogueurs aiment cette page :