wake-up-neo.net

TextBox-Bindung TwoWay wird erst aktualisiert, wenn Focus WP7 verloren geht

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? 

43
Josh Close

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.

7
Derek Lakin

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();
}
56

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.

16
Praetorian

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!

7
rrhartjr

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:

  1. Fügen Sie Ihrem Windows Phone-Projekt einen Verweis auf System.Windows.Interactivity Assembly hinzu.
  2. Fügen Sie auf jeder Seite, auf der Sie das Verhalten verwenden möchten, der Assembly eine XAML-Referenz hinzu: Xmlns: i = "clr-namespace: System.Windows.Interactivity; Assembly = System.Windows.Interactivity"
  3. 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.

6
Tony Wall

versuchen Sie, die UpdateSourceTrigger-Eigenschaft auf 'PropertyChanged' zu setzen.

so was 

Property="{Binding PropertyBinding, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
5
Rajiv

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. 

1
PhilChuang

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

0
jlo