Office 2007 Ribbon Galleries mit dynamischen Inhalten

Office 2007 bietet viele Ansatzmöglichkeiten für Entwickler. Und seit auf der Office System Developer Conference die erste Version von Visual Studio Tools für Office (Version 3) ausgegeben wurde, macht die Programmierung mit .NET für Office 2007 noch mehr Spaß. Zugegeben, man muß noch einiges von Hand erledigen, aber was das Entwicklungsteam von Mike Hernandez da geschafft hat, nötigt Respekt ab.

Ribbons, die neue Oberfläche für Office 2007, bieten u.a. auch sog. Galleries. Das sind Controls, die eine visuelle Repräsentation des zu erwartenden Ergebnisses bieten. Sie werden mittels XML deklarativ erstellt und über Callback Handler mit "Leben" gefüllt. Im Ribbon XML werden die Callback Handler deklariert und im dahinterliegenden Ribbon.vb oder Ribbon.cs ausprogrammiert.

Es gibt eine ganze Reihe von verfügbaren Callback Handlern, z.B. getImage zum Festlegen des Standard-Bildes des Gallery Controls oder getItemImage zum Zuordnen eines Bildes zum jeweiligen Gallery-Eintrag. Um eine Gallery dynamisch aufzufüllen, benötigt man dann noch getItemCount, um Office mitzuteilen, wieviele Einträge denn zu erwarten sind und getItemLabel, um den Namen des einzelnen Eintrags festzulegen. Desweiteren könnten wir noch getItemSupertip verwenden, um den Text für den neuen SuperToolTip zu definieren.

Das Ribbon XML (für Office 2007 Beta 1Technical Refresh) sieht dann folgendermaßen aus:

<customUI xmlns="https://schemas.microsoft.com/office/2006/01/customui" onLoad="OnLoad">

  <ribbon startFromScratch="false">

    <tabs>

      <tab id="TabMyTab" label="My Tab">

        <group id="myGroup1" label="My Group 1">

          <gallery id="FotoGallery" label="FotoGallery" columns="3" rows="3" size="large"

                  getImage="getImage" getItemImage="getItemImage"

                   getItemCount="getItemCount" getItemLabel="getItemLabel"

                   getItemSupertip="getItemSuperTooltip">

          </gallery>

   </group>

      </tab>

    </tabs>

  </ribbon>

</customUI>

Nun definieren wir die Callback Handler. Zuerst das allgemeine getImage. Da wir mit Office, also einer COM-Anwendung kommunizieren, müssen wir (zumindest in diesem CTP) ein .NET Image in ein IpictureDisp konvertieren. Dazu gibt es unter System.Windows.Forms.AxHost eine Funktion GetIPictureDispFromPicture. Die allerdings wurde mit dem Attribut MustInherit versehen, so daß wir ein wenig Aufwand treiben müssen:

Public Class ImageConverter

  Inherits System.Windows.Forms.AxHost

  Public Sub New()

    MyBase.new(Nothing)

  End Sub

  Public Overloads Shared Function GetIPictureDispFromPicture(ByVal img As Image) As stdole.IPictureDisp

    Return AxHost.GetIPictureDispFromPicture(img)

  End Function

End Class

Diese Funktion können wir jetzt im Callback Handler verwenden:

Public Function getImage(ByVal control As Office.IRibbonControl) As stdole.IPictureDisp

  Select Case control.Id

    Case "FotoGallery"

      Return ImageConverter.GetIPictureDispFromPicture(My.Resources.Bild01)

    Case "btnSonstWas"

      Return ImageConverter.GetIPictureDispFromPicture(My.Resources.Bild02)

    Case Else

      Return ImageConverter.GetIPictureDispFromPicture(My.Resources.NoPhoto)

  End Select

End Function

Angenommen, wir haben die Gallery-Einträge in einer XML-Datei (hier schon in das XmlDataDocument xPeople eingelesen), dann lesen wir jetzt von dort die Anzahl der Einträge aus:

Public Function getItemCount(ByVal control As Office.IRibbonControl) As Integer

  Return xPeople.DocumentElement.ChildNodes.Count

End Function

Die Bezeichnungen für die einzelnen Einträge holen wir uns auch von da:

Public Function getItemLabel(ByVal control As Office.IRibbonControl, ByVal index As Integer) As String

  Return xPeople.DocumentElement.ChildNodes(index).ChildNodes(1).InnerText()

End Function

Ebenso wie den Text für den SuperToolTip:

Public Function getItemSuperTooltip(ByVal control As Office.IRibbonControl, ByVal index As Integer) As String

  Return xPeople.DocumentElement.ChildNodes(index).ChildNodes(2).InnerText()

End Function

Wo Sie die Bilder für die Gallery herholen, bleibt Ihnen überlassen. Wichtig ist nur die Signatur des Callback Handlers mit der Control-Instanz und dem Index des entsprechenden Gallery-Eintrags sowie dem Rückgabewert IPictureDisp

Public Function getItemImage(ByVal control As Office.IRibbonControl, ByVal index As Integer) As stdole.IPictureDisp

  Dim img As Image My.Resources.NoPhoto

  Select Case index

    Case 0

      Img = …

    Case 1

      Img = ..

  End Select

  Return ImageConverter.GetIPictureDispFromPicture(img)

End Function

Damit sieht unsere dynamisch befüllte Gallery jetzt folgendermaßen aus: