Ich habe eine Seite mit einigen Textfeldern für die Dateneingabe. Die Bindung des Textfelds ist auf TwoWay
festgelegt. Die Daten in meinem Ansichtsmodell werden nur aktualisiert, wenn das Textfeld den Fokus verliert. Wenn ich auf eine Schaltfläche wie "Speichern" klicke und das Textfeld immer noch den Fokus hat, werden die Änderungen im Textfeld in meinem Ansichtsmodell beim Speicherereignis nicht geändert.
Gibt es eine Möglichkeit, die Bindung den Wert des Textfelds zu speichern, bevor es den Fokus verliert? Oder muss ich beim Save-Event etwas unternehmen?
Sie können das Verhalten UpdateTextBindingOnPropertyChanged
aus der Prism-Bibliothek für WP7 verwenden, um den gebundenen Wert zu aktualisieren, wenn sich der Text ändert und nicht bei verlorenem Fokus.
Ich gehe davon aus, dass es sich bei Ihrer Save-Schaltfläche um eine ApplicationBarButton-Schaltfläche handelt (keine normale Schaltfläche). Bei normalen Schaltflächen funktioniert das nur, weil sie den Fokus haben und daher die Datenbindung eintritt.
Für ApplicationBarButtons auf dem Telefon ist dies ein wenig anders, da sie sich nicht auf die Client-App konzentrieren. Um sicherzustellen, dass die Datenbindung wirksam wird, wenn Sie auf die Schaltfläche Speichern klicken, können Sie den folgenden Code in Ihrem Handler hinzufügen:
object focusObj = FocusManager.GetFocusedElement();
if (focusObj != null && focusObj is TextBox)
{
var binding = (focusObj as TextBox).GetBindingExpression(TextBox.TextProperty);
binding.UpdateSource();
}
Laden Sie Charles Petzolds kostenloses Buch herunter Programmieren Windows Phone 7 . Auf Seite 387 spricht er darüber, wie das geht.
Setzen Sie die UpdateSourceTrigger
-Eigenschaft von Binding
grundsätzlich auf Explicit
. Aktualisieren Sie dann in dem TextBox
-Callback von TextChanged
die Bindungsquelle.
Ich gehe in die entgegengesetzte Richtung von @Praetorian.
Ihr TextBox
hat einen Standardwert von UpdateSourceTrigger
von LostFocus
. Das bedeutet, dass der Wert nur dann in die ViewModel-Eigenschaft verschoben wird, wenn der Fokus verloren geht.
Sie können den UpdateSourceTrigger auf PropertyChanged setzen:
<TextBox UpdateSourceTrigger="PropertyChanged" Text="{Binding TextViewModelProperty}" />
Von http://msdn.Microsoft.com/de-de/library/system.windows.data.binding.updatesourcetrigger.aspx :
Einer der UpdateSourceTrigger-Werte . Der Standard ist Default und gibt .__ zurück. der Standardwert für UpdateSourceTrigger der Ziel-Abhängigkeitseigenschaft . Der Standardwert für die meisten Abhängigkeitseigenschaften sind PropertyChanged, während der Text Eigenschaft hat einen Standardwert von LostFocus.
Denken Sie daran, dass alles, was durch ein Update dieser Eigenschaft ausgelöst wird, viel häufiger vorkommt (im Wesentlichen bei jedem Tastendruck statt eines einzelnen "Flush", wenn TextBox
den Fokus verliert).
Hoffentlich hilft das!
Hier ist eine schnelle Antwort auf die von Derek vorgeschlagene Microsoft-Lösung. Anstatt alle Prism-Dateien herunterzuladen und zu durchsuchen, kopieren Sie diese Klasse einfach in Ihr Projekt und folgen Sie den nachstehenden Schritten, um sie zu aktivieren:
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();
}
}
}
Hierbei handelt es sich im Wesentlichen um eine bereinigte Version des Microsoft Prism 4.1-Codes (siehe Projekt Silverlight\Prism.Interactivity, wenn Sie den Rest durchsuchen möchten).
Nun, wie man es benutzt:
Fügen Sie in der XAML jeder TextBox, auf die Sie den Bahvior anwenden möchten (der bereits eine TwoWay-Bindung für Ihre Quelleigenschaft hat) Folgendes hinzu:
<i: Interaction.Behaviors>
<mein: UpdateTextBindingOnPropertyChanged />
</ i: Interaction.Behaviors>
Hinweis: Das Präfix "my:" kann sich in Ihrem Code unterscheiden. Es ist nur die Namespacereferenz, in der Sie die Verhaltensklasse hinzugefügt haben.
versuchen Sie, die UpdateSourceTrigger
-Eigenschaft auf 'PropertyChanged' zu setzen.
so was
Property="{Binding PropertyBinding, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
Ich habe die Antwort von @ Praetorian nicht ausprobiert. Wenn dies also gut funktioniert, tun Sie das. Andernfalls verwenden Sie sowohl die KeyUp AND TextChanged-Ereignisse, um die Bindungsquelle zu aktualisieren.
Dieser Link hat eine Lösung, die in WinRT perfekt funktioniert hat. Er erbt TextBox und fügt eine neue Eigenschaft hinzu: BindableText.
http://www.familie-smits.com/post/2012/07/29/UpdateSourceTrigger-in-WinRT.aspx