two - WPF: los cambios en el cuadro de texto con foco no se cometen hasta después de que el evento de cierre se dispare
wpf binding types (6)
Tengo una ventana de WPF para editar la información de la base de datos, que se representa utilizando un objeto Entity Framework. Cuando el usuario cierra la ventana, me gustaría notar en el evento de Cierre si la información ha cambiado y mostrar un cuadro de mensaje que ofrece guardar los cambios en la base de datos.
Desafortunadamente, los cambios en la edición centrada actualmente no se asignan a la fuente de enlace hasta que la edición pierde el foco, lo que sucede en algún momento después de que se haya procesado el evento de Cierre.
Idealmente, habría una rutina que confirme todos los cambios en la jerarquía de vistas a los que podría llamar antes de verificar si mi entidad ha sido modificada. También busqué información sobre aclarar programáticamente el foco en el control con enfoque, pero no puedo encontrar la manera de hacerlo.
Mi pregunta es, ¿cómo se maneja esto normalmente?
Tal vez necesites quitar el foco del elemento actual
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
FocusManager.SetFocusedElement(this, null);
}
Esto debería acercarte bastante:
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
ForceDataValidation();
}
private static void ForceDataValidation()
{
TextBox textBox = Keyboard.FocusedElement as TextBox;
if (textBox != null)
{
BindingExpression be = textBox.GetBindingExpression(TextBox.TextProperty);
if (be != null && !textBox.IsReadOnly && textBox.IsEnabled)
{
be.UpdateSource();
}
}
}
La forma más fácil es establecer el foco en algún lugar. Puede volver a establecer el foco inmediatamente, pero establecer el foco en cualquier lugar activará el LostFocus-Event en cualquier tipo de control y lo actualizará:
IInputElement x = System.Windows.Input.Keyboard.FocusedElement;
DummyField.Focus();
x.Focus();
Otra forma sería obtener el elemento enfocado, obtener el elemento vinculante del elemento enfocado y activar la actualización manualmente. Un ejemplo para TextBox y ComboBox (necesitaría agregar cualquier tipo de control que necesite admitir):
TextBox t = Keyboard.FocusedElement as TextBox;
if ((t != null) && (t.GetBindingExpression(TextBox.TextProperty) != null))
t.GetBindingExpression(TextBox.TextProperty).UpdateSource();
ComboBox c = Keyboard.FocusedElement as ComboBox;
if ((c != null) && (c.GetBindingExpression(ComboBox.TextProperty) != null))
c.GetBindingExpression(ComboBox.TextProperty).UpdateSource();
En WPF puede cambiar una Binding
para actualizar la fuente en la modificación, en lugar de perder el foco. Esto se hace estableciendo la propiedad UpdateSourceTrigger
en PropertyChanged
:
Value="{Binding Path=MyProperty, UpdateSourceTrigger=PropertyChanged}"
Suponiendo que hay más de un control en la secuencia de pestañas, la siguiente solución parece ser completa y general (solo cortar y pegar) ...
Control currentControl = System.Windows.Input.Keyboard.FocusedElement as Control;
if (currentControl != null)
{
// Force focus away from the current control to update its binding source.
currentControl.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
currentControl.Focus();
}
También mira las sugerencias en esta publicación