我有一个页面,其中包含一些用于输入数据的文本框。文本框的绑定设置为TwoWay
。如果文本框失去焦点,则视图模型中的数据仅会更新。如果单击某个按钮(例如“保存”),并且文本框仍具有焦点,则在保存事件的视图模型中不会更改文本框中的更改。
有没有办法让绑定在失去焦点之前保存文本框的值?或者我是否需要在保存事件中执行某些操作?
答案 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项目。)
现在该如何使用它:
在要应用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