对于Windows Phone 7 TextBox,“UpdateSourceTrigger = PropertyChanged”等效
有没有办法让Windows Phone 7中的TextBox更新绑定作为用户键入每个字母,而不是失去焦点后?
像下面的WPF文本框一样:
<TextBox Text="{Binding Path=TextProperty, UpdateSourceTrigger=PropertyChanged}"/>
Silverlight for WP7不支持您列出的语法。 做相反的事情:
<TextBox TextChanged="OnTextBoxTextChanged" Text="{Binding MyText, Mode=TwoWay, UpdateSourceTrigger=Explicit}" />
UpdateSourceTrigger = Explicit
在这里是一个聪明的奖金。 它是什么? 显式 :仅在调用UpdateSource
方法时更新绑定源。 当用户离开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(); }
我喜欢使用附加的属性。 以防万一你进入那些小小的bug子手
<toolkit:DataField Label="Name"> <TextBox Text="{Binding Product.Name, Mode=TwoWay}" c:BindingUtility.UpdateSourceOnChange="True"/> </toolkit:DataField>
然后是支持代码。
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(); } } }
不通过绑定语法,不,但是没有。 您必须处理TextChanged事件并在绑定上调用UpdateSource 。
private void TextBox_TextChanged(object sender, TextChangedEventArgs e) { ((TextBox) sender).GetBindingExpression( TextBox.TextProperty ).UpdateSource(); }
这可以很容易地转换成附加的行为 。
在TextChanged事件中调用UpdateSource() 。
BindingExpression be = itemNameTextBox.GetBindingExpression(TextBox.TextProperty); be.UpdateSource();
您可以编写自己的TextBox行为来处理TextChanged上的更新:
这是我的示例PasswordBox,但你可以简单地改变它来处理任何对象的任何属性。
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>
UpdateSourceTrigger =显式不适用于我,因此我使用从TextBox派生的自定义类
public class TextBoxEx : TextBox { public TextBoxEx() { TextChanged += (sender, args) => { var bindingExpression = GetBindingExpression(TextProperty); if (bindingExpression != null) { bindingExpression.UpdateSource(); } }; } }
这只是一行代码!
(sender as TextBox).GetBindingExpression(TextBox.TextProperty).UpdateSource();
您可以在页面后面的代码中创build一个通用的TextChanged事件(例如“ImmediateTextBox_TextChanged”),并将其链接到页面中的任何TextBox。
我拿了Praetorian的答案,并做了一个inheritanceTextBox
的扩展类,所以你不必混淆视图的代码。
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
然后在XAML中这样调用:
<local:TextBoxUpdate Text="{Binding PersonName, Mode=TwoWay}"/>