34 votes

Équivalent de "UpdateSourceTrigger=PropertyChanged" pour une TextBox Windows Phone 7

Existe-t-il un moyen de faire en sorte qu'une TextBox dans Windows Phone 7 mette à jour la reliure au fur et à mesure que l'utilisateur tape chaque lettre plutôt qu'après avoir perdu le focus ?

Comme le ferait la TextBox WPF suivante :

<TextBox Text="{Binding Path=TextProperty, UpdateSourceTrigger=PropertyChanged}"/>

51voto

Praetorian Points 47122

Silverlight pour WP7 ne prend pas en charge la syntaxe que vous avez mentionnée. Procédez plutôt comme suit :

<TextBox TextChanged="OnTextBoxTextChanged"
         Text="{Binding MyText, Mode=TwoWay,
                UpdateSourceTrigger=Explicit}" />

UpdateSourceTrigger = Explicit est un bonus intelligent. Qu'est-ce que c'est ? Explicite : Met à jour la source de liaison uniquement lorsque vous appelez la fonction UpdateSource méthode. Elle permet d'économiser un jeu de liens supplémentaire lorsque l'utilisateur quitte la page TextBox .

En C# :

private void OnTextBoxTextChanged( object sender, TextChangedEventArgs e )
{
  TextBox textBox = sender as TextBox;
  // Update the binding source
  BindingExpression bindingExpr = textBox.GetBindingExpression( TextBox.TextProperty );
  bindingExpr.UpdateSource();
}

23voto

Parrhesia Joe Points 477

J'aime utiliser une propriété attachée. Juste au cas où vous seriez intéressé par ces petites bestioles.

<toolkit:DataField Label="Name">
  <TextBox Text="{Binding Product.Name, Mode=TwoWay}" c:BindingUtility.UpdateSourceOnChange="True"/>
</toolkit:DataField>

Puis le code de soutien.

public class BindingUtility
{
public static bool GetUpdateSourceOnChange(DependencyObject d)
{
  return (bool)d.GetValue(UpdateSourceOnChangeProperty);
}

public static void SetUpdateSourceOnChange(DependencyObject d, bool value)
{
  d.SetValue(UpdateSourceOnChangeProperty, value);
}

// Using a DependencyProperty as the backing store for …
public static readonly DependencyProperty
  UpdateSourceOnChangeProperty =
    DependencyProperty.RegisterAttached(
    "UpdateSourceOnChange",
    typeof(bool),
              typeof(BindingUtility),
    new PropertyMetadata(false, OnPropertyChanged));

private static void OnPropertyChanged (DependencyObject d,
  DependencyPropertyChangedEventArgs e)
{
  var textBox = d as TextBox;
  if (textBox == null)
    return;
  if ((bool)e.NewValue)
  {
    textBox.TextChanged += OnTextChanged;
  }
  else
  {
    textBox.TextChanged -= OnTextChanged;
  }
}
static void OnTextChanged(object s, TextChangedEventArgs e)
{
  var textBox = s as TextBox;
  if (textBox == null)
    return;

  var bindingExpression = textBox.GetBindingExpression(TextBox.TextProperty);
  if (bindingExpression != null)
  {
    bindingExpression.UpdateSource();
  }
}
}

5voto

Adam Sills Points 8749

Pas par le biais d'une syntaxe contraignante, non, mais c'est assez facile sans. Vous devez gérer l'événement TextChanged et appeler UpdateSource sur la reliure.

private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
    ((TextBox) sender).GetBindingExpression( TextBox.TextProperty ).UpdateSource();
}

Il peut être converti en un comportement attaché aussi assez facilement.

1voto

lukas Points 7789

Dans l'événement TextChanged, appeler UpdateSource() .

BindingExpression be = itemNameTextBox.GetBindingExpression(TextBox.TextProperty);
be.UpdateSource();

1voto

Vous pouvez écrire votre propre comportement de TextBox pour gérer la mise à jour sur TextChanged :

Il s'agit de mon exemple pour PasswordBox mais vous pouvez simplement le modifier pour gérer n'importe quelle propriété de n'importe quel objet.

public class UpdateSourceOnPasswordChangedBehavior
     : Behavior<PasswordBox>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.PasswordChanged += OnPasswordChanged;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.PasswordChanged -= OnPasswordChanged;
    }

    private void OnPasswordChanged(object sender, RoutedEventArgs e)
    {
        AssociatedObject.GetBindingExpression(PasswordBox.PasswordProperty).UpdateSource();
    }
}

Ussage :

<PasswordBox x:Name="Password" Password="{Binding Password, Mode=TwoWay}" >
    <i:Interaction.Behaviors>
        <common:UpdateSourceOnPasswordChangedBehavior/>
    </i:Interaction.Behaviors>
</PasswordBox>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X