Ответ 1
Вы можете использовать поведение UpdateTextBindingOnPropertyChanged
из Prism Library для WP7, чтобы обновить связанное значение, когда текст изменяется вместо потерянного фокуса.
У меня есть страница с некоторыми текстовыми полями для ввода данных. Для привязки текстового поля установлено значение TwoWay
. Данные в моей модели просмотра обновляются, только если текстовое поле теряет фокус. Если я нажимаю кнопку, например сохранение, а текстовое поле все еще имеет фокус, изменения в текстовом поле не изменяются в моей модели просмотра в событии сохранения.
Есть ли способ привязки сохранить значение текстового поля до того, как он потеряет фокус? Или мне нужно что-то сделать в событии сохранения?
Вы можете использовать поведение UpdateTextBindingOnPropertyChanged
из Prism Library для WP7, чтобы обновить связанное значение, когда текст изменяется вместо потерянного фокуса.
Я предполагаю, что ваша кнопка "Сохранить" - это ApplicationBarButton (не обычная кнопка). Для обычных кнопок это будет просто работать, потому что они фокусируются, и, следовательно, привязка данных начнется.
Для ApplicationBarButtons на телефоне это немного отличается, потому что они не отвлекают внимание от клиентского приложения. Чтобы обеспечить принудительное связывание данных при нажатии кнопки "Сохранить", вы можете добавить в свой обработчик следующий код:
object focusObj = FocusManager.GetFocusedElement();
if (focusObj != null && focusObj is TextBox)
{
var binding = (focusObj as TextBox).GetBindingExpression(TextBox.TextProperty);
binding.UpdateSource();
}
Скачать бесплатную книгу Чарльза Петцольда Программирование Windows Phone 7. На странице 387 он рассказывает о том, как это сделать.
В принципе, установите для свойства UpdateSourceTrigger
значение Binding
значение Explicit
. Затем в обратном вызове TextBox
TextChanged
обновите источник привязки.
Я иду в противоположном направлении @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. По умолчанию используется значение по умолчанию, которое возвращает значение UpdateSourceTrigger по умолчанию свойства целевой цели. Однако значение по умолчанию для большинства свойства зависимостей PropertyChanged, а текст свойство имеет значение по умолчанию LostFocus.
Помните, это означает, что все, что является триггером обновления к этому свойству, будет происходить гораздо чаще (в основном с каждым нажатием клавиши, вместо одиночного "флеша", когда TextBox
теряет фокус).
Надеюсь, что это поможет!
Вот ответ быстрого доступа к решению 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, если вы хотите просмотреть остальные).
Теперь, как его использовать:
Внутри XAML каждого TextBox, к которому вы хотите применить bahvior (у которого уже есть привязка TwoWay к вашему исходному свойству), добавьте следующее:
< я: Interaction.Behaviors >
< my: UpdateTextBindingOnPropertyChanged/" >
</I: Interaction.Behaviors >
Примечание: префикс "my:" может отличаться в вашем коде. Это просто ссылка пространства имен, в которой вы добавили класс поведения.
попробуйте установить свойство UpdateSourceTrigger
в свойство PropertyChanged
как это
Property="{Binding PropertyBinding, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
Я не пробовал @Praetorian ответ, так что если это хорошо работает, тогда сделайте это - в противном случае используйте события KeyUp и TextChanged для обновления источника привязки.
В этой ссылке есть решение, отлично работающее в WinRT. Он наследует TextBox и добавляет новое свойство: BindableText.
http://www.familie-smits.com/post/2012/07/29/UpdateSourceTrigger-in-WinRT.aspx