首页 文章

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

提问于
浏览
43

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

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

8 回答

  • 1

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

  • 7

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

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

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

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

    基本上,将 BindingUpdateSourceTrigger 属性设置为 Explicit . 然后,在 TextBoxTextChanged 回调中,更新绑定源 .

  • 56

    我正朝着@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属性的默认值是LostFocus .

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

    希望有所帮助!

  • 5

    以下是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项目) .

    现在该如何使用它:

    • 将对System.Windows.Interactivity程序集的引用添加到Windows Phone项目中 .

    • 在要使用该行为的每个页面中,向程序集添加XAML引用:xmlns:i = "clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

    • 在要应用bahvior(已经具有与源属性的TwoWay绑定)的每个TextBox的XAML中,添加以下内容:

    <I:Interaction.Behaviors>
    <my:UpdateTextBindingOnPropertyChanged />
    </i:Interaction.Behaviors>

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

  • 6

    尝试将 UpdateSourceTrigger 属性设置为'PropertyChanged'

    像这样

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

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

  • 0

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

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

相关问题