25/9/2007 21:54 El Bruno

[DSL] Como agregar un menu personalizado

Buenas,

siguiendo con la lista de las tareas más comunes que realizamos o aunque sea tratamos cuando trabajamos con las Domain Specific Language Tools es agregar un menú personalizado dentro del IDE de Visual Studio 2005.

Como siempre el mejor lugar para poder encontrar una referencia es MSDN, pero sin embargo no existe un ejemplo end-to-end para poder completar esta tarea. Es por esto que el siguiente tutorial, partirá desde el último ejemplo de un proyecto DSL para la gestión de Proyectos y Usuarios, y sobre el diseñador agregaremos un menú contextual que muestre información sobre el o los elementos seleccionados.

 

Tutorial

  1. Trabajaremos sobre el proyecto DslPackage.
  2. Editar el archivo DslPackage \\ CtcComponents \\ Commands.ctc
    (es conveniente refrescar algunos conociemientos de hace algun tiempo para comprender la sintaxís de este archivo, pero siempre es bueno volver a la fuente)
  3. Después de la sección de los includes, agregamos 2 #defines para referenciar nuestro nuevo elemento del menú.
  4. El primer elemento definirá un id unívoco para el menú y el segundo elemento identificará al ícono que se le asignará al menú.
    #define displaySelectedItemInformation 0x801 #define IconDslMenu guidOfficeIcon:msotcidMergeToDocument
  5. Para la imagen del menú he utilizado uno de los 7000 iconos disponibles que trae Office y que podemos encontrar en el archivo "..\Program Files\Visual Studio 2005 SDK\2007.02\VisualStudioIntegration\Common\Inc\office10\msobtnid.h", incluido dentro de la definición del archivo Commands.ctc. De este archivo he seleccionado la entrada 159 que representa al Label: "&Merge to Document"
  6. Dentro de la sección BUTTONS_BEGIN agregamos la definición para la creación de nuestro menú.
    BUTTONS_BEGIN GENERATED_BUTTONS // Add additional button definitions here. // Command, Parent Group, Priority, Image, Type, Visibility, Text; //guidCmdSet:displaySelectedItemInformation, guidCmdSet:grpidContextMain, 0x0100, OI_NOID, BUTTON, DIS_DEF, "&Display Selected Item Information"; guidCmdSet:displaySelectedItemInformation, // Command ID guidCmdSet:grpidContextMain, // Group ID 0x0100, // Priority IconDslMenu, // Icon ID BUTTON, // Button Type 0, // Flags "&Display Information", // Command Text "&Display Information", // Menu Text "Display Selected Item Information", // ToolTip Text "Display Selected Item Information", // Command Well Text "DisplayImformation", // English Command Name "DisplayImformation"; // Localized Command Name BUTTONS_END

    la definición de cada nuevo elemento que querramos agregar se comprende de una serie de valores que identifican el elemento, el elemento superior, la prioridad, el icono del mismo, el tipo de elemento, la visibilidad, y el texto. La definición completa de los elemento en esta sección se explica en el MSDN en este link.
  7. A continuación editamos el archivo DslPackage \\ GeneratedCode \\ Package.tt; y modificamos la definición de los menues que agregaremos incrementando el parametro contador como la cantidad de menúes que queremos agregar. En este caso es igual a 1:
    [VSShell::ProvideMenuResource(1000, 1)]
  8. Transformamos todos los templates desde el Solution Explorer (o alguna ruta alternativa)
  9. Agregamos una nueva clase al proyecto llamada Dsl15CommandSet.partial.cs. Este archivo implementará una clase parcial para la clase Dsl15CommandSet.
  10. Dentro de esta clase agregaremos una constante que represente nuestro menú y que coincida con el valor del menu que creamos en el Commands.ctc. Por ejemplo:
    #region Command ID constants // Must be unique within this DSL. // Must equal the values defined in Commands.ctc private const int displaySelectedItemInformation = 0x801; #endregion
  11. Sobreescribiremos la función GetMenuCommands(), donde agregaremos un nuevo menu referenciado al id que creamos en el paso anterior. Para la creación del CommandId utilizo un helper llamado CustomCommandId():
    /// <summary> /// Register event handlers for menu commands. Called once when the DSL designer starts. /// </summary> /// <returns></returns> protected override IList<System.ComponentModel.Design.MenuCommand> GetMenuCommands() { // Get the commands defined in the generated code. global::System.Collections.Generic.IList<global::System.ComponentModel.Design.MenuCommand> commands = base.GetMenuCommands(); CommandID cmdId = CustomCommandId(displaySelectedItemInformation); // Unique Id for this command // Add command handlers for menu items to change an Association's sort. // Each command has two handlers: // OnStatus... which determines whether the command should appear on the menu // OnMenu... which performs the command DynamicStatusMenuCommand displaySelectedItemMenu = new DynamicStatusMenuCommand( new EventHandler(OnPopUpMenuDisplayAction), new EventHandler(OnPopUpMenuClick), cmdId); displaySelectedItemMenu.Text = "&Display Selected Item Information"; // add new PopUpMenu commands.Add(displaySelectedItemMenu); // Registration of more command handlers if required go here... return commands; } /// <summary> /// Helper to create local CommandIDs. /// The integer ID is qualified with a Guid for this DSL, so as to ensure /// the ID is unique in the system. /// </summary> /// <param name="command">Command number within this language</param> /// <returns></returns> private CommandID CustomCommandId(int command) { return new CommandID(new Guid(Constants.Dsl15CommandSetId), command); }
  12. Finalmente debemos agregar 2 EventHandlers para gestionar la visibilidad del elemento en tiempo de ejecución (OnPopUpMenuDisplayAction) y para gestionar el evento Click del mismo (OnPopUpMenuClick). En el evento Click recorreremos la lista de elementos seleccionados y crearemos un string con el contenido de los mismos para mostrarlo en un MessageBox.
    #region Handlers for New PopUpMenu internal void OnPopUpMenuDisplayAction(object sender, EventArgs e) { MenuCommand command = sender as MenuCommand; // The popmenu command is always visible command.Visible = true; command.Enabled = true; } internal void OnPopUpMenuClick(object sender, EventArgs e) { MenuCommand command = sender as MenuCommand; StringBuilder sb = new StringBuilder(); foreach (object selectedObject in this.CurrentSelection) { sb.AppendLine("Selected Object: " + selectedObject.ToString()); } System.Windows.Forms.MessageBox.Show(sb.ToString()); } #endregion
  13. Compilamos la solución y cuando ejecutamos la misma podremos ver, si desplegamos el menu contextual sobre el diseñador la nueva opción:


  14. Si seleccionamos los 3 elementos de usuario y presionamos el menú que recién hemos creado veremos el mensaje con la información de los elementos seleccionados:


Proyecto de ejemplo

El proyecto de ejemplo se puede descargar desde aquí y un pequeño video para mostrar el resultado final del proyecto.

 


Video: DSL - Add new menu item

 

Update: como validar la visualización del elemento http://elbruno.com/blogs/elbruno/archive/2007/12/12/dsl-como-agregar-un-menu-personalizado-2da-parte.aspx

 

Saludos @ Home

El Bruno

Crossposting from ElBruno.com
Archivado en: ,,
Comparte este post:

# re: [DSL] Como agregar un menu personalizado

Wednesday, December 12, 2007 12:05 PM by Paola

muy interesante