Archive for April, 2008

Smart Client Software Factory - April 2008 Release ya esta disponible

Finalmente después de publicar la versión Alpha, la versión Beta y la Release Candidate 1 en Codeplex, ayer se publicó la versión release en MSDN.

Installer

Lo nuevo en esta versión

Known Issues

Publicamos un artículo en la Knowledge Base de SCSF con los Known Issues del presente release:

Habilitar soluciones creadas con SCSF - May 2007

Para habilitar las soluciones creadas con Smart Client Software Factory - May 2007 en esta nueva versión, seguir los pasos explicados en el siguiente artículo:

Documentacion disponible On Line

Toda lo documentación de Smart Client Software Factory - April 2008 fue publicada en MSDN. Esto ayuda a lo usuarios a encontrar lo que necesitan más rápidamente y también a evaluar el contenido de la Factory antes de descargarla y/o instalarla.

Usted puede accederla desde aquí.

MSDNDocumentation

Download disponibles

SCSF Contrib Release 1.5 Just Published!

We have just published a new relase for the Smart Client Contrib project.

logosc


New Features

  • All solutions and projects were migrated to Visual Studio 2008 and .NET Framework 3.5.
  • The DockPanelWorkspace and FormWorkspace workspaces were added to SCSFContrib.CompositeUI.WinForms project.
  • Action Catalog Service was added to SCSFContrib.Services project.
  • Visual Studio templates and Installer were added for Trusted and Untrusted modules in the WPF CAB Shell.

New Samples

  • New BankTeller implementation migrated to WPF CAP Shell.
  • Demo Application with its Demo Script that provides step-by-step instructions to create a CAB and SC-SF application.
  • OrdersManager application that demonstrates how to integrate CAB and SC-SF with Windows Workflow Foundation.
  • TestSuite reference application showing DockPanelWorkspace workspace usage.
  • WPF CAB Shell sample application (source code, libs and unit tests).

640x474.aspx

Download it from here.

Versión Alpha de SCSF April 2008 con soporte para Visual Studio 2008 ya está disponible

Ayer se publicó el primer drop the Smart Client Software Factory April 2008 con soporte para Visual Studio 2008 y .NET Framework 3.5.

Lo nuevo

  • Este release de Smart Client Software Factory incluye soporte solo para Visual Studio 2008 (no soporta Visual Studio 2005).
  • Se fixearon algunos de los bugs identificados por la Comunidad
  • Requiere Guidance Automation Extensions – February 2008 release.
  • La Guidance Package de April 2008 puede correr side-by-side con la de May 2007.

Note: Este es una versión alpha y todavía tiene bugs conocidos. Todavía no terminamos de testear la factory completamente. Úselo bajo su propio riesgo.

Known issues

  • Si el código fuente de SCSF es instalado en el path que se especifica por default, al compilar la solución Quickstarts.WPFIntegration.sln se encontrará con un error: path too long error.
  • Si el código fuente de SCSF es instalado en el path path que se especifica por default, al compilar el Guidance Package (GuidancePackage.sln) se encontrará con un error: path too long error.
  • Correr en modo debug los unit tests del proyecto CompositeUI.WPF.Tests (en la solución CompositeUI-WPFExtensions.sln) producirá un error.

El feedback es bienvenido! 

Descargar SCSF April 2008 versión Alpha.

 

Introducción a Composite UI Application Block (CAB) VI - Commands

Introducción

Las aplicaciones de Windows a menudo presentan situaciones donde más de un control realiza la misma acción. Por ejemplo un ítem de un menú y un botón de la barra de herramientas pueden ambos ejecutar el método SaveFile para guardar un archivo. Composite UI Application Block resuelve estas situaciones utilizando el concepto de comandos (Commands). Los comandos permiten, entre otras cosas, implementar un solo handler y asociarlo con más de un UIElement y/o asociar un UIElement con más de un handler. La Figura 1 muestra un escenario posible.

UsosDeLosComandos

Figura 1
Dos botones diferentes que ejecutan la misma acción para el evento Click.

Los comandos de CAB son una implementación del patrón de diseño Command. Este patrón permite desacoplar el código que ejecuta el comando, del código que lo invoca. Para entender el diseño e implementacón de este patrón en CAB, hay que tener en cuenta a las siguientes clases:

Clase Características
Command Es la clase que representa a un comando. Utiliza CommandAdapters para poder manejar distintos tipos de invocadores de comandos. La clase WorkItem contiene la colección Commands donde se van guardando todos los comandos creados en la aplicación. Cada comando está identificado en esta colección con un string como ID.
CommandAdapter Es una clase abstracta que define la lógica e interfaz necesaria para que un objeto pueda ser registrado como un invocador de un comando.
EventCommandAdapter Clase genérica que extiende a CommandAdapter. Esta implementación dispara un evento cuando el comando es lanzado.
CommandAdapterMapService Servicio que implementa la interfaz ICommandAdapterMapService usado para realizar el mapeo entre un CommandAdapter y un determinado tipo de invoker.

Uso de los Comandos

Como se pudo ver en previos post, cuando un módulo se carga puede agregar ítems al Shell utilizando la colección UIExtensionSites del WorkItem. La clase WorkItem además posee la colección Commands donde se almacenan todos los comandos identificándolos con un string de ID. El siguiente código muestra cómo agregar un botón a la barra de herramientas del Shell y registrarlo como invocador del comando cuyo ID es “SaveCommand“.

[C#]

private void ExtendToolStrip()

{

ToolStripButton saveButton = new ToolStripButton(”Save”);

RootWorkItem.UIExtensionSites["MainToolStrip"].Add(saveButton);

RootWorkItem.Commands["SaveCommand"].AddInvoker(saveButton, “Click”);

}

[Visual Basic]

Private Sub ExtendToolStrip()

Dim saveButton As ToolStripButton = New ToolStripButton(”Save”)

RootWorkItem.UIExtensionSites(”MainToolStrip”).Add(saveButton)

RootWorkItem.Commands(”SaveCommand”).Add(saveButton, “Click”)

End Sub

La registración de invocadores de comandos se logra mediante el método AddInvoker de la clase Command. A continuación se muestra la declaración del método de esta clase.

[C#]

public virtual void AddInvoker(object invoker, string eventName);

[Visual Basic]

Public Overridable Sub AddInvoker(ByVal invoker As Object, ByVal eventName As String)

El parámetro invoker es el UIElement que será invocador del comando y el parámetro eventName es el nombre del evento del invoker que disparará el comando (por ejemplo el evento “Click”). El objeto invoker debe contener entre sus atributos al evento especificado en eventName pues sino se lanzará una excepción.

Nota:
CAB provee soporte de CommandAdapters solo para las clases ToolStripItem y Control y sus descendientes (ver las clases ToolStripItemCommandAdapter y ControlCommandAdapter). Para poder registrar otros tipos de objetos como invocadores de comandos, será necesario implementar los correspondientes CommandAdapter y registrarlos en el servicio CommandAdapterMapService.

Hasta ahora vimos cómo se registran los comandos. Pero ¿cómo se identifica a los métodos que queremos que se ejecuten cuando un comando es lanzado?

Para identificar a los métodos que se ejecutarán cuando se dispare el comando se los debe marcar con el atributo [CommandHandler] especificando el ID del comando con el que cual se lo quiere asociar. El siguiente código registra al método SaveButton_Click como handler del comando “SaveCommand”.

[C#]

[CommandHandler("SaveCommand")]

public void SaveButton_Click(object sender, EventArgs e)

{

// TODO: Save application’s state.

}

[Visual Basic]

<CommandHandler(”SaveCommand”)> _

Public Sub SaveButton_Click(ByVal sender As Object, ByVal e As EventArgs)

‘ TODO: Save application’s state.

End Sub

Como se puede observar en el código anterior, el identificador de visibilidad del método debe ser public.

Para lograr el correcto funcionamiento de los comandos, la clase en donde se agregan los objetos invocadores de comandos debe ser construida a partir de un WorkItem descendiente (o el mismo) del que construyó la clase que contiene a los métodos marcados con el atributo [CommandHandler]. De lo contrario no se encontrarán los comandos requeridos en la colección Commands.

Una última característica a tener en cuenta es que no se puede decidir qué parámetros pasar a los handlers de los comandos debido a que no se tiene control desde nuestro código de cómo y cuando estos se lanzarán. Si lo que se necesita es pasar parámetros al handler entonces es recomendable usar la funcionalidad Event Broker en lugar de comandos (este sistema se verá en más detalle en próximos post).

¿Cómo funciona el atributo [CommandHandler]?

Para responder esta pregunta primero debemos introducirnos a ObjectBuilder.

ObjectBuilder es una fábrica abstracta de objetos. CAB utiliza este framework como base para construir a todos los objetos e implementar el patrón Dependency Injection. Es por eso que para crear objetos en una aplicación CAB no se debe utilizar new, sino que se debe utilizar, por ejemplo, el método genérico AddNew.

ObjectBuilder posee un un pipeline por donde pasan los objetos durante su etapa de construcción. Este pipeline está dividido en distintas etapas donde se van ejecutando distintas Strategies (clases que realizan una parte del proceso de construcción) y Policies (objetos usados por las Strategies para customizar sus acciones y para pasar a la siguiente en la cadena).

ObjectBuilder define las siguientes etapas para la construcción de un objeto, las cuales suceden en el siguiente orden:

  • PreCreation
  • Creation
  • Initialization
  • PostInitialization

CAB agrega a la cadena de Strategies la clase CommandStrategy la cual se ejecuta durante la etapa de Initialization. Esta strategy busca por reflection dentro del objeto que se está construyendo a todos los métodos marcados con el atributo [CommandHandler] y los registra en la colección Commands del WorkItem (con el ID correspondiente).

Para más información acerca de ObjectBuilder recomiendo la lectura de los siguientes artículos (en inglés):

Alcance de los Comandos

Hay casos donde la disponibilidad de un comando depende del estado de la aplicación. Por ejemplo el botón Copiar de la barra de herramientas en un editor de textos estará deshabilitado si no hay ningún texto seleccionado. En una aplicación normal esto se logra modificando acordemente la propiedad Visible en cada ítem de la barra de herramientas. CAB provee una forma de realizar esta tarea indirectamente usando los comandos. Esto permite que si hay más de un UIElement que invocan al mismo comando, entonces todos se actualizarán acordemente.

Cada comando presenta la propiedad Status a la cual se le puede asignar cualquiera de los siguientes valores:

  • Enable: El CommandAdapter deberá mostrar el UIElement.
  • Disable: El CommandAdapter deberá deshabilitar el UIElements (o una operación equivalente disponible). En general el elemento estará visible pero no disponible para su uso.
  • Unavailable: El CommandAdapter deberá ocultar el UIElements (o una operación equivalente disponible). En general el elemento no estará visible y obviamente tampoco disponible para su uso.

Cuando el valor de esta propiedad cambia, cada CommandAdapter relacionado con el su UIElement aplica los cambios correspondientes de la manera apropiada.

El siguiente código muestra cómo se usa esta propiedad en el comando cuyo ID es “SaveCommand”:

[C#]

// CommandStatus es un tipo enumerado con los posibles estados

// de un comando.

// Habilita al comando.

WorkItem.Commands["SaveCommand"].Status = CommandStatus.Enabled;

// Deshabilita el comando.

WorkItem.Commands["SaveCommand"].Status = CommandStatus.Disabled;

// Oculta y deshabilita al comando.

WorkItem.Commands["SaveCommand"].Status = CommandStatus.Unavailable;

[Visual Basic]

‘ CommandStatus es un tipo enumerado con los posibles estados

de un comando.

‘ Habilita al comando.

WorkItem.Commands(”SaveCommand”).Status = CommandStatus.Enabled

‘ Deshabilita el comando.

WorkItem.Commands(”SaveCommand”).Status = CommandStatus.Disabled

‘ Oculta y deshabilita al comando.

WorkItem.Commands(”SaveCommand”).Status = CommandStatus.Unavailable

La Figura 2 muestra una sucesión de screenshots de una aplicación donde se han aplicado los tres estados posibles al comando Save.

500x155.aspx

Figura 2
La secuencia corresponde primero al comando habilitado, luego al comando deshabilitado y por último al comando oculto.

En el próximo post explicaré en detalle cómo se implementan los servicios en CAB.