Command Bindings
Hace unos días un co-equiper de ID Coporate se acercó y me dijo, refiriéndose a un proyecto nuevo en wpf: “voy a implementar, para darle un valor agregado a esta aplicación, un menú contextual para el botón derecho en determinados lugares”. De esta frase se desprende la siguiente entrada, que tiene que con la facilidad de hacer esto dados los command bindings del nuevo framework.
Por qué esto?
Para explicarlo, antes que nada, me voy a referir a cómo era la implementación de esto, por ejemplo, en el framework anterior, para no “duplicar código”.
Supongamos que teníamos un Windows form, con un Window class, una clase de Tareas de aplicación que llamaré para el ejemplo “TareasDeAplicación” y otro componente que se haga cargo de la impresión propiamente dicha (PrinterClass). Para implementar varios “entry points” a una misma tarea (voy a tomar una tarea de impresión, por ejemplo), debíamos crear varios event handler que hagan referencia a la clase TareasDeAplicación y al método correspondiente. Este último delegaría la impresión a un componente a este efecto (PrinterClass). Un diagrama tentativo sería algo así:
Esto que vemos, aunque sabemos que es totalmente aplicable, nos obliga a escribir tantos event handlers como puntos de entrada tengamos que interfacear con el usuario. En este ejemplo en particular estamos armando tres eventhandlers que están haciendo exactamente lo mismo (tareasDeAplicacion.imprimirDocumento()).
Más allá de esto, nosotros estábamos obligados a generar la lógica para habilitar o deshabilitar dichas operaciones en dónde y cuándo correspondiese. Supongamos que vamos a dejarle imprimir una grilla, pero solo cuándo esta tiene datos; de estar vacía dicha grilla, deberíamos deshabilitar el botón, el menú y deberíamos preguntar en el Grid_KeyDown si es que esa grilla está vacía o no antes de ejecutar la operación.
Los command bindings del framework 3.0 nos permiten hacer eso sin necesidad de crear dichos event handlers (y sin el dolor de cabeza de armar la lógica de habilitar y deshabilitar en cada caso). El modelo de commands del framework 3.0 nos deja “adjuntar” cualquier objeto de nuestra aplicación a un command determinado mediante el binding.
Además de poder controlar todo desde un solo lugar (un command) nos permite mantener el estado de habilitación/deshabilitación sincronizado desde el mismo objeto command.
Cómo?
La interfaz de commands del framwork 3.0 (public interface ICommand) nos permite implementar 3 partes para hacer todo esto:
void Execute (object parameter);
bool CanExecute(object parameter);
event EventHandler CanExecuteChanged;
En una implemetación simple como la que tratamos en el ejemplo, el método Execute debería contente la lógica de aplicación (imprimirDocumento()) y será ejecutado por el objeto que haga el binding , en este caso la grilla con el shortcut (ctrl-p), el botón de imprimir y el menú contextual.
El método CanExecute devuelve el estado del comando y deberá contener la lógica de si este puede o no ser ejecutado (por ejemplo, verificar si la grilla – o mejor dicho, si el objeto que contiene la grilla – está o no vacía).
Por último, el evento CanExecuteChanged es levantado cuándo el estado del comando cambió. Esto avisa a los “sources” (el botón o el menú) que tiene que habilitarse o deshabilitarse según corresponda.
Como consecuencia directa de esto, implementar un menú contextual (sobre todo si este estará “imitando” la funcionalidad de un botón que ya existe, y lo que queremos es darle más puntos de entrada al usuario para que nuestra aplicación sea más sencilla de utilizar) es una tarea que nos llevará muy poco tiempo.
Nos vemos,
Sonny
Developer @ ID Corporate Solutions |