“UpdateSourceTrigger = PropertyChanged”等效于Windows Phone 7 TextBox

时间:2011-01-28 21:11:58

标签: c# silverlight windows-phone-7

有没有办法让Windows Phone 7中的TextBox更新Binding,因为用户键入每个字母而不是失去焦点?

就像下面的WPF TextBox一样:

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

8 个答案:

答案 0 :(得分:51)

Silverlight for WP7不支持您列出的语法。请改为:

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

UpdateSourceTrigger = Explicit在这里是一个明智的奖励。 它是什么? 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();
}

答案 1 :(得分:23)

我喜欢使用附属物。以防你遇到那些小小的虫子。

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

答案 2 :(得分:5)

不是通过绑定语法,不是,但没有它就很容易。您必须处理TextChanged事件并在绑定上调用UpdateSource

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

这很容易转换为attached behavior

答案 3 :(得分:1)

在TextChanged事件中调用UpdateSource()

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

答案 4 :(得分:1)

您可以编写自己的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>

答案 5 :(得分:0)

UpdateSourceTrigger = Explicit对我不起作用,因此我使用从TextBox派生的自定义类

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

}

答案 6 :(得分:0)

这只是一行代码!

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

您可以在页面后面的代码中创建一个通用的TextChanged事件(例如“ImmediateTextBox_TextChanged”),然后将其链接到页面中的任何TextBox。

答案 7 :(得分:0)

我使用了Praetorian's answer并创建了一个继承TextBox的扩展类,因此您无需使用此行为混淆视图后面的代码。

<强> C-夏普

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}"/>