2010-04-14 12 views
26

Tengo un diálogo sencillo WPF con estos dos controles:WPF MVVM: Cuadro de texto y botón de enlace predeterminado hace demasiado tarde actualización

<TextBox Text="{Binding MyText}"/> 
<Button Command="{Binding MyCommand}" IsDefault="True"/> 

Ahora, cuando entro en algún texto en el cuadro de texto y haga clic en el botón utilizando el mouse, todo funciona como se esperaba: el TextBox configurará MyText y se llamará MyCommand.

Pero cuando ingreso texto y presiono enter para "hacer clic" en el botón predeterminado, no funciona. Como al presionar Enter el foco no sale del TextBox, el enlace no se actualizará MyText. Entonces, cuando se llama a MyCommand (que funciona), MyText contendrá datos antiguos.

¿Cómo puedo solucionar esto en MVVM? En código clásico detrás probablemente llamaría "MyButton.Focus()" en el controlador MyCommand, pero en MVVM el controlador MyCommand no sabe nada sobre el botón.

¿Y ahora qué?

Respuesta

30

Agregue UpdateSourceTrigger a su TextBox con el valor PropertyChanged. El comportamiento predeterminado de TextBox es actualizar la fuente cuando se pierde el foco.

<TextBox Text="{Binding MyText, UpdateSourceTrigger=PropertyChanged}"/> 
+2

Así que tendría que agregar esto a cada encuadernación (ya que siempre puede haber botones accesibles mis atajos de teclado)? – Sam

2

Una solución ist, para crear su propia clase OKButton que llama Me.Focus en el OnClick-Método. Esto se llamará antes del evento Click_Event y antes de cualquier comando que esté vinculado al botón. Solo tiene que recordar utilizar un OKButton en lugar de establecer IsDefault = True

Public Class OKButton 
    Inherits System.Windows.Controls.Button 

    Public Sub New() 
    MyBase.New() 
    Me.Content = "OK" 
    Me.IsDefault = True 
    End Sub 

    Protected Overrides Sub OnClick() 
    Me.Focus() 
    MyBase.OnClick() 
    End Sub 
End Class 
+0

¿Qué pasa con los botones que no son el botón predeterminado y se activan al usar su atajo alternativo? Esto no funcionaría para ellos. – Sam

5

Pruebe esto. Este código mueve el foco en el botón presionado. Por lo tanto, el enlace se completa antes del comando procesado.

public App() 
    { 
     EventManager.RegisterClassHandler(typeof(Button), Button.ClickEvent, new RoutedEventHandler(GenericButtonClickHandler)); 
    } 

    void GenericButtonClickHandler(object sender, RoutedEventArgs e) 
    { 
     var button = sender as Button; 
     if (button == null) 
      return; 
     if (button.IsDefault) 
      button.Focus(); 
    } 
+0

¿Qué pasa con los botones que no son el botón predeterminado y se activan al usar su atajo alternativo? Esto no funcionaría para ellos. – Sam

+0

Sí, Sam. Está bien 'if (button.IsDefault)' no es aplicable para una solución genérica. – Aleks

+0

Pero la idea de esta solución es capturar todos los clics antes de manipular y establecer el foco en un botón en un solo lugar. Pero no usa 'UpdateSourceTrigger' en ningún control editable en toda la aplicación. – Aleks

Cuestiones relacionadas