自定义 Office 2010 Backstage 视图中的控件格式

Office 可视操作方法

**摘要:**了解如何定义控件的水平布局或垂直布局,以及控件在 Microsoft Office 2010 Backstage 视图中的显示方式。(11 个打印页面)

上次修改时间: 2015年3月9日

适用范围: Excel 2010 | Office 2010 | Open XML | PowerPoint 2010 | VBA | Visual Studio | Word 2010

**发布时间:**2010 年 4 月

**供稿人:**Michael Case,iSoftStone

概述

Microsoft Office Backstage 视图是 Microsoft Office 2010 中的一项新功能,它将代替传统的"文件"菜单来为文件管理任务(例如,打开新文件或现有文件、定义文档属性和共享信息)提供一个集中空间。与 Microsoft Office Fluent 功能区类似,可使用 XML 扩展 Backstage 视图以定义结构、组件和回调过程,以便为组件提供功能。

此 Office 直观操作方法一文将说明如何使用自定义控件格式来创建特定于文档的自定义 Backstage 视图。该 Backstage 视图使用 layoutContainer 控件指定是垂直显示还是水平显示一组控件,它还使用回调过程来动态定义一组控件的显示方式。

此直观操作方法附带的示例使用 Trang Luu 的自定义 UI 编辑器工具(该链接可能指向英文页面)以简化向 Microsoft Excel 2010 工作簿添加自定义 UI XML 这一操作。您必须下载并安装自定义 UI 编辑器才能按照本文中提供的步骤进行操作。

编码

本文通过使用 XML 和 Microsoft Visual Basic for Applications (VBA) 代码的组合来自定义 Microsoft Excel 2010 工作簿的 Backstage 视图。XML 定义要在 Backstage 视图中显示的自定义选项卡和控件。VBA 代码提供了自定义 UI XML 中定义的回调过程所需的功能。本文还指导您完成下列步骤以说明如何在 Excel 2010 工作簿中创建自定义 Backstage 视图:

  • 使用 Backstage 视图创建示例 Excel 工作簿。

  • 添加自定义 UI XML。

  • 添加 VBA 回调代码。

  • 查看自定义 Backstage 视图页。

创建示例 Excel 工作簿

在此直观操作方法中,你将向 Excel 工作簿添加自定义 UI XML 和 VBA 代码。

> [!NOTE] >

您必须将 Excel 工作簿创建为启用宏的工作簿 (.xlsm) 才能支持 VBA 代码。

  1. 启动 Microsoft Excel 2010。

  2. 在"文件"菜单上,单击"另存为"。

  3. 在"另存为"对话框的"保存类型"下拉列表中,选择"Excel 启用宏的工作簿(*.xlsm)"。

  4. 将文档另存为 C:\Temp\BackstageViewFormatControls.xlsm。单击"保存"以完成操作。

添加自定义 UI XML

自定义 UI 编辑器简化了将自定义 UI XML 添加到您在上一步骤中创建的工作簿的过程。

  1. 启动自定义 UI 编辑器。

  2. 在"文件"菜单上,单击"打开"。

  3. 选择在上一过程中创建的 C:\Temp\BackstageViewFormatControls.xlsm 文件,然后单击"打开"。

  4. 在"插入"菜单上,单击"Office 2010 自定义 UI 部件"。这将在文档中创建 CustomUI14.xml 文件。

  5. 选择 customUI14.xml 文件,并将以下 XML 复制到该文件中。

    <?xml version="1.0" encoding="utf-8"?>
    <!-- CustomUI is the root tag of all Office Fluent UI customizations. -->
    <customUI xmlns="https://schemas.microsoft.com/office/2009/07/customui"
          onLoad="onLoad">
      <!-- The Backstage view defines custom structure of the Backstage UI. -->
      <backstage>
        <tab id="customFormatTab" label="Customized Control Format"
             insertAfterMso="TabInfo">
          <firstColumn>
            <group id="specDetailsGroup" label="Specification Details"
                   getHelperText="GetSpecDetailsHelperText">
              <topItems>
                <!-- The layoutChildren attribute places 
                      this set of controls vertically. -->
                <!-- The GetSpecDetailText callback returns 
                      a value to display for each editBox. -->
                <layoutContainer id="specDetails" layoutChildren="vertical">
                  <editBox id="specTitle" label="Title:        "
                           getText="GetSpecDetailText" />
                  <editBox id="specDesigner" label="Designer: "
                           getText="GetSpecDetailText" />
                  <editBox id="specEngineer" label="Engineer: "
                           getText="GetSpecDetailText" />
                  <editBox id="specTeam" label="Team:      "
                           getText="GetSpecDetailText"/>
                  <editBox id="specCost" label="Cost:        "
                           getText="GetSpecDetailText"/>
                </layoutContainer>
                <!-- The layoutChildren attribute places 
                      the buttons horizontally. -->
                <layoutContainer id="specButtons" layoutChildren="horizontal">
                  <button id="getCostBasis" 
                          label="Get Cost Basis Info"/>
                  <button id="getCostCodes" 
                          label="Get Cost Codes"/>
                  <button id="getTeamCodes" 
                          label="Get Team Codes"/>
                </layoutContainer>
              </topItems>
            </group>
          </firstColumn>
          <secondColumn>
            <!-- The getStyle and getHelperText callbacks dynamically 
                  set the Open Design Issues Group style 
                  and text based on whether there are any open issues. -->
            <group id="openDesignIssuesGroup" label="Open Design Issues"
                   getStyle="GetIssuesStyle" 
                   getHelperText="GetIssuesHelperText">
              <topItems>
                <!-- The layoutChildren attribute places 
                      each set of issues controls horizontally. -->
                <!-- The onAction callback marks issues as resolved 
                      when the user clicks the Click to resolve button. -->
                <!-- The getVisible callback hides the 
                      issues after they are marked as resolved. -->
                <layoutContainer id="delayIssueContainer"
                                 layoutChildren="horizontal">
                  <button id="resolveDelayIssue" label="Click to resolve"
                          imageMso="AcceptInvitation" onAction="ResolveIssue"
                          getVisible="getIssueVisibility" />
                  <labelControl id="delayIssue"
                                label="Issue: Delay in Material Delivery"
                                getVisible="getIssueVisibility" />
                </layoutContainer>
                <layoutContainer id="equipmentIssueContainer"
                                 layoutChildren="horizontal">
                  <button id="resolveEquipmentIssue" label="Click to resolve"
                          imageMso="AcceptInvitation" onAction="ResolveIssue"
                          getVisible="getIssueVisibility" />
                  <labelControl id="equipmentIssue"
                                label="Issue: Equipment Down Time"
                                getVisible="getIssueVisibility" />
                </layoutContainer>
                <layoutContainer id="laborIssueContainer"
                                 layoutChildren="horizontal">
                  <button id="resolveLaborIssue" label="Click to resolve"
                          imageMso="AcceptInvitation" onAction="ResolveIssue"
                          getVisible="getIssueVisibility" />
                  <labelControl id="laborIssue"
                                label="Issue: Labor Dispute"
                                getVisible="getIssueVisibility" />
                </layoutContainer>
              </topItems>
            </group>
          </secondColumn>
        </tab>
      </backstage>
    </customUI>
  6. 在"文件"菜单上,单击"保存"。

  7. 关闭自定义 UI 编辑器。

添加 VBA 回调代码

VBA 回调过程将向您在前一过程中使用自定义 UI XML 添加的自定义 Backstage 视图组件添加功能。

  1. 启动 Microsoft Excel 2010。

  2. 在"文件"选项卡上,单击"打开"。

  3. 打开 BackstageViewFormatControls.xlsm 工作簿。

  4. 选择"开发工具"选项卡。

  5. 单击"Visual Basic"。

  6. 在"插入"菜单上,单击"模块"。

  7. 选择"Module1",然后将下面的 VBA 代码复制到文件中。

    ' Reference to the ribbon for refreshing the UI.
    Public processRibbon As IRibbonUI
    
    ' Variables that track the open design issues.
    Public delayIssueResolved As Boolean
    Public equipmentIssueResolved As Boolean
    Public laborIssueResolved As Boolean
    
    ' Store a reference to the ribbon for refreshing the UI.
    Sub OnLoad(ribbon As IRibbonUI)
      Set processRibbon = ribbon
    End Sub
    
    ' Helper text for the specification details group.
    Sub GetSpecDetailsHelperText(control As IRibbonControl, _
                                 ByRef returnedVal)
      returnedVal = "Please be sure that the following information " & _
                    "is kept up to date. Many processes rely on " & _
                    "this information."
    End Sub
    
    ' Returns the text to display for each specification detail editBox object.
    Sub GetSpecDetailText(control As IRibbonControl, _
                          ByRef returnedVal)
      Select Case control.ID
        Case "specTitle"
          returnedVal = "Flexible Bracket"
        Case "specDesigner"
          returnedVal = "Andrew Fuller"
        Case "specEngineer"
          returnedVal = "Nancy Davolio"
        Case "specTeam"
          returnedVal = "Design"
        Case "specCost"
          returnedVal = "$896,210"
      End Select
    End Sub
    
    ' Group style for the open design issues group.
    ' If all issues are not resolved the error style
    ' emphasizes the group.
    Sub GetIssuesStyle(control As IRibbonControl, _
                       ByRef returnedVal)
      If (delayIssueResolved And equipmentIssueResolved _
          And laborIssueResolved) Then
        ' This enumeration was renamed after the Office 2010 beta release.
        ' For the beta, use the OutSpaceSlabStyle.OutSpaceSlabStyleNormal enumeration.
        returnedVal = BackstageGroupStyle.BackstageGroupStyleNormal
      Else
        ' This enumeration was renamed after the Office 2010 beta release.
        ' For the beta release, use the OutSpaceSlabStyle.OutSpaceSlabStyleError enumeration.
        returnedVal = BackstageGroupStyle.BackstageGroupStyleError
      End If
    End Sub
    
    ' Helper text for the open design issues group.
    ' Text returned is based on the status of all issues.
    Sub GetIssuesHelperText(control As IRibbonControl, _
                            ByRef returnedVal)
      If (delayIssueResolved And equipmentIssueResolved _
          And laborIssueResolved) Then
        returnedVal = "All issues are resolved."
      Else
        returnedVal = "Click Resolve as issues are resolved."
      End If
    End Sub
    
    ' Visibility for each open design issue.
    ' If an issue is not marked as resolved, the corresponding
    ' button and label display.
    Sub GetIssueVisibility(control As IRibbonControl, _
                           ByRef returnedVal)
      Select Case control.ID
        Case "resolveDelayIssue"
          returnedVal = Not delayIssueResolved
        Case "delayIssue"
          returnedVal = Not delayIssueResolved
        Case "resolveEquipmentIssue"
          returnedVal = Not equipmentIssueResolved
        Case "equipmentIssue"
          returnedVal = Not equipmentIssueResolved
        Case "resolveLaborIssue"
          returnedVal = Not laborIssueResolved
        Case "laborIssue"
          returnedVal = Not laborIssueResolved
      End Select
    End Sub
    
    ' Called when the user clicks a resolve issue button.
    ' Sets the button's corresponding issue as resolved.
    Sub ResolveIssue(control As IRibbonControl)
      Select Case control.ID
        Case "resolveDelayIssue"
          delayIssueResolved = True
        Case "resolveEquipmentIssue"
          equipmentIssueResolved = True
        Case "resolveLaborIssue"
          laborIssueResolved = True
      End Select
    
      ' Invalidate is called to reset the UI, causing all controls
      ' to redisplay and executing all relevant callbacks.
      processRibbon.Invalidate
    End Sub
  8. 在"文件"菜单上,单击"保存"。

  9. 关闭 Visual Basic for Applications 编辑器,并返回到工作簿。

查看自定义 Backstage 视图页

若要查看先前定义的自定义 Backstage 视图页,可选择"文件"选项卡来显示 Backstage 视图。此时将显示新建的 Backstage 视图。在显示 Backstage 视图后,请选择位于内置"信息"选项卡下方的"Customized Control Format"选项卡。选择"Customized Control Format"选项卡后,您可与自定义 Backstage 视图页进行交互。

图 1. 自定义 Backstage 视图页

自定义 Backstage 视图页

 

读取

若要扩展 Office 2010 Backstage 视图以包含自定义页和控件,则需要将自定义 UI XML 添加到 Office 文档,并添加 VBA 代码以提供自定义 UI XML 中指定的回调的功能。

该示例代码不仅演示了控制已添加到 Backstage 视图页的控件的水平布局和垂直布局的方式,还演示了通过设置组的显示样式来强调控件组的方式。

初始化自定义 UI

在某些情况下,回调过程会执行需要重新显示 Backstage 视图控件的更改操作。若要重新显示 Backstage 视图控件,请调用 RibbonUI 对象的 Invalidate 方法。

下面的代码段演示如何在加载自定义 UI 时存储对 RibbonUI 控件的引用。customUI 元素包含 onLoad 属性。在此实例中,该属性用于指定 OnLoad 回调。OnLoad 回调将存储对 RibbonUI 对象的引用。可在回调中使用 RibbonUI 对象来重新显示 Backstage 视图控件。

<!-- customUI is the root tag of all Fluent UI customizations. -->
<customUI xmlns="https://schemas.microsoft.com/office/2009/07/customui"
      onLoad="OnLoad">
'Reference to the ribbon for refreshing the UI.
Public processRibbon As IRibbonUI

'Store a reference to the ribbon for refreshing the UI.
Sub OnLoad(ribbon As IRibbonUI)
  Set processRibbon = ribbon
End Sub

指定控件布局

您可能希望将控件水平放置在页面中,而不是使用默认的垂直布局。下面的代码示例演示如何使用 layoutContainer 控件通过设置 layoutContainer 控件的 layoutChildren 属性来水平或垂直放置控件。第一个 layoutContainer 控件会将 layoutChildren 属性设置为默认值 vertical。这还将在一个垂直列中显示"Specification Detail"编辑框控件。第二个 layoutContainer 控件会将 layoutChildren 属性设置为 horizontal。这将在编辑框下方的一个水平行中显示"Specification Detail"按钮控件。

<!-- The layoutChildren attribute places
      this set of controls vertically. -->
<!-- The GetSpecDetailText callback returns 
      a value to display for each editBox. -->
<layoutContainer id="specDetails" layoutChildren="vertical">
  <editBox id="specTitle" label="Title:        "
           getText="GetSpecDetailText" />
  <editBox id="specDesigner" label="Designer: "
           getText="GetSpecDetailText" />
  <editBox id="specEngineer" label="Engineer: "
           getText="GetSpecDetailText" />
  <editBox id="specTeam" label="Team:      "
           getText="GetSpecDetailText"/>
  <editBox id="specCost" label="Cost:        "
           getText="GetSpecDetailText"/>
</layoutContainer>
<!-- The layoutChildren attribute places 
      the buttons horizontally. -->
<layoutContainer id="specButtons" layoutChildren="horizontal">
  <button id="getCostBasis" 
          label="Get Cost Basis Info"/>
  <button id="getCostCodes" 
          label="Get Cost Codes"/>
  <button id="getTeamCodes" 
          label="Get Team Codes"/>
</layoutContainer>

将组样式设置为强调状态

在某些情况下,您可能希望基于某个条件来展示一组特定控件。当存在未解决的问题时,"Open Design Issues"组将通过突出显示为红色来展示自己。Backstage 视图组通过使用 getStyle 属性的回调来设置其显示样式。此回调可返回下列 BackstageGroupStyle 枚举值之一:

  • BackstageGroupStyleNormal。该组未经任何特殊的可视化处理。

  • BackstageGroupStyleWarning。该组突出显示为黄色。

  • BackstageGroupStyleError。该组突出显示为红色。

下面的自定义 UI XML 示例演示如何动态指定回调以定义控件在页面上的显示方式。"Open Design Issues"组将设置 getStyle 属性的回调和 getHelperText 属性的回调。这些回调将估计是否存在未解决的问题,并返回适当的样式和文本。每个问题的"Click to Resolve"按钮和说明性标签将设置 getVisible 属性的回调,并在解决问题后隐藏控件。该解决按钮还会设置 onAction 属性的回调以将问题标记为已解决。

<!-- The getStyle and getHelperText callbacks 
      dynamically set the Open Design Issues Group style 
      and text based on whether there are any open issues. -->
<group id="openDesignIssuesGroup" label="Open Design Issues"
       getStyle="GetIssuesStyle" 
       getHelperText="GetIssuesHelperText">
  <topItems>
    <!-- The layoutChildren attribute places 
          each set of issue controls horizontally. -->
    <!-- The onAction callback marks issues as resolved 
          when the user clicks the resolve button. -->
    <!-- The getVisible callback hides 
          issues after they are marked as resolved. -->
    <layoutContainer id="delayIssueContainer" 
    layoutChildren="horizontal">
      <button id="resolveDelayIssue" label="Click to resolve"
              imageMso="AcceptInvitation" onAction="ResolveIssue"
              getVisible="getIssueVisibility" />
      <labelControl id="delayIssue"
                    label="Issue: Delay in Material Delivery"
                    getVisible="getIssueVisibility" />
    </layoutContainer>
    <layoutContainer id="equipmentIssueContainer"
                     layoutChildren="horizontal">
      <button id="resolveEquipmentIssue" label="Click to Resolve"
              imageMso="AcceptInvitation" onAction="ResolveIssue"
              getVisible="getIssueVisibility" />
      <labelControl id="equipmentIssue"
                    label="Issue: Equipment Down Time"
                    getVisible="getIssueVisibility" />
    </layoutContainer>
    <layoutContainer id="laborIssueContainer"
                     layoutChildren="horizontal">
      <button id="resolveLaborIssue" label="Click to resolve"
              imageMso="AcceptInvitation" onAction="ResolveIssue"
              getVisible="getIssueVisibility" />
      <labelControl id="laborIssue"
                    label="Issue: Labor Dispute"
                    getVisible="getIssueVisibility" />
    </layoutContainer>
  </topItems>
</group>

下面的代码示例演示"Open Design Issues"组的 getStyle 属性(及其对应的 GetIssuesStyle 回调)和 getHelperText 属性(及其对应的 GetIssuesHelperText 回调)如何在存在未解决的问题时强调该组。最初,所有问题都处于未解决状态,且 GetIssuesStyle 回调将返回 BackstageGroupStyleError 枚举值以强调"Open Design Issues"组。在解决所有问题后,GetIssuesStyle 回调将返回 BackstageGroupStyleNormal 枚举值来移除该强调。getHelperText 属性的回调 GetIssuesHelperText 将与 GetIssuesStyle 回调并行工作,采用的方式是返回有关如何在解决所有问题后将这些问题标记为已解决的说明。

' Group style for the Open Design Issues Group.
' If all issues are not resolved the error style 
' emphasizes the group.
Sub GetIssuesStyle(control As IRibbonControl, _
                   ByRef returnedVal)
  If (delayIssueResolved And equipmentIssueResolved _
      And laborIssueResolved) Then
    ' This enumeration was renamed after the Office 2010 beta release.
    ' For the beta release, use the OutSpaceSlabStyle.OutSpaceSlabStyleNormal
    ' enumeration.
    returnedVal = BackstageGroupStyle.BackstageGroupStyleNormal
  Else
    ' This enumeration was renamed after the Office 2010 beta release.
    ' For the beta release, use the OutSpaceSlabStyle.OutSpaceSlabStyleError
    ' enumeration.
    returnedVal = BackstageGroupStyle.BackstageGroupStyleError
  End If
End Sub

'Helper Text for the Open Design Issues group.
' Text returned is based on the status of all issues.
Sub GetIssuesHelperText(control As IRibbonControl, _
                        ByRef returnedVal)
  If (delayIssueResolved And equipmentIssueResolved _
      And laborIssueResolved) Then
    returnedVal = "All issues are resolved."
  Else
    returnedVal = "Click resolve as issues are resolved."
  End If
End Sub

下面的代码示例演示"Click to resolve"按钮和"issue"标签的 getVisible 属性(及其 GetIssueVisibility 回调)如何在问题被标记为已解决后将其隐藏。GetIssueVisibility 值标识要显示的控件,并根据相关问题的解决状态返回 True 或 False 值。

' Visibility for each Open Design Issue.
'If an issue is not marked as resolved, the corresponding
' button and label display.
Sub GetIssueVisibility(control As IRibbonControl, 
                       ByRef returnedVal)
  Select Case control.ID
    Case "resolveDelayIssue"
      returnedVal = Not delayIssueResolved
    Case "delayIssue"
      returnedVal = Not delayIssueResolved
    Case "resolveEquipmentIssue"
      returnedVal = Not equipmentIssueResolved
    Case "equipmentIssue"
      returnedVal = Not equipmentIssueResolved
    Case "resolveLaborIssue"
      returnedVal = Not laborIssueResolved
    Case "laborIssue"
      returnedVal = Not laborIssueResolved
  End Select
End Sub

下面的代码示例演示"Click to Resolve"按钮的 onAction 属性的回调 ResolveIssue 如何将问题标记为已解决。ResolveIssue 回调标识已单击的按钮,并将相应的问题标记为已解决。解决问题后,RibbonUI 对象的 Invalidate 方法将重新显示 Backstage 视图控件,并显示当前解决的问题的状态。在调用 Invalidate 方法时,将再次执行"Open Design Issues"组的 getStyle 属性的回调和 getHelperText 属性的回调。此外,还会再次执行每个"Click to Resolve"按钮和"issue"标签的 getVisible 属性的回调。

' Called when a  user clicks the Resolve issue button.
' Sets the button's corresponding issue as resolved.
Sub ResolveIssue(control As IRibbonControl)
  Select Case control.ID
    Case "resolveDelayIssue"
      delayIssueResolved = True
    Case "resolveEquipmentIssue"
      equipmentIssueResolved = True
    Case "resolveLaborIssue"
      laborIssueResolved = True
  End Select

  ' Invalidate is called to reset the UI, causing all controls
  ' to redisplay and executing all relevant callbacks.
  processRibbon.Invalidate
End Sub
观看

观看视频

观看视频(该链接可能指向英文页面)

视频时长:00:09:14 | 文件大小:19.2 MB | 文件类型:WMV

单击以获取代码

获取代码(该链接可能指向英文页面)

浏览