2009-05-20 19 views
6

Tengo una ventana de WPF que contiene un cuadro de texto. Implementé un comando que se ejecuta en Crtl-S que guarda el contenido de la ventana. Mi problema es que si el cuadro de texto es el control activo y he editado recientemente el texto en el cuadro de texto, los últimos cambios en el cuadro de texto no están comprometidos. Necesito salir del cuadro de texto para obtener los cambios.EndEdit equivalente en WPF

En WinForms, normalmente llamaría a EndEdit en el formulario y se comprometerían todos los cambios pendientes. Otra alternativa es usar el enlace onPropertyChange en lugar de onValidation, pero preferiría no hacerlo.

¿Cuál es el equivalente de WPF a EndEdit, o cuál es el patrón a usar en este tipo de escenario?

Gracias,

Respuesta

4

Para evitar la necesidad de eliminar pestañas, simplemente puede cambiar la propiedad UpdateSourceTrigger del enlace de sus controles. Pruebe lo siguiente:

<TextBox.Text> 
    <Binding Path="MyProperty" UpdateSourceTrigger="PropertyChanged"/> 
</TextBox.Text> 

Esto le indica a WPF para actualizar el objeto respaldo siempre que se cambie la propiedad Text. De esta manera, no necesita preocuparse por quitar las pestañas. ¡Espero que esto ayude!

EDIT:

La respuesta aceptada para la siguiente pregunta SO proporciona una forma de ejecutar automáticamente las reglas de validación de una página. Puede modificarlo para llamar a UpdateSource() en todos los objetos BindingExpression.

Link

+0

que preferentemente no tendría que añadir el UpdateSourceTrigger a todos los cuadros de texto en mi forma, una llamada para asegurarse de que todos los cambios pendientes están 'comprometidos' es lo que estoy buscando. Su sugerencia es como el enlace 'OnPropertyChange'. Es factible, pero también causa más eventos de los que me gustaría ver. Estoy buscando un patrón WPF genérico para resolver este tipo de problema. Gracias por responder. – Thies

1

HI, Bueno, durante el uso de WPF, hay que adoptar para una mentalidad diferente.

Básicamente vincularía la propiedad TextBox's Text a una de mis propiedades (Model, ViewModel, Code-Behind, lo que sea que lo haga feliz). Así que cuando maneja CTRL + S, simplemente va a la propiedad clr que está enlazada y continúa felizmente con todos los datos que desea.

Espero que lo ayuden, si necesita ejemplos de código, déjeme un comentario. Ariel

5

Puede forzar fijaciones específicas para actualizar utilizando código como el siguiente:

var bindingExpression = txtInput.GetBindingExpression(TextBox.TextProperty); 
bindingExpression.UpdateSource(); 

Hacer esto de manera más general es difícil porque no hay manera genérica para obtener todos los enlaces, ni tampoco necesariamente quiere que todos estén actualizados.

+0

Eso probablemente también funcionaría. La respuesta aceptada para la siguiente pregunta SO proporciona una forma de ejecutar automáticamente las reglas de validación para una página. Creo que podría modificarlo para llamar a UpdateSource() en todos los objetos BindingExpression. http://stackoverflow.com/questions/127477/detecting-wpf-validation-errors – Pwninstein

+0

Estoy buscando una solución genérica que no tenga que hacerme cambiar el enlace en todos los formularios. Algo que compromete todas las ediciones en curso. Gracias por responder. – Thies

+0

Esto es exactamente lo que estaba buscando porque tengo algunos comandos de Propiedades Adjuntas que requieren que el texto esté actualizado. –

3

No estoy de acuerdo con ArielBH. El problema aquí es la interacción entre el teclado y el enfoque lógico y, a menos que haya cambiado todos los desencadenantes de actualización de enlace de datos a PropertyChanged, puede omitir algunas actualizaciones de datos de origen en ciertos escenarios (por ejemplo, clics en el botón de la barra de herramientas). Por ejemplo, el desencadenador de actualización predeterminado para TextBox.Text es LostFocus y al hacer clic en el botón de la barra de herramientas no se difumina el foco activo de TextBox.

Si tiene algún mecanismo para registrar los controles, puede forzar explícitamente el enlace de datos para actualizar la fuente en el mismo lugar que llamaría EndEdit en una aplicación de WinForms. No es limpio ni elegante, pero hace el trabajo bien.

Si alguien ha encontrado una solución mejor, también sería todo oídos.

+1

Vea el enlace que publiqué en mi comentario a la respuesta de commongenius para ver un ejemplo de cómo se podría forzar la consolidación de enlaces. De acuerdo, el ejemplo que se muestra no hace exactamente eso, pero podría modificarse fácilmente para hacer exactamente lo que estás sugiriendo. :) – Pwninstein

5

Basado en la respuesta de Pwninstein, ahora he implementado un EndEdit en mi clase común para WPF Views/Windows que buscará enlaces y forzará una actualización de ellos, código debajo;

Código debajo;

private void EndEdit(DependencyObject parent) 
{ 
    LocalValueEnumerator localValues = parent.GetLocalValueEnumerator(); 
    while (localValues.MoveNext()) 
    { 
     LocalValueEntry entry = localValues.Current; 
     if (BindingOperations.IsDataBound(parent, entry.Property)) 
     { 
      BindingExpression binding = BindingOperations.GetBindingExpression(parent, entry.Property); 
      if (binding != null) 
      { 
       binding.UpdateSource(); 
      } 
     } 
    }    

    for(int i=0; i < VisualTreeHelper.GetChildrenCount(parent); i++) 
    { 
     DependencyObject child = VisualTreeHelper.GetChild(parent, i); 
     this.EndEdit(child); 
    } 
} 

protected void EndEdit() 
{ 
    this.EndEdit(this); 
} 

En mi comando Guardar, ahora acaba de llamar al método EndEdit, y no tiene que preocuparse por otros programadores de selección de método de encuadernación.

+0

Editado mi respuesta anterior para incluir mis comentarios. ¡Gracias! Me alegro de que ayudó :) – Pwninstein

+0

He votado a favor. Funciona muy bien, pero causa un problema con la virtualización activada. Cambiar ItemSource hace que las barras de desplazamiento dejen de funcionar. Ver: [http://stackoverflow.com/questions/8107618/datagrid-scroll-bar-stops-working](http://stackoverflow.com/questions/8107618/datagrid-scroll-bar-stops-working) – CrazyIvan1974

1

Creo que se supone que debes declarar un grupo vinculante y luego hacer referencia a ese grupo vinculante en el código. Puse el mío en el elemento de la ventana raíz para que obtenga los enlaces de todos los controles en la ventana.

<Window.BindingGroup> 
    <BindingGroup /> 
</Window.BindingGroup> 

this.BindingGroup.CommitEdit(); 
+0

Gracias para la retroalimentación. Parece prometedor, pero primero tengo que intentarlo. – Thies