Comandos en WPF
Aunque hace tiempo que comencé a aplicar los comandos de WPF en Precove, cada vez le veo más color. Al principio usaba el comportamiento básico ofrecido por WPF: los comandos son una abstracción intermedia entre un botón (elemento visual) y su manejador (código). En una ventana defines un botón asociado al comando (en lugar de capturar su evento
Click), y en esa misma ventana estableces un CommandBinding que dice qué hacer cuando se ejecute el comando (con un manejador cuyo código está en la misma ventana). También puedes decirle cuándo se puede ejecutar el comando, con CanExecute, lo que automáticamente deshabilita los botones asociados con él. Por supuesto, esta es una de las ventajas, puede haber distintos botones, menús... asociados con un comando; incluso se pueden ejecutar por código, necesario por ejemplo al hacer doble clic en un elemento de una tabla.Ahora lo he ampliado, al descubrir que el código que ejecuta un comando suele ser el mismo independientemente del contexto. Realmente tenemos dos casos: el típico ejemplo del botón Copiar, o más concretamente el botón Nuevo, que según la ventana o control que tenga el foco se comportarán de forma distinta; y el de un botón como Dar Presupuesto, que siempre muestra el asistente como una nueva ventana. Para este segundo caso, he incluido en
Nibi.Presenta una clase abstracta SmartRoutedUICommand, en la que al heredar podemos definir un código estándar para los métodos CanExecute y Execute. Y para que este código se ejecute sin necesidad de añadir un trivial CommandBinding, se ofrece una clase CommandBinder que ofrece una propiedad Command que además de asignar el comando a un botón, crea el CommandBinding con los métodos del comando. Obviamente, sólo se puede usar con comandos SmartRoutedUICommand, que son los que ofrecen un código estándar.Otra ampliación adicional ha sido la utilización de
RoutedUICommand, y su ampliación a ImageRoutedUICommand añadiendo una descripción y una imagen (ImageSource para WPF, realmente es una ruta para cargar la imagen sólo cuando el motor gráfico necesite mostrarla). SmartRoutedUICommand hereda de ImageRoutedUICommand, con lo que ofrece esta información adicional para automatizar su visualización en la barra de botones, como botón suelto, como menú... Para esta visualización, se define un estilo con la clave ToolBar.ButtonStyleKey para que se aplique a todos los botones que se muestren en una barra de herramientas, y que utilice los datos del Command asociado al botón. Así lo botones sólo deben definir esa propiedad, Command, y de ahí se sacan sus propiedades como Imagen, Título y Descripción (para el ToolTip). Este estilo estará por defecto en la aplicación, pero si en un tema se redefine, deberá utilizarse el mismo sistema para obtener y establecer las propiedades a partir del comando.Por último, comentar una pega que me he encontrado con el grid de Xceed. Aunque ellos en su página web informan de que son compatibles con los comandos de WPF, y que incluso ofrecen nuevos comandos como Editar celda que uno puede asociar a sus botones y el grid responde a su ejecución, yo le encuentro una pega mucho más sencilla: la documentación de WPF afirma que los comandos son actualizados en cada cambio en la interfaz. Pues bien, mientras nos movemos por el grid no se actualiza nada. En cambio, si me meto en un textbox que he puesto junto a él, nada más entrar el foco se actualizan los comandos (se ejecutan sus CanExecute). Puede ser culpa de que el grid se encuentra dentro de un control de usuario y el botón fuera, pero el hecho y verdad es que he tenido que repetir el CommandBinding (este no es un Smart...) dentro y fuera de ese control de usuario para que afecte en los dos sitios.
