2011-04-06 13 views
42

Tengo una página con algunos cuadros de texto para la entrada de datos. El enlace del cuadro de texto está establecido en TwoWay. Los datos en mi modelo de vista solo se actualizan si el cuadro de texto pierde el foco. Si hago clic en un botón, como guardar, y el cuadro de texto todavía tiene el foco, los cambios en el cuadro de texto no cambian en mi modelo de vista en el evento de guardar.Encuadernación del cuadro de texto TwoWay no se actualiza hasta que se perdió el foco WP7

¿Hay alguna manera de que el enlace guarde el valor del cuadro de texto antes de que pierda el foco? ¿O debo hacer algo en el evento guardar?

+0

mismo tema en WP8, @StefanWick respuesta resuelto por mí. –

+1

Aquí puede encontrar una solución de trabajo actualizando el enlace en el evento TextChanged: http://stackoverflow.com/a/4833196/928955 – breigo

Respuesta

7

Puede usar el comportamiento UpdateTextBindingOnPropertyChanged del Prism Library for WP7 para actualizar el valor encuadernado cuando el texto cambia en lugar de en el foco perdido.

+3

Ya estoy usando MVVM Light y no quiero incluir Prism solo por eso. :( –

+0

Bueno, el código fuente también está disponible, así que puedes incluir ese único archivo;) –

+0

Sí, eso es lo que estoy viendo en este momento. No me di cuenta de cuán ligero es el Prism para WP7 en realidad. Puede que tenga que buscar las diferencias entre Prism y MVVM Light. Prism parece tener algunas cosas adicionales que necesito usar. –

16

Descargue el libro gratuito de Charles Petzold Programming Windows Phone 7. En la página 387 habla de cómo hacer esto.

Básicamente, establezca la propiedad UpdateSourceTrigger del Binding en Explicit. Luego, en la devolución de llamada de TextBoxTextChanged, actualice la fuente de enlace.

1

No he intentado la respuesta de @ Praetorian así que si eso funciona bien, entonces hazlo; de lo contrario, utiliza los eventos KeyUp Y TextChanged para actualizar la fuente de enlace.

6

Voy en la dirección opuesta a @Praetorian.

Su TextBox tiene un valor UpdateSourceTrigger predeterminado de LostFocus. Esto significa que el valor solo se envía a su propiedad de ViewModel cuando ... pierde foco.

Puede configurar el UpdateSourceTrigger a PropertyChanged:

<TextBox UpdateSourceTrigger="PropertyChanged" Text="{Binding TextViewModelProperty}" /> 

De http://msdn.microsoft.com/en-us/library/system.windows.data.binding.updatesourcetrigger.aspx:

Uno de los valores UpdateSourceTrigger. El valor predeterminado es Predeterminado, que devuelve el valor predeterminado UpdateSourceTrigger de la propiedad de dependencia de destino. Sin embargo, el valor predeterminado para la mayoría de las propiedades de dependencia es PropertyChanged, mientras que la propiedad Text tiene un valor predeterminado de LostFocus.

Tenga en cuenta esto significa que cualquier cosa que sea de disparo por una actualización a esta propiedad va a pasar con mucha más frecuencia (básicamente con cada pulsación de tecla, en lugar de un único "al ras" cuando el TextBox pierde el foco).

Espero que ayude!

+3

Silverlight no admite el valor 'PropertyChanged' para 'UpdateSourceTrigger'. Ha vinculado el tema de WPF, que no se aplica en WP7. –

+0

Vaya, soy un tipo WPF, ¡así que siempre me olvido de eso! ¡Lo siento! – rrhartjr

+4

Establecer la propiedad Text en Text = "{Binding TextViewModelProperty, Mode = TwoWay, UpdateSourceTrigger = PropertyChanged}" funcionó para mí (estoy usando SL5). –

55

Supongo que su botón Guardar es un Botón de barra de aplicación (no es un botón normal). En el caso de los botones normales, funcionará porque toman el foco y, por lo tanto, se activará el enlace de datos.

Para ApplicationBarButtons en el teléfono, es un poco diferente porque no aleja la atención de la aplicación del cliente.Para asegurar las patadas de enlace de datos en cuando se hace clic con el botón Guardar, se puede añadir el siguiente código en el controlador:

object focusObj = FocusManager.GetFocusedElement(); 
if (focusObj != null && focusObj is TextBox) 
{ 
    var binding = (focusObj as TextBox).GetBindingExpression(TextBox.TextProperty); 
    binding.UpdateSource(); 
} 
+3

Gracias. Es bueno saber la razón por la cual. –

+0

Gracias por esto. Guardamos automáticamente la estructura de datos cada vez que se actualiza la propiedad del texto, y no nos pareció correcto que eso ocurriera para cada golpe de tecla. – dythim

+0

Gracias me ayudó ya que no uso la luz MVVM. – NoobDeveloper

6

Aquí es una respuesta acceso rápido a la solución de Microsoft sugerido por Derek. En lugar de la descarga y tamizado a través de todas las cosas Prisma, simplemente copiar esta clase en su proyecto a continuación, siga los pasos después de activarlo:

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

Ésta es básicamente una versión limpia en marcha de el código Microsoft Prism 4.1 (vea el proyecto Silverlight \ Prism.Interactivity si desea explorar el resto).

Ahora, ¿cómo se usa:

  1. agregar una referencia al ensamblaje System.Windows.Interactivity a su proyecto de Windows Phone.
  2. En cada página en la que desea utilizar el comportamiento, agregue una referencia a la asamblea XAML: xmlns: i = "CLR-espacio de nombres: System.Windows.Interactivity; montaje = System.Windows.Interactivity"
  3. en el interior del XAML de cada cuadro de texto al que desea aplicar el bahvior (que ya cuenta con la unión a su propiedad de origen de un TwoWay), añada lo siguiente:

    < i: Interaction.Behaviors>
    < mi: UpdateTextBindingOnPropertyChanged />
    < /i:Interaction.Behaviors>

    Nota: el prefijo "mi:" puede ser diferente en su código. Es solo la referencia del espacio de nombres donde agregó la clase de comportamiento.

0

Este enlace tiene una solución que funcionó perfectamente en WinRT. Hereda TextBox y agrega una nueva propiedad: BindableText.

http://www.familie-smits.com/post/2012/07/29/UpdateSourceTrigger-in-WinRT.aspx

+0

Extender TextBox no parece una buena idea. En realidad es una muy mala idea. Es la peor Idea, de hecho. Una AttachProperty podría ser mejor. Sin embargo, este tipo de solución te limita a un solo control y esa es una de las razones por las que estoy totalmente en desacuerdo. ¿y si queremos el mismo comportamiento en otro control? –

+0

url incluido caducado – Rajiv

4

intenta establecer UpdateSourceTrigger propiedad a 'PropertyChanged'

como esto

Property="{Binding PropertyBinding, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" 
Cuestiones relacionadas