curso wpf data-binding mvvm command

curso - relay command wpf



Problema extraño donde el botón no se vuelve a habilitar a menos que se haga clic en el mouse (3)

Mi aplicación está escrita usando el patrón MVVM en WPF, y todos mis botones usan enlaces de comando para ejecutar código en mi modelo. Todos los comandos tienen código en CanExecute para determinar el estado habilitado del botón enlazado. La lógica funciona perfectamente, pero en todos los casos, la GUI permanece en estado desactivado a menos que haga clic en otro lugar en la GUI.

Por ejemplo, tengo un botón llamado Discard Candy. Cuando hago clic en este botón, se inicia un proceso en una secuencia de subprocesos, que establece una propiedad bool llamada Ejecutar en verdadero . Dado que el método CanExecute para el comando Discard Candy se parece a esto

public bool CanExecute(object parameter) { return !Running; }

el botón se desactivará una vez que comience el proceso. El problema es que cuando el proceso finaliza, Running se configura como falso , pero la GUI no se actualiza, es decir, Discard Candy no se vuelve a habilitar.

Sin embargo, si hago clic en cualquier parte de la GUI, como en la ventana o la barra de título, el botón Discard Candy se activa de repente. Entonces la lógica funciona, pero está sucediendo algo que simplemente no entiendo. ¿Puede alguien explicarme este comportamiento?

EDITAR - hasta ahora, parece que CommandManager.InvalidateRequerySuggested no ha ayudado a las personas. Voy a intentarlo, pero por el momento soy un poco cauteloso. Seguí los enlaces recomendados y, al hacerlo, decidí leer más sobre el juego de herramientas ligeras MVVM. Suena muy bien. ¿Alguien lo ha usado aquí y ha podido confirmar que no muestra el problema que he visto hasta ahora? Aunque planeo probar el juego de herramientas ligero MVVM en la próxima gran revolución. de mi aplicación, no quiero rehacer todos los comandos que tengo actualmente, por lo que es probable que comience con CommandManager.InvalidateRequerySuggested para que todos podamos obtener otro punto de datos con respecto a su utilidad.

EDIT # 2 : muy interesante, el juego de herramientas MVVM light se basa en CommandManager.InvalidateRequerySuggested para admitir la capacidad de la interfaz de usuario para deshabilitar / volver a habilitar comandos. El autor dice:

"En sentido estricto, en WPF, y si su comando está vinculado a un control que está vigilado por CommandManager, no debería tener que plantear el evento CanExecuteChanged usted mismo. Puede dejar que CommandManager maneje la situación. Dicho esto, los eventos externos podrían también cambia el estado de la IU. Imaginemos que la UI debe habilitarse de 9 a.m. a 5 p.m., y luego deshabilitarla por la noche. El usuario no está activando la IU, por lo que el código debe solicitar (educadamente) que el CommandManager vuelva a consultar al estado de los comandos. Esto se hace llamando al método InvalidateRequerySuggested en el CommandManager. Y como ya habrás adivinado, el método RaiseCanExecuteChanged de la clase RelayCommand hace precisamente eso. "


WPF no actualiza los controles vinculados a comandos a menos que tenga una razón para hacerlo. Al hacer clic en la GUI, WPF se actualiza para que la actualización funcione.

Puede realizar manualmente una actualización de los controles vinculados a comandos llamando a CommandManager.InvalidateRequerySuggested .


En ocasiones, establecer el foco en el control principal hace que el CommandManager active CanExecute. Pruebe lo siguiente después de configurar Running a false:

... Running = false; parentControl.Focusable = true; parentControl.Focus();


Mi problema parecía estar vinculado a la vinculación de comandos: utilicé RelayCommand como hago frecuentemente, pero la reproducción de un botón simplemente no era correcta hasta que hice clic en una ventana.

Eliminar el código CanExecute del CommandBinding y usar una propiedad IsEnabled en lugar de eso resolvió mi problema sin un dolor de cabeza, solo tomó una eternidad hasta que intenté con este entre tantas otras cosas que podrían haber sido el problema ...