two - WPF MVVM: TextBox y el enlace de botón predeterminado se actualiza demasiado tarde
wpf binding textbox (3)
Tengo un diálogo simple de WPF con estos dos controles:
<TextBox Text="{Binding MyText}"/>
<Button Command="{Binding MyCommand}" IsDefault="True"/>
Ahora, cuando ingreso texto en el TextBox y hago clic en el botón con el mouse, todo funciona como se espera: el TextBox configurará MyText y se llamará MyCommand.
Pero cuando ingreso un 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 arreglo 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é?
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}"/>
Prueba 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();
}
Una solución es, crear su propio OKButton de clase que llame a Me.Focus en el método OnClick. Esto se llamará antes del evento Click_Event y antes de cualquier comando que esté vinculado al botón. Solo tiene que recordar usar 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