way two raisepropertychanged property example change c# silverlight windows-phone-7

c# - two - wpf binding textbox



"UpdateSourceTrigger=PropertyChanged" equivalente para Windows Phone 7 TextBox (8)

¿Hay alguna forma de obtener un TextBox en Windows Phone 7 para actualizar el enlace a medida que el usuario escribe cada letra en lugar de perder el foco?

Al igual que el siguiente WPF TextBox haría:

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


¡Es solo una línea de código!

(sender as TextBox).GetBindingExpression(TextBox.TextProperty).UpdateSource();

Puede crear un evento genérico TextChanged (por ejemplo, "ImmediateTextBox_TextChanged") en el código detrás de su página, y luego vincularlo a cualquier TextBox en la página.


En el evento TextChanged, llama a UpdateSource() .

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


Me gusta usar una propiedad adjunta. Por si acaso te interesan esos pequeños cabrones.

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

Y luego el código de respaldo.

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(); } } }


No a través de la sintaxis vinculante, no, pero es bastante fácil sin. Debe manejar el evento TextChanged y llamar a UpdateSource en el enlace.

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

Esto se puede convertir en un comportamiento adjunto también bastante fácilmente.


Puede escribir su propio comportamiento de TextBox para manejar la actualización en TextChanged:

Esta es mi muestra para PasswordBox, pero puede cambiarla para manejar cualquier propiedad de cualquier objeto.

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(); } }

Usage

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


Silverlight para WP7 no es compatible con la sintaxis que ha enumerado. Haga lo siguiente en su lugar:

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

UpdateSourceTrigger = Explicit es una bonificación inteligente aquí. ¿Qué es? Explicit : Actualiza la fuente de enlace solo cuando llama al método UpdateSource . Le ahorra un conjunto de enlaces extra cuando el usuario abandona el TextBox .

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(); }


Tomé la respuesta de Praetorian e hice una clase de extensión que hereda TextBox para que no tengas que complicar el código de tu vista con este comportamiento.

C-Sharp :

public class TextBoxUpdate : TextBox { public TextBoxUpdate() { TextChanged += OnTextBoxTextChanged; } private void OnTextBoxTextChanged(object sender, TextChangedEventArgs e) { TextBox senderText = (TextBox)sender; BindingExpression bindingExp = senderText.GetBindingExpression(TextBox.TextProperty); bindingExp.UpdateSource(); } }

VisualBasic :

Public Class TextBoxUpdate : Inherits TextBox Private Sub OnTextBoxTextChanged(sender As Object, e As TextChangedEventArgs) Handles Me.TextChanged Dim senderText As TextBox = DirectCast(sender, TextBox) Dim bindingExp As BindingExpression = senderText.GetBindingExpression(TextBox.TextProperty) bindingExp.UpdateSource() End Sub End Class

Luego llame así en XAML :

<local:TextBoxUpdate Text="{Binding PersonName, Mode=TwoWay}"/>


UpdateSourceTrigger = Explícito no funciona para mí, por lo tanto, estoy usando una clase personalizada derivada de TextBox

public class TextBoxEx : TextBox { public TextBoxEx() { TextChanged += (sender, args) => { var bindingExpression = GetBindingExpression(TextProperty); if (bindingExpression != null) { bindingExpression.UpdateSource(); } }; } }