TextBox绑定TwoWay不会更新,直到焦点丢失WP7

时间:2011-04-06 16:23:56

标签: xaml silverlight windows-phone-7 data-binding

我有一个页面,其中包含一些用于输入数据的文本框。文本框的绑定设置为TwoWay。如果文本框失去焦点,则视图模型中的数据仅会更新。如果单击某个按钮(例如“保存”),并且文本框仍具有焦点,则在保存事件的视图模型中不会更改文本框中的更改。

有没有办法让绑定在失去焦点之前保存文本框的值?或者我是否需要在保存事件中执行某些操作?

8 个答案:

答案 0 :(得分:57)

我假设您的保存按钮是ApplicationBarButton(不是普通按钮)。对于普通按钮,它只会起作用,因为它们会聚焦,因此数据绑定会起作用。

对于手机上的ApplicationBarButtons,它们有点不同,因为它们不会将焦点从客户端应用程序中移开。要确保在单击“保存”按钮时启动数据绑定,您可以在处理程序中添加以下代码:

object focusObj = FocusManager.GetFocusedElement();
if (focusObj != null && focusObj is TextBox)
{
    var binding = (focusObj as TextBox).GetBindingExpression(TextBox.TextProperty);
    binding.UpdateSource();
}

答案 1 :(得分:16)

下载Charles Petzold的免费书籍Programming Windows Phone 7。在第387页,他谈到了如何做到这一点。

基本上,将UpdateSourceTrigger的{​​{1}}属性设置为Binding。然后,在Explicit的{​​{1}}回调中,更新绑定源。

答案 2 :(得分:7)

您可以使用Prism Library for WP7中的UpdateTextBindingOnPropertyChanged行为更新文本更改时的绑定值,而不是丢失焦点。

答案 3 :(得分:7)

我正朝着@Praetorian的方向前进。

您的TextBox的默认UpdateSourceTrigger值为LostFocus。这意味着只有当它失去焦点时,该值才会被推送到ViewModel属性。

您可以将UpdateSourceTrigger设置为PropertyChanged:

<TextBox UpdateSourceTrigger="PropertyChanged" Text="{Binding TextViewModelProperty}" />

来自http://msdn.microsoft.com/en-us/library/system.windows.data.binding.updatesourcetrigger.aspx

  

UpdateSourceTrigger值之一。   默认值为Default,返回   默认的UpdateSourceTrigger值   目标依赖属性的。   但是,大多数的默认值   依赖属性是   PropertyChanged,而Text   property的默认值为   引发LostFocus。

请记住,这意味着更新此属性触发的任何内容都会更频繁地发生(基本上每次按键时,而不是TextBox失去焦点时的单个“刷新”。) p>

希望有所帮助!

答案 4 :(得分:6)

这是Derek建议的Microsoft解决方案的快速访问答案。而不是下载和筛选所有Prism的东西,只需将此类复制到您的项目中,然后按照以下步骤激活它:

UpdateBindingOnPropertyChangedBehviour.cs

using System;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Interactivity;

namespace MyCompany.MyProduct
{
    /// <summary>
    /// Custom behavior that updates the source of a binding on a text box as the text changes.
    /// </summary>
    public class UpdateTextBindingOnPropertyChanged : Behavior<TextBox>
    {
        /// <summary>
        /// Binding expression this behavior is attached to.
        /// </summary>
        private BindingExpression _expression;

        /// <summary>
        /// Called after the behavior is attached to an AssociatedObject.
        /// </summary>
        /// <remarks>
        /// Override this to hook up functionality to the AssociatedObject.
        /// </remarks>
        protected override void OnAttached()
        {
            base.OnAttached();

            // Hook events to change behavior
            _expression = AssociatedObject.GetBindingExpression(TextBox.TextProperty);
            AssociatedObject.TextChanged += OnTextChanged;
        }

        /// <summary>
        /// Called when the behavior is being detached from its AssociatedObject, but before it has actually occurred.
        /// </summary>
        /// <remarks>
        /// Override this to unhook functionality from the AssociatedObject.
        /// </remarks>
        protected override void OnDetaching()
        {
            base.OnDetaching();

            // Un-hook events
            AssociatedObject.TextChanged -= OnTextChanged;
            _expression = null;
        }

        /// <summary>
        /// Updates the source property when the text is changed.
        /// </summary>
        private void OnTextChanged(object sender, EventArgs args)
        {
            _expression.UpdateSource();
        }
    }
}

这基本上是Microsoft Prism 4.1代码的清理版本(如果您想浏览其余部分,请参阅Silverlight \ Prism.Interactivity项目。)

现在该如何使用它:

  1. 将对System.Windows.Interactivity程序集的引用添加到Windows Phone项目中。
  2. 在要使用该行为的每个页面中,向程序集添加XAML引用: 的xmlns:I = “CLR-名称空间:System.Windows.Interactivity;装配= System.Windows.Interactivity”
  3. 在要应用bahvior的每个TextBox的XAML中(已经对源属性进行了TwoWay绑定),添加以下内容:

    &LT; I:Interaction.Behaviors&GT;
        &lt; my:UpdateTextBindingOnPropertyChanged /&gt;
    &LT; / I:Interaction.Behaviors&GT;

    注意:代码中的“my:”前缀可能有所不同。它只是您添加行为类的命名空间参考。

答案 5 :(得分:5)

尝试将UpdateSourceTrigger属性设置为&#39; PropertyChanged&#39;

像这样

Property="{Binding PropertyBinding, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"

答案 6 :(得分:1)

我没有试过@Praetorian的答案,所以如果效果很好那么就这样做 - 否则,使用KeyUp和TextChanged事件来更新Binding源。

答案 7 :(得分:0)

此链接有一个在WinRT中完美运行的解决方案。他继承了TextBox并添加了一个新属性:BindableText。

http://www.familie-smits.com/post/2012/07/29/UpdateSourceTrigger-in-WinRT.aspx