MSDN Magazine > Inicio > Todos los números > 2007 > June >  Conceptos básicos avanzados: Uso de Ribbon...
Conceptos básicos avanzados
Uso de RibbonX desde Visual Basic
Ken Getz

En el número de febrero 2007 de MSDN Magazine, Eric Faller demostró cómo crear extensiones para 2007 Microsoft® Office system mediante la API de RibbonX y el marcado XML (consulte msdn.microsoft.com/msdnmag/issues/07/02/RibbonX). En el mismo número, Paul Stubbs presentó los complementos administrados para aplicaciones de 2007 Office system (específicamente, para PowerPoint® 2007) y demostró como puede crearlas con Visual Studio® 2005 Tools para Office Second Edition. En esta columna, continuaré sus excelentes trabajos, tratando de anticiparme a algunas preguntas que probablemente le surgirán cuando trabaje con RibbonX y cree sus propias personalizaciones de la cinta.
Tenga en cuenta que debido a que 2007 Office system o Visual Studio 2005 no ofrecen un diseñador real para la cinta, se requiere un pequeño esfuerzo adicional para crear personalizaciones. No existe una bonita interfaz de usuario para crear sus personalizaciones de cinta, y todo lo que hace se lleva a cabo en XML, con agregado de código compatible ya sea con .NET o bien con Visual Basic® for Applications (VBA). (La próxima versión de Visual Studio Tools para Office ofrecerá un diseñador para la cinta. Si desea obtener más información, consulte el artículo de Steve Fox y Paul Stubbs en este número). Para obtener más información sobre la cinta de 2007 Office system en general, visite msdn.microsoft.com/office/tool/ribbon. Aquí encontrará la información más actualizada de Microsoft para trabajar con la cinta de 2007 Office system y personalizarla.

Preparación
Para trabajar con los distintos controles de la cinta, necesita conocer el identificador (es decir, el atributo msoID) correspondiente a cada elemento de la cinta. Descargue " el documento de 2007 Office System: lista de identificadores de controles". Esta descarga (disponible en formato Excel® 2003 o Excel 2007) incluye una serie de hojas de cálculo que contienen una divulgación completa de cada elemento de la cinta. Sin esta información, la modificación de la cinta existente es casi imposible. Observe que también puede obtener el identificador de cualquier control si desplaza el puntero sobre el mismo en el panel Personalización del cuadro de diálogo Opciones.
Asegúrese de que tiene una copia del esquema XML que describe RibbonX en su equipo de desarrollo. Con este esquema (denominado customUI.xsd), el editor XML de Visual Studio 2005 puede ofrecer IntelliSense® cuando crea el marcado de personalización de la cinta. Puede descargar "2007 Office system: referencia del esquema XML". La descarga incluye tanto el archivo customUI.xsd como material de referencia para éste y otros esquemas que usa 2007 Office system. Una vez descargado y extraído customUI.xsd, cópielo en la carpeta %Archivos de programa%\Microsoft Visual Studio 8\Xml\Schemas. (Reemplace %Archivos de programa% en la ruta de acceso anterior con la ubicación de la carpeta Archivos de programa de su propio equipo). Con el archivo de esquema instalado en esta carpeta, Visual Studio 2005 puede hacer que el esquema esté disponible cuando crea un nuevo archivo de personalización de la cinta.
Si desea almacenar la personalización de la cinta como parte de un documento Word 2007, Excel 2007 o PowerPoint 2007, mediante la atención a las devoluciones de llamada de la cinta en código VBA, debe abrir el documento con una herramienta de administración de archivos ZIP, crear la parte de la personalización y establecer las relaciones necesarias con la parte. Esto supone un gran esfuerzo y se puede evitar si descarga la herramienta Custom UI Editor de OpenXMLDeveloper.org. Aunque la herramienta no lo ayudará a crear personalizaciones de la cinta, será útil de distintas maneras que caben destacar: administra la inserción de la personalización en un documento o plantilla de Word, Excel o PowerPoint, la configuración de partes y relaciones necesarias; puede insertar iconos en el documento para su personalización; valida el marcado de RibbonX con customUI.xsd; y puede generar códigos auxiliares del controlador de devolución de llamada de estilo VBA por lo que no necesita buscar el formato exacto de los procedimientos de devolución de llamada. Incluso si crea un complemento de Visual Studio Tools para Office (VSTO) o un complemento compartido de Visual Studio COM, las dos últimas características pueden ser de gran utilidad.
Por supuesto, necesitará documentación. MSDN® proporciona un conjunto de tres artículos en línea, que cuenta como coautores a Frank Rice y a quién escribe, que ofrecen ejemplos, referencias y respuestas a las preguntas más frecuentes. Estos artículos proporcionan un buen comienzo hasta que Microsoft suministre los archivos de ayuda completos de RibbonX en una ubicación. Encontrará los artículos en la parte 1, parte 2 y parte 3.
Por último, debe considerar dónde almacenará la personalización de la cinta. Como se describe en el primero de los tres artículos, dispone de varias opciones. Puede almacenar el marcado de RibbonX directamente en un documento Word, Excel o PowerPoint si crea una parte de IU personalizada y configura relaciones con la parte; y puede usar la herramienta Custom UI Editor que mencioné anteriormente para facilitar la inserción de la IU personalizada en el documento. Para personalizaciones de la cinta de Access™ 2007, puede almacenar el marcado XML en una tabla y recuperar y activar la personalización mediante código. También puede almacenar la personalización en la tabla USysRibbons y Access la puede cargar igual que una base de datos. Cada una de estas alternativas crea una personalización basada en documentos o plantillas.
Si desea crear una personalización basada en aplicaciones, debe pensar en crear un complemento COM para aplicaciones de 2007 Office system. Para ello, puede crear un complemento mediante una plantilla de un complemento compartido de Visual Studio 2005, o mediante Visual Studio 2005 Tools para Office Second Edition (este es el enfoque más sencillo y más sólido). Nuevamente, el primer artículo de MSDN demuestra cómo usar ambas técnicas.
Contando con todas las herramientas y la documentación, ya está listo para crear sus propias personalizaciones de RibbonX. Aunque es posible que no las use todas a medida que realice los pasos de esta columna, serán de un valor incalculable al crear sus propias personalizaciones.
Debido a que el marcado XML es el mismo independientemente de dónde se almacena el contenido, he elegido la solución más sencilla que permite controlar las devoluciones de llamadas de la cinta mediante código administrado; es decir, crearé un complemento para Excel 2007 mediante VSTO 2005 SE. (Si aún no instaló VSTO 2005 SE, puede obtener información más detallada en el portal del producto en msdn2.microsoft.com/aa905543.aspx y descargarlo desde allí).

Creación de un complemento de ejemplo
Para comenzar, necesita crear y probar un complemento sencillo mediante VSTO 2005 SE. Resumiré rápidamente las instrucciones que se proporcionan en el primero de los tres artículos de MSDN mencionados, creando un complemento de Excel en lugar de uno de Word. Para obtener explicaciones más detalladas, consulte el artículo completo.
Primero, cree un proyecto nuevo en Visual Studio 2005. En el panel Tipos de proyecto del cuadro de diálogo Nuevo proyecto, amplíe el nodo Office y seleccioné Complementos 2007. En el panel Plantillas, seleccione Complemento de Excel. Denomine RibbonAddin al nuevo complemento y haga clic en Aceptar para crearlo. (Observe que la plantilla de complemento crea tanto el proyecto del complemento, como un proyecto de instalación. Por ahora, no tome en cuenta el proyecto de instalación. Aunque facilite la implementación del complemento, no será necesario en esta demostración).
En el menú Proyecto, haga clic en Agregar nuevo elemento y en el cuadro de diálogo, seleccione Compatibilidad con la cinta de opciones. Haga clic en Agregar para aceptar el nombre predeterminado, Ribbon1.vb. Además del archivo Ribbon1.vb, la plantilla agrega un archivo XML denominado Ribbon1.xml que se modificará más adelante. En el menú Proyecto, haga clic en Propiedades de RibbonAddin. Haga clic en la ficha Recursos y, en el explorador de soluciones, arrastre Ribbon1.xml sobre la superficie de diseño de recursos. Cierre la ventana Recursos y guarde los recursos.
En el explorador de soluciones, haga doble clic en Ribbon1.xml para ver su contenido. El marcado predeterminado, que se muestra en la figura 1, crea un nuevo grupo etiquetado como My Group en la ficha Complementos. El grupo contiene un botón de alternar con la etiqueta My Button. Al elegir este botón, se llama al procedimiento de devolución de llamada OnToggleButton1.
<customUI
  xmlns=http://schemas.microsoft.com/office/2006/01/customui
  onLoad=”OnLoad”>
  <ribbon>
    <tabs>
      <tab idMso=”TabAddIns”>
        <group id=”MyGroup”
               label=”My Group”>
          <toggleButton id=”toggleButton1” 
                        size=”large”
                        label=”My Button”
                        screentip=”My Button Screentip”
                        onAction=”OnToggleButton1” 
                        imageMso=”HappyFace” />
        </group>
      </tab>
    </tabs>
  </ribbon>
</customUI>
En el explorador de soluciones, en el archivo Ribbon1.vb, quite el comentario de la clase parcial ThisAddIn. En la clase Ribbon1, modifique el procedimiento GetCustomUI para que devuelva el valor del nuevo recurso de esta manera:
Return My.Resources.Ribbon1
El procedimiento auxiliar GetResourceText provisto abre el contenido XML manualmente y recupera el texto mediante un lector. Puede eliminar el procedimiento en este momento, si lo desea.
En la mayoría de los casos, deberá poder hacer referencia a la aplicación host desde la personalización de la cinta, de modo que en la clase Ribbon1, agregue la siguiente declaración:
Public Application As Excel.Application
También deberá inicializar esta variable, de modo que en el método RequestService de la clase ThisAddIn, agregue la siguiente línea de código inmediatamente después de que el procedimiento crea la instancia de la clase Ribbon1:
ribbon.Application = Application
Amplíe en el código la zona Ribbon Callbacks y examine el procedimiento de devolución de llamada OnLoad:
Public Sub OnLoad(ByVal ribbonUI As Office.IRibbonUI)
    Me.ribbon = ribbonUI
End Sub
Este procedimiento toma el valor Office.IRibbonUI pasado a la instancia Ribbon1 y lo almacena para que las devoluciones de llamada posteriores puedan interactuar también con la cinta. Sin este paso, no podría realizar importantes operaciones como, por ejemplo, actualizar la cinta después de cambiar el contenido de un elemento.
Además, encontrará el procedimiento de devolución de llamada de ejemplo que administra cómo presionar y soltar el botón de alternar creado por el marcado XML. Simplemente muestra una alerta apropiada cada vez que presiona o suelta el nuevo botón de alternar:
Public Sub OnToggleButton1( _
  ByVal control As Office.IRibbonControl, _
  ByVal isPressed As Boolean)
    If isPressed Then
        MessageBox.Show(“Pressed”)
    Else
        MessageBox.Show(“Released”)
    End If
End Sub
Debido a que modifiqué un poco las instrucciones, puede continuar con el artículo original si desea una explicación más completa. Por ahora, guarde y ejecute su proyecto, comprobando que Visual Studio inicia Excel 2007. Seleccione la ficha Complementos y presione y suelte el botón de alternar My Button. En cada caso, observará la alerta mostrada por el complemento.
En el resto de las demostraciones de esta columna, modificará el contenido de Ribbon1.xml y agregará a la clase Ribbon1 procedimientos más complejos de devolución de llamada. Aunque probablemente existe un número infinito de cosas que se pueden realizar con la cinta, tenemos limitaciones de espacio por lo que sólo demostraré dos usos divertidos de la API.
En primer lugar, supondré que desea mostrar su propia galería, que contiene un subconjunto de los colores disponibles, para que los usuarios puedan llenar el fondo de una celda. Para ello, creará su propia galería de colores. La figura 2 muestra qué aspecto tendrá. En segundo lugar, mostraré cómo puede controlar la disponibilidad de su galería de colores mediante una casilla de verificación, tal como se muestra en la esquina superior izquierda de la figura 2.
Figura 2 Creación de su propia galería mediante RibbonX 

Creación de una galería de colores personalizada
Aunque los usuarios pueden seleccionar los colores de relleno de la galería de colores de relleno de Excel, tal como se muestra en la figura 3, quizá desee limitar las opciones de colores a un subconjunto específico. Para ello, puede crear su propia galería de colores. No obstante, si examina la galería de colores de relleno de Excel, quizá advierta que es más sencillo tener acceso a esta galería que a la galería de la figura 2; la diferencia es que la galería de Excel aparece cuando hace clic en el control SplitButton, en cambio la galería que crea debe colgar de un menú. Estaría bien si pudiera crear una galería directamente como un elemento secundario de un botón de división, pero según el esquema customui.xsd, un control SplitButton sólo puede contener un botón o un botón de alternar, junto con un menú. El ejemplo que creará cuelga el control de galería de un sencillo menú.
Figura 3 Galería de colores de relleno de Excel 
Para comenzar a usar el complemento creado, reemplace el contenido de Ribbon1.xml con el marcado según la figura 4. Puede que resulte instructivo escribir realmente este código desde cero, en lugar de copiarlo de la versión en línea de esta columna. Es útil familiarizarse con la manera en que Intellisense ayuda a crear el marcado de RibbonX. Este código crea la personalización al llamar al procedimiento onLoad que ya creó cuando éste se inicia. Además, este marcado crea una nueva ficha denominada demoTab, que muestra el texto "Ribbon Customization". En la ficha, el marcado crea un grupo con la etiqueta "gallery Control", y dentro del grupo, un control splitButton que contiene un botón y un menú. El botón usa el Id. integrado de CellFillColorPicker para proporcionar la imagen. Obtuve el verdadero Id. de este control examinando con detenimiento el libro que contiene los Id. de control de cinta de Excel que descargué del sitio de Microsoft mencionado anteriormente. En este momento, guarde y ejecute el complemento para comprobar el comportamiento.
<?xml version=”1.0” encoding=”utf-8” ?>
<customUI
   xmlns=http://schemas.microsoft.com/office/2006/01/customui
   onLoad=”onLoad”>
  <ribbon>
    <tabs>
      <tab id=”demoTab” label=”Ribbon Customization” >
        <group id=”galleryGroup” label=”gallery Control”>
            <splitButton id=”highlightSplitButton” >
              <button id=”highlightButton” 
                imageMso=”CellFillColorPicker”/>
              <menu id=”highlightMenu” >
              </menu>
            </splitButton>
        </group>
      </tab>
    </tabs>
  </ribbon>
</customUI>
Continúe la modificación del marcado insertando el elemento de la figura 5 en el cuerpo del elemento <menu>. Este marcado crea el control de galería y usa casi todos los procedimientos disponibles de devolución de llamadas del control. En primer lugar, el marcado especifica la etiqueta e indica que el control no debe mostrar etiquetas de elemento (en este ejemplo sólo quiere que aparezcan colores sin etiquetas). Además, el código especifica el número de filas y columnas que se deben mostrar en la galería. El marcado designa el resto de las propiedades de la galería al especificar procedimientos de devolución de llamadas. A medida que Excel 2007 representa la personalización de la cinta, llama a cada uno de los procedimientos enumerados aquí cuando necesita recuperar los datos. (Por ejemplo, llama al método GetItemWidth cuando necesita determinar el ancho de un elemento). Además, el marcado especifica un botón que se muestra en el fondo de la galería. Puede tener el número de botones que desee, pero este ejemplo sólo requiere uno.
<gallery id=”highlightGallery” 
  label=”Select Color”
  showItemLabel=”false”
  columns=”5” rows=”3”
  onAction=”InsertFillColor”
  getEnabled=”GetEnabled” 
  getItemCount=”GetItemCount” 
  getItemHeight=”GetItemHeight” 
  getItemWidth=”GetItemWidth” 
  getItemImage=”GetItemImage” 
  getItemScreentip=”GetItemScreenTip”>
  <button id=”noColorButton” 
    label=”No color” 
    onAction=”RemoveFillColor” 
    screentip=”Remove color” 
    supertip=”Remove any applied color.”/>
</gallery>
Para implementar el comportamiento del control de galería, debe suministrar ahora cada uno de los procedimientos de devolución de llamada enumerados en el marcado. Para ello, abra Ribbon1.vb en la ventana del editor de código y busque la zona Ribbon Callbacks. Aunque no necesita colocar el código en esta zona, esto le ayuda a organizar su código. En los siguientes párrafos le mostraré la creación de cada uno de los procedimientos de devolución de llamada requeridos.
Tenga en cuenta que no tiene necesidad de usar cualquiera de estos procedimientos de devolución de llamada. En cambio, puede suministrar valores estáticos para cada una de las distintas propiedades del control de galería. Es decir, en vez de especificar el atributo getItemHeight en el marcado, puede proporcionar el atributo itemHeight con un valor fijo. Este ejemplo usa código en cada una de estas propiedades, de modo que puede variar dinámicamente el diseño de la galería.
Para mostrar la galería, necesitará una lista de colores, de modo que inserte el código siguiente en la clase Ribbon1:
Private image As New Bitmap(25, 25)
Private colors As Color() = _
  {Color.Yellow, Color.GreenYellow, Color.Turquoise, _
   Color.Magenta, Color.Blue, Color.Red, Color.DarkBlue, _
   Color.Teal, Color.Green, Color.Violet, Color.DarkRed, _
   Color.YellowGreen, Color.Gray, Color.DarkGray, Color.Black}
Este código crea una instancia Bitmap de nivel de clase que usará para crear las distintas imágenes y una matriz de valores Color que representan los diversos colores de relleno. Asegúrese de insertar éste y el resto del código en la clase Ribbon1, y no en la clase parcial ThisAddIn.

Creación de GetEnabled
En la clase Ribbon1.vb, agregue el siguiente procedimiento de devolución de llamada. Este procedimiento coincide con la firma requerida para esta devolución de llamada específica. Si la devolución de llamada no coincide con la firma correcta, las aplicaciones de 2007 Office system no podrán llamar al procedimiento:
Public Function GetEnabled( _
       ByVal control As Office.IRibbonControl) As _
           Boolean

     Dim returnValue As Boolean = False
     Select Case control.Id
       Case “highlightGallery”
         returnValue = True
     End Select
     Return returnValue
   End Function
Para encontrar la firma de éste y de todos los demás procedimientos de devolución de llamada, remítase a la documentación en el tercer artículo del conjunto de tres partes mencionado anteriormente.
2007 Office system pasa una referencia al control que desencadena la devolución de llamada como un parámetro para el método GetEnabled, y el código de ejemplo usa esa información para crear una instrucción Select Case basada en la propiedad de Id. del autor de la llamada. Mediante un patrón de diseño como éste, puede crear un procedimiento único de devolución de llamada GetEnabled que pueda funcionar con cualquier control de cinta que comparta la misma firma del procedimiento de devolución de llamada. En este caso, el procedimiento devuelve simplemente True, lo que indica que la galería debería estar habilitada.

Creación de GetItemCount
La devolución de llamada de getItemCount permite calcular el número de elementos para mostrar en la galería, y debe especificar este procedimiento de devolución de llamada para cada galería que crea, si desea especificar el número de elementos para mostrar. En el complemento, inserte el siguiente procedimiento en la clase Ribbon1:
Public Function GetItemCount( _
 ByVal control As Office.IRibbonControl) As Integer
  Dim returnValue As Integer = 0

  Select Case control.Id
    Case “highlightGallery”
      returnValue = 15
  End Select
  Return returnValue
End Function
Al igual que antes, esta devolución de llamada recibe una referencia al control que la desencadena y devuelve un valor escalar que indica el número de elementos para mostrar en la galería.
Si no le gusta la técnica de incluir un bloque Select Case en cada devolución de llamada, mediante la propiedad de Id. del control que realiza la llamada para determinar el comportamiento del procedimiento puede crear fácilmente un procedimiento separado de devolución de llamada para cada control que comparta una devolución de llamada. Me gusta consolidar de este modo el comportamiento, pero sin duda no se necesita.

Creación de GetItemHeight y GetItemWidth
Su código especifica la altura y el ancho de cada elemento de la galería. Cada elemento debe tener el mismo tamaño y la instancia Bitmap que creó anteriormente controla ese tamaño. Por lo tanto, agregue a la clase Ribbon1 los procedimientos de devolución de llamada de la figura 6 para devolver las dimensiones correctas a Excel.
Public Function GetItemHeight( _
 ByVal control As Office.IRibbonControl) As Integer

  Dim returnValue As Integer = 0
  Select Case control.Id
    Case “highlightGallery”
      returnValue = image.Height
  End Select
  Return returnValue
End Function

Public Function GetItemWidth( _
 ByVal control As Office.IRibbonControl) As Integer

  Dim returnValue As Integer = 0
  Select Case control.Id
    Case “highlightGallery”
      returnValue = image.Width
  End Select
  Return returnValue
End Function

Creación de las imágenes
Aunque puede cargar fácilmente imágenes del disco o de un archivo de recursos para cada elemento de la galería, este ejemplo simplemente necesita bloques de color. Por lo tanto, el procedimiento de devolución de llamada GetItemImage necesita dibujar un bloque sólido del color apropiado para cada elemento de la galería. El procedimiento de devolución de llamada GetItemImage recibe no sólo una referencia al control que desencadena la devolución de llamada, sino también un índice, que indica la imagen que debe devolver. Inserte en la clase Ribbon1 el procedimiento de devolución de llamada mostrado en la figura 7.
Public Function GetItemImage( _
 ByVal control As Office.IRibbonControl, _
 ByVal index As Integer) As Object

  Select Case control.Id
    Case “highlightGallery”
      Using g As Graphics = Graphics.FromImage(image)
        Using brush As New SolidBrush(colors(index))
          g.DrawRectangle(Pens.Gray, _
            New Rectangle(0, 0, image.Width - 1, image.Height - 1))
          g.FillRectangle(brush, _
            New Rectangle(1, 1, image.Width - 2, image.Height - 2))
        End Using
      End Using
  End Select
  Return image
End Function
El procedimiento GetItemImage crea un objeto Graphics del Bitmap que creó anteriormente y crea un nuevo pincel sólido que usa el valor proporcionado para poner índices en la matriz de colores. El código dibuja un rectángulo gris un poco más pequeño que el mapa de bits y, a continuación, rellena el rectángulo con el color apropiado.

Creación de la sugerencia de pantalla y prueba del complemento
Cuando desplaza el mouse sobre cada una de las imágenes, Excel debe mostrar el nombre del color. El procedimiento de devolución de llamada GetItemScreenTip solicita el texto para mostrar en cada imagen y su trabajo es simplemente devolver el nombre de cada color. Aunque por sencillez he elegido usar GetItemScreenTip, GetItemLabel quizá sea una mejor opción porque permite que los usuarios con problemas de vista obtengan las etiquetas de los elementos de la galería, aunque las etiquetas estén visualmente ocultas con el atributo showItemLabel. Los elementos usarán automáticamente sus etiquetas como sugerencias de pantalla si no se proporciona explícitamente ninguna sugerencia de pantalla. Agregue el siguiente procedimiento a la clase Ribbon1 para incorporar este comportamiento:
Public Function GetItemScreenTip( _
 ByVal control As Office.IRibbonControl, _
 ByVal index As Integer) As String

  Dim returnValue As String = String.Empty
  Select Case (control.Id)
    Case “highlightGallery”
      returnValue = colors(index).Name
  End Select
  Return returnValue
End Function
Hasta aquí, ha proporcionado todos los procedimientos de devolución de llamada que se necesitan para mostrar la galería. Guarde y ejecute el proyecto. Visual Studio carga Excel 2007 y cuando selecciona la ficha Personalización de la cinta en la cinta, encontrará el control splitButton. Haga clic en la flecha desplegable, seleccione el elemento de menú y aparecerá la galería. No obstante, si hace clic en cualquier botón de la galería, recibirá un error, ya que todavía no proporcionó el procedimiento de devolución de llamada que administra los clics de botones en la galería. Tiene que salir de Excel y volver a Visual Studio para completar esta parte del complemento.

Adición de devoluciones de llamada Action
El marcado para su personalización incluye dos devoluciones de llamada "action": InsertFillColor para la galería misma y RemoveFillColor para el botón del fondo de la galería. Para evitar los errores que ocurren cuando selecciona un botón en la galería o el botón en el fondo de la galería, agregue a la clase Ribbon1 los siguientes procedimientos de devolución de llamada:
Public Sub InsertFillColor( _
 ByVal control As Office.IRibbonControl, _
 ByVal selectedId As String, ByVal index As Integer)

  CType(Application.Selection, Excel.Range).Interior.Color = _
        ColorTranslator.ToOle(colors(index))
End Sub

Public Sub RemoveFillColor( _
 ByVal control As Office.IRibbonControl)

  CType(Application.Selection, Excel.Range). _
       Interior.Color = Excel.Constants.xlNone
End Sub
Tenga en cuenta que los dos procedimientos usan firmas diferentes: El primer procedimiento administra la devolución de llamada OnAction del control de galería y el segundo administra la devolución de llamada OnAction del control del botón. La devolución de llamada OnAction de la galería proporciona no sólo una referencia al control y el índice del elemento seleccionado dentro de la galería, sino también una cadena que contiene un Id. Este parámetro selectedId es el Id. del elemento seleccionado, mientras que la propiedad Id. del control es la propiedad de la galería misma.
Los procedimientos de devolución de llamada InsertFillColor y RemoveFillColor son específicos de esta galería, de modo que no me molesté en usar un bloque Select Case dentro de los procedimientos. Además, los dos procedimientos convierten el valor Application.Selection a un Excel.Range y establecen la propiedad Interior.Color al color seleccionado, o a ningún color. El método ColorTranslator.ToOle administra la conversión de colores del tipo administrado System.Drawing.Color a colores que VBA y Excel entienden.
Para probar el complemento, guarde una vez más el proyecto y ejecútelo. Cuando selecciona un elemento de la galería, su complemento establece el color de relleno para el intervalo seleccionado al color que seleccionó. Al hacer clic en el botón del fondo de la galería se eliminan todos los colores del intervalo seleccionado.
En este momento, ha creado una personalización sencilla de cinta que resalta varias de las diferentes devoluciones de llamada disponibles. ¿Qué sucede si desea habilitar y deshabilitar la galería, en función de la entrada del usuario? Por ejemplo, ¿qué ocurre si desea tener un control de casilla de verificación en la cinta que le permita controlar la disponibilidad de la galería? Agregaré a continuación esta característica un poco más compleja.

Adición de interacción con el control de la cinta
Si crea una aplicación Windows, es sencillo hacer que una casilla de verificación cambie el estado habilitado de otro control. En el controlador de eventos apropiado, establezca la propiedad Enabled del control y el entorno del tiempo de ejecución se ocupa de los detalles. Aún cuando genera aplicaciones web que usan ASP.NET, no debe preocuparse por los detalles de cómo cambia exactamente el estado habilitado del control; establece una propiedad, y el tiempo de ejecución de ASP.NET administra la representación del control la próxima vez que obligue la actualización de la página.
No obstante, a diferencia de muchos otros entornos, la programación de los controles de la cinta no permite interactuar directamente con las propiedades de los controles. En cambio, lo mejor que puede hacer es establecer el estado de una variable local, invalidar el control cuya propiedad quiere cambiar y hacer que los procedimientos de devolución de llamada del control representen el control en la forma en que lo solicita.
Para demostrar este tipo de comportamiento, agregará un control de casilla de verificación a su personalización de la cinta y hará que el estado activado de la casilla de verificación determine el estado habilitado del control de galería. En el elemento de grupo existente del archivo Ribbon1.xml, bajo el elemento existente splitButton, agregue el siguiente marcado:
<checkBox id=”enableColorsCheckBox” label=”Enable Color Selection?” 
  screentip=”Enable color selection” 
  onAction=”HandlePressedAction”
  supertip=”Select to enable or disable color selection.” 
  getPressed=”GetPressed”/>
El atributo onAction indica qué procedimiento de devolución de llamada desea llamar cuando el usuario activa o desactiva la casilla de verificación, y el atributo getPressed especifica la devolución de llamada que se llamará cuando la cinta inicialice el valor de la casilla de verificación.
En la clase Ribbon1, agregue una variable que puede mantener el estado actual de activación de la casilla de verificación:
Private enableColors As Boolean = False
Modifique el procedimiento existente GetEnabled, para que en vez de devolver simplemente True, el método devuelva el valor de la variable enableColors:
returnValue = enableColors
Para garantizar que el estado del control de casilla de verificación refleje el valor de la variable de enableColors, agregue el siguiente procedimiento de devolución de llamada. La cinta de 2007 Office system llama a este código cuando inicializa el estado del control de casilla de verificación:
Public Function GetPressed( _
 ByVal control As Office.IRibbonControl) As Boolean

  Dim returnValue As Boolean = True
  Select Case control.Id
    Case “enableColorsCheckBox”
      returnValue = enableColors
  End Select
  Return returnValue
End Function
Por último, necesita alguna manera de atender lo que sucede cuando el usuario activa o desactiva la casilla de verificación. El truco es establecer el valor de la variable enableColors y obligar a la cinta a invalidar el control de galería. Al invalidar el control, obliga su reinicialización, con lo cual se establece apropiadamente el estado habilitado del control:
Public Sub HandlePressedAction( _
 ByVal control As Office.IRibbonControl, _
 ByVal pressed As Boolean)

  Select Case control.Id
    Case “enableColorsCheckBox”
      enableColors = pressed
      ribbon.InvalidateControl(“highlightGallery”)
  End Select
End Sub
La línea de código que invalida el control de galería resalta dos aspectos importantes de la automatización de la cinta: En primer lugar, si el complemento no almacenó la referencia a la cinta que se pasó durante su inicialización, no habrá forma de interactuar con la cinta en procedimientos posteriores. Por eso es esencial que el código de la cinta atienda la devolución de llamada OnLoad, almacenando la referencia a la cinta que ésta pasó en una variable de nivel de clase. Además, el código de ejemplo demuestra el método InvalidateControl de la interfaz IRibbonUI. Puede llamar al método InvalidateControl si pasa un control específico para invalidar, o puede llamar al método Invalidate (e invalidar la cinta completa). De cualquier manera, debe llamar a uno de estos procedimientos para avisar a la cinta sobre el hecho que debe volver a trazar uno o todos los controles.
Al igual que antes, guarde y ejecute el proyecto. En Excel 2007, seleccione la ficha Personalización de cinta en la cinta y encontrará la nueva casilla de verificación además del control splitbutton existente. Intente mostrar la galería y encontrará deshabilitado el elemento de menú. Active la casilla de verificación e intente otra vez mostrar la galería, y esta vez está disponible.
Como puede observar, las interacciones entre los controles de la cinta requieren un poco más de trabajo que el esperado, debido a la arquitectura de la cinta misma. Puede reducir el tamaño del código si no piensa agregar ningún otro control a la cinta; la instrucción Select Case en cada procedimiento de devolución de llamada facilita la extensión del código más adelante, pero no se necesita.
Puede usar esta misma técnica en muchos escenarios diferentes basados en la cinta. En cualquier situación en que necesite modificar el diseño, el comportamiento o el contenido de cualquier control según el "evento" de un control diferente, use las variables de nivel de clase para mantener el estado e invalidar el control o la cinta completa.
Aunque pensé que no me iba a gustar la nueva interfaz de usuario, descubrí que estaba equivocado. La cinta ofrece una excelente manera de presentar opciones a los usuarios y el modelo declarativo es mucho más fácil de programar que el antiguo modelo CommandBar de Office.

Envíe sus preguntas y comentarios para Ken a basics@microsoft.com.


Ken Getz es consultor senior de MCW Technologies y autor de software con fines pedagógicos para AppDev. Es coautor de ASP .NET Developers Jumpstart (Addison-Wesley, 2002), Access Developer’s Handbook (Sybex, 2002) y VBA Developer’s Handbook, 2nd Edition (Sybex, 2001). Se puede poner en contacto con él a través de keng@mcwtech.com.

Page view tracker