データ入力用のテキストボックスがいくつかあるページがあります。テキストボックスのバインドはTwoWay
に設定されます。ビューモデルのデータは、テキストボックスがフォーカスを失った場合にのみ更新されます。保存などのボタンをクリックしても、テキストボックスにフォーカスがある場合、テキストボックスの変更は、保存イベントのビューモデルでは変更されません。
バインディングがフォーカスを失う前にテキストボックスの値を保存する方法はありますか?または、保存イベントで何かをする必要がありますか?
Prism Library for WP7 のUpdateTextBindingOnPropertyChanged
動作を使用して、フォーカスが失われたときではなく、テキストが変更されたときにバインド値を更新できます。
保存ボタンは(通常のボタンではなく)ApplicationBarButtonであると思います。通常のボタンの場合、ボタンがフォーカスを取得し、データバインディングが機能するため、機能します。
電話のApplicationBarButtonsの場合、クライアントアプリからフォーカスを奪わないため、少し異なります。 [保存]ボタンをクリックしたときにデータバインディングが確実に開始されるように、ハンドラーに次のコードを追加できます。
object focusObj = FocusManager.GetFocusedElement();
if (focusObj != null && focusObj is TextBox)
{
var binding = (focusObj as TextBox).GetBindingExpression(TextBox.TextProperty);
binding.UpdateSource();
}
Charles Petzoldの無料の本をダウンロード Programming Windows Phone 7 。 387ページで、彼はこれを行う方法について話します。
基本的に、UpdateSourceTrigger
のBinding
プロパティをExplicit
に設定します。次に、TextBox
のTextChanged
コールバックで、Bindingソースを更新します。
UpdateSourceTrigger
プロパティを 'PropertyChanged'に設定してみてください
このような
Property="{Binding PropertyBinding, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
@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値の1つ。デフォルトはDefaultで、ターゲットの依存関係プロパティのデフォルトのUpdateSourceTrigger値を返します。ただし、ほとんどの依存関係プロパティのデフォルト値はPropertyChangedですが、Textプロパティのデフォルト値はLostFocusです。
これは、このプロパティの更新によってトリガーされるすべてのことがはるかに頻繁に発生することを覚えておいてください(基本的に、TextBox
がフォーカスを失ったときに1回の「フラッシュ」ではなく、キーを押すたびに)。
お役に立てば幸いです。
これが、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バインディングを持っています)に、次を追加します。
<i:Interaction.Behaviors>
<my:UpdateTextBindingOnPropertyChanged />
</ i:Interaction.Behaviors>
注: "my:"プレフィックスはコードによって異なる場合があります。これは、動作クラスを追加した名前空間参照です。
私は@Praetorianの回答を試していないので、うまくいく場合はそれを行います。そうでない場合は、KeyUpイベントとTextChangedイベントの両方を使用してBindingソースを更新します。
このリンクには、WinRTで完全に機能するソリューションがあります。彼はTextBoxを継承し、新しいプロパティBindableTextを追加します。
http://www.familie-smits.com/post/2012/07/29/UpdateSourceTrigger-in-WinRT.aspx