[英]No PropertyChanged option for UpdateSourceTrigger in Windows Phone 8 apps?
[英]“UpdateSourceTrigger=PropertyChanged” equivalent for a Windows Phone 7 TextBox
有没有一种方法可以让Windows Phone 7中的TextBox在用户键入每个字母而不是失去焦点后更新绑定?
就像下面的WPF TextBox一样:
<TextBox Text="{Binding Path=TextProperty, UpdateSourceTrigger=PropertyChanged}"/>
WP7的Silverlight不支持您列出的语法。 而是执行以下操作:
<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();
}
我喜欢使用附加属性。 以防万一您迷上了那些小虫子。
<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();
}
这也可以很容易地转换为附加行为 。
您可以编写自己的TextBox Behavior以处理TextChanged上的Update:
这是我对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();
}
}
用法:
<PasswordBox x:Name="Password" Password="{Binding Password, Mode=TwoWay}" >
<i:Interaction.Behaviors>
<common:UpdateSourceOnPasswordChangedBehavior/>
</i:Interaction.Behaviors>
</PasswordBox>
在TextChanged事件中,调用UpdateSource() 。
BindingExpression be = itemNameTextBox.GetBindingExpression(TextBox.TextProperty);
be.UpdateSource();
UpdateSourceTrigger = Explicit对我不起作用,因此Im使用从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();
您可以在页面后面的代码中创建通用TextChanged事件(例如“ ImmediateTextBox_TextChanged”),然后将其链接到页面中的任何TextBox。
我接受了Praetorian的回答,并制作了一个继承类TextBox
的扩展类,因此您不必在这种情况下混淆视图的代码。
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}"/>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.