为开发人员自定义 Office 2010 Backstage 视图

**摘要:**Microsoft Office 2010 引入了一个名为 Backstage 视图的新界面。查看说明如何为您自己的应用程序扩展用户界面的示例。(17 张打印页)

上次修改时间: 2015年4月24日

适用范围: Excel 2010 | Office 2007 | Office 2010 | Open XML | PowerPoint 2010 | SharePoint Server 2010 | VBA | Word 2010

本文内容
Microsoft Office Backstage 视图介绍
初始化自定义 UI
在首次显示或隐藏 Backstage 视图时执行操作
创建快速命令按钮
在 Backstage 视图中创建三类列布局
在内置选项卡中插入自定义组
在内置选项卡中插入自定义任务
动态更改组的可视性
指定控件的布局
动态设置控件的样式以强调其状态
从一组控件同步另一组控件的可视性
结论
其他资源

**发布时间:**2009 年 11 月

**供稿人:**Mirko Mandic,Microsoft Corporation | Frank Rice,Microsoft Corporation

内容

  • Microsoft Office Backstage 视图介绍

  • 初始化自定义 UI

  • 在首次显示或隐藏 Backstage 视图时执行操作

  • 创建快速命令按钮

  • 在 Backstage 视图中创建三类列布局

  • 在内置选项卡中插入自定义组

  • 在内置选项卡中插入自定义任务

  • 动态更改组的可视性

  • 指定控件的布局

  • 动态设置控件的样式以强调其状态

  • 从一组控件同步另一组控件的可视性

  • 结论

  • 其他资源

Microsoft Office Backstage 视图介绍

Microsoft Office Backstage 视图是 Microsoft Office 2010 系统的最新功能之一。此用户界面组合了文件级别的任务和操作,并取代了早期版本的 Microsoft Office system 中的 Microsoft Office 按钮所提供的类似功能,可以从"文件"选项卡访问此用户界面。

备注

有关包含元素和属性说明以及回调签名的详细的介绍性信息,请参阅标题为针对开发人员的 Office 2010 Backstage 视图介绍的文章。

与 Microsoft Office Fluent 功能区 UI 一样,通过使用 XML 定义结构、组件和编程代码(这称作"回调"过程)来实现这些组件的功能性,可对 Backstage 视图进行完全扩展。如果您能熟练地扩展功能区 UI,则您基本上能够更新现有选项卡和创建自定义 Backstage 视图 UI。

可以使用 Office Open XML 格式的文件为文档特定的自定义项创建自定义 Backstage 视图,也可以使用 COM 加载项为应用程序级的自定义项创建自定义 Backstage 视图。有关这两个 UI 扩展性方法的详细信息,请参阅标题为为开发人员自定义 2007 Office Fluent 功能区的一系列文章。

备注

有关本文中所述的代码示例,请参阅 https://code.msdn.microsoft.com 上相应的可下载文件。

以下方案描述了用于自定义 Microsoft Excel 2010 中的 Backstage 视图的 XML 和 Microsoft Visual Basic for Applications (VBA) 代码。

备注

为了帮助您将 XML 和图像添加到 Microsoft Office 2010 程序中,您应考虑使用自定义 UI 编辑器。本文的结尾处提供了此编辑器的下载链接。

初始化自定义 UI

可以从 <customUI> 元素的 onLoad 属性指向代码以引用 UI 并初始化代码中使用的任何变量。通过设置 <customUI> 元素的 onLoad 属性为此事件指定回调。

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

下面的回调过程首先通过 RibbonUI 对象引用 UI。之后,将初始化本文中所述的代码示例中使用的多个变量。

Private processRibbon As IRibbonUI

Sub OnLoad(ribbon As IRibbonUI)
    Set processRibbon = ribbon
    engGrpVisible = True
    taskOneComplete = False
    taskTwoComplete = False
    taskThreeComplete = False
    taskFourComplete = False
    issueResolved = False
    issueVisibility = True
End Sub

在首次显示或隐藏 Backstage 视图时执行操作

可能存在这样的实例,即在显示 Backstage 视图或不再显示 Backstage 视图时,您需要执行相应操作。例如,您可能需要基于某个事件(如超出特定日期)显示或隐藏选项卡。<backstage> 元素的 onShow 属性和 onHide 属性可指向执行此类操作的代码。下面的示例说明如何使用 onShow 属性指定组中某个按钮的样式。

<backstage onShow="OnShow">

<group id="workStatusGroup" label="Work Status" getHelperText="GetStatusHelperText" getStyle="GetWorkStatusStyle" >
   <primaryItem>
      <button id="sendStatusMailButton" label="Send Status E-Mail" imageMso="ReplyAll" />
   </primaryItem>
</group>

查看下面的 VBA 代码,根据日期值的不同, showGrpStyle 变量设置为以下三个值之一:

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

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

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

Sub OnShow(ByVal contextObject As Object)
    If (Date < #9/29/2009#) Then
        showGrpStyle = BackstageGroupStyle.BackstageGroupStyleWarning
    ElseIf ((Date >= #9/29/2009#) And (Date < #10/1/2009#)) Then
        showGrpStyle = BackstageGroupStyle.BackstageGroupStyleError
    Else
        showGrpStyle = BackstageGroupStyle.BackstageGroupStyleNormal
    End If
    processRibbon.Invalidate
End Sub

Sub GetWorkStatusStyle(control As IRibbonControl, ByRef returnedVal)
        returnedVal = showGrpStyle
End Sub

XML 和代码按如下方式协作:

  1. 显示 Backstage 视图,这将触发 OnShow 回调过程。

  2. OnShow 过程中的代码测试日期并将 showGrpStyle 字符串变量设置为 BackstageGroupStyle 对象的三个枚举之一,具体取决于日期值。

  3. 然后,该代码将执行 processRibbon.Invalidate 方法,这会导致 UI 重置,从而对 Backstage 视图上的每个控件执行回调。

  4. workStatusGroup 组的 getStyle 属性指向回调 GetWorkStatusStyle,这将返回变量 showGrpStyle的值,在此示例中,该值为枚举值之一。此操作设置了组的样式。

创建快速命令按钮

快速命令对于必须经常使用的选项很有用。使用以下 XML 可创建用于保存当前工作簿的快速命令按钮。它还使用 isDefinitive 属性关闭 Backstage 视图并返回工作表。图 1 显示了 XML 标记所创建的快速命令。

图 1. 保存并关闭快速命令

保存并关闭

看一下此 XML,insertAfterMso="FileSaveAs" 属性分配紧挨"另存为"命令后插入自定义按钮。注意是如何使用两个 &amp;&amp; 串联标记将 & 符号插入标签中的。

<button id="saveBtn" label="Save &amp;&amp; Close" imageMso="SourceControlCheckIn" keytip="Z" onAction="SaveAction" insertAfterMso="FileSaveAs" isDefinitive="true" />

onAction 属性指向一个回调,此回调使用活动工作簿的 Save 方法来保存该工作簿。

Sub SaveAction(control As IRibbonControl)
    'Saves any changes to the workbook.
    ActiveWorkbook.Save
End Sub

在 Backstage 视图中创建三类列布局

在 Backstage 视图中,当您添加自定义内容时,可以使用三个选项。您可以使用 <firstColumn> 元素指定一个列。在您需要以水平方式呈现信息时,此选项很有用。您也可以使用 <firstColumn> 和 <secondColumn> 元素指定两个信息列。这是最典型的选项。最后,您可以选择使用 taskFormGroup 控件创建其他子导航。例如,在您单击第一个列中的不同控件时,该列旁边的窗口中会显示不同的组。

只需使用 <firstColumn> 元素即可创建单个列布局,如图 2 所示。

图 2. 单个列布局的示例

单个列布局

<firstColumn>
   <group id="reviewersGroup" label="Document Reviewers">
      <topItems>
         <layoutContainer id="headerLayout" layoutChildren="horizontal">
            <labelControl id="spacerLabel" label="               " />
            <labelControl id="nameHeaderLabel" label="       NAME" />
            <labelControl id="titleHeaderLabel" label="      TITLE " />
            <labelControl id="roleHeaderLabel" label="       ROLE" />
            <labelControl id="approvalDueDateLabel" label="    APPROVAL DUE DATE" />
         </layoutContainer>
         <layoutContainer id="arthurLayout" layoutChildren="horizontal">
            <imageControl id="arthurImage" image="Arthur" />
            <labelControl id="arthurNameLabel" label="          Arthur Davis" />
            <labelControl id="arthurTitleLabel" label="    Corporate VP" />
            <labelControl id="arthurRoleLabel" label="    Final Approver" />
            <labelControl id="arthurDueDateLabel" label="    10/20/2009" />
         </layoutContainer>
      </topItems>
</firstColumn>

此 XML 的下一个部分使用 <firstColumn> 和 <secondColumn> 元素定义两个信息列,如图 3 所示。

图 3. 两列布局的示例

两列布局

<firstColumn>
…<group id="customPrinter" label="PR-XYZ Printer" insertAfterMso="GroupPrintSettings" >
      <primaryItem>
         <button id="setPaperType" label="Set Paper Type" imageMso="PrintAreaMenu" />
      </primaryItem>
      <topItems>
         <button id="setPlotStart" label="Set Plot Start      " imageMso="ChartDepthAxis" />
         <button id="setPlotXAxis" label="Set X-Axis Limits" imageMso="ChartSecondaryHorizontalAxis" />
         <button id="setPlotYAxis" label="Set Y-Axis Limits" imageMso="ChartSecondaryVerticalAxis" />
      </topItems>
…</group>
</firstColumn>
<secondColumn>
   <taskGroup id="bidProcessTaskGroup" label="Contract Bid Process Checklist" >
      <category id="defineWorkScopeCategory" getLabel="GetCatHelperText"  >
         <task id="defineScope" label="Define the Scope of Work." tag="Work scope" imageMso="_1" onAction="GetCalcCostCatVisibility"/>
         <task id="assignTasks" label="Assign the Tasks" tag="Task assignments" imageMso="_2" onAction="GetCalcCostCatVisibility"/>
      </category>
             
</secondColumn>

利用 taskFormGroup 控件,您可以基于该控件中的选择来显示组。该控件使用类别中的任务来包含组定义。当您单击 taskFormGroup 控件中的某个任务时,此任务控件旁边的窗格中将显示 <task> 元素内定义的组。图 4 和 5 显示的示例将使用下面的 XML 标记中描述的 taskFormGroup 控件。

图 4. 选择第一个组将在其右侧显示一个组

第一个组显示

图 5. 选择下一个组将在其右侧显示另一个组

下一个组显示

下面的 XML 演示如何使用 taskFormGroup 控件。

<tab id="teamTasksTab" label="Team Tasks" >
   <firstColumn>
      <taskFormGroup id="teamTaskFormGroup">
            <category id="engineeringTeamCategory" label="Engineering Tasks">
              <task id="engineeringTeamTasks" label="Manager: William Rodgers" description="Engineering Excellance" imageMso="TableDesign">
                <group id="engineeringTeamTasksGroup" label="Engineering Group">
                     <topItems>
                        <button id="concept" label="Concept     " tag="Task One" imageMso="_1" />
                        <button id="design" label="Design       " tag="Task Two" imageMso="_2" />
                        <button id="prototype" label="Prototype  " tag="Task Three" imageMso="_3" />
                        <button id="production" label="Production" tag="Task Four" imageMso="_4" />
                     </topItems>
                </group >
              </task>
            </category>
            <category id="manufacturingTeamCategory" label="Manufacturing Tasks">
              <task id="manufacturingTeamTasks" label="Manager: Alice Morton" description="Right the First Time" imageMso="ControlsGallery">
                <group id="manufacturingTeamTasksGroup" label="Manufacturing Group">
                   <topItems>
                        <button id="flowDesign" label="Flow Design    " tag="Task One" imageMso="_1" />
                        <button id="tooling" label="Tooling            " tag="Task Two" imageMso="_2" />
                        <button id="staffing" label="Staffing           " tag="Task Three" imageMso="_3" />
                        <button id="manufacturing" label="Manufacturing" tag="Task Four" imageMso="_4" />
                   </topItems>
                </group >
              </task>
            </category>
         <category id="marketingTeamCategory" label="Marketing Tasks">
            <task id="marketingTeamTasks" label="Manager: Jane Burns" description="Bringing Quality to the Customer" imageMso="SignatureShow">
               <group id="marketingTeamTasksGroup" label="Marketing Group">
                  <topItems>
                     <button id="concepts" label="Concepts              " tag="Task One" imageMso="_1" />
                     <button id="storyBoarding" label="Story Boarding     " tag="Task Two" imageMso="_2" />
                     <button id="finalization" label="Finalization           " tag="Task Three" imageMso="_3" />
                     <button id="channelSelection" label="Channel Selection " tag="Task Four" imageMso="_4" />
                     <button id="execution" label="Execution              " tag="Task Five" imageMso="_5" />
                  </topItems>
               </group >
            </task>
          </category>
      </taskFormGroup >
   </firstColumn>
</tab>

当您单击第一个列中的 engineeringTeamTasks 任务时,第一个列旁边的窗格中将显示 engineeringTeamTasksGroup 组。当您单击列一中的 manufacturingTeamTasks 任务时,manufacturingTeamTasksGroup 组将替换该列右侧的 engineeringTeamTasksGroup 组。因此,选择不同的任务控件可切换该列旁边的一个或多个组的显示。这样,您可以在更小的空间内显示更多的信息。

在内置选项卡中插入自定义组

在内置选项卡中插入组与在功能区选项卡中插入组类似。通过使用 idMso 属性(任何使用 Mso 后缀的属性都引用内置控件或图像)引用内置选项卡。若要在内置控件后插入自定义组,可以使用 insertAfterMso 属性。在下面的示例中,您在内置"打印"选项卡上的内置组 GroupPrintSettings 后插入自定义组 customPrinter。

<tab idMso="TabPrint">
    <firstColumn>
      <group id="customPrinter" label="PR-XYZ Printer" insertAfterMso="GroupPrintSettings" >
         <primaryItem>
             <button id="setPaperType" label="Set Paper Type" imageMso="PrintAreaMenu" />
         </primaryItem>
         <topItems>
            <button id="setPlotStart" label="Set Plot Start      " imageMso="ChartDepthAxis" />
            <button id="setPlotXAxis" label="Set X-Axis Limits" imageMso="ChartSecondaryHorizontalAxis" />
            <button id="setPlotYAxis" label="Set Y-Axis Limits" imageMso="ChartSecondaryVerticalAxis" />
         </topItems>
       </group>
   </firstColumn>
</tab>

使用此 XML 会生成图 6 中所示的结果。

图 6. 向"打印"选项卡添加自定义打印机

自定义打印机组

也可以向内置选项卡中的任务添加自定义组。图 7 显示向内置任务添加自定义组的情况,而此图后面的 XML 说明如何做到这一点。

图 7. 向内置任务添加自定义组所产生的结果

添加自定义组的结果

<taskFormGroup idMso="GroupShare">
    <category idMso="Share">
      <task idMso="SendUsingEmail">
         <group id="sendViaHotmailGroup" insertAfterMso="GroupSendAsLink" label=" ">
            <bottomItems>
               <layoutContainer id="hotmailItemsLayout" layoutChildren="horizontal">
                  <button id="sendViaHotmail" style="large" label="Send via Hotmail" image="WindowsLive32"/>
                     <layoutContainer id="hotmailLabelAndBulletsLayout" layoutChildren="vertical">
                        <labelControl id="hotmailLabel" label="Use your Hotmail account to send this document."/>
                           <layoutContainer id="BillboardHotmailRowOne" layoutChildren="horizontal">
                               <imageControl id="BillboardHotmailRowOneBullet" image="BillboardBullet"/>
                              <labelControl id="BillboardHotmailRowOneLabel" label="Choose from your list of Hotmail contacts."/>
                           </layoutContainer>
                           <layoutContainer id="BillboardHotmailRowTwo" layoutChildren="horizontal">
                               <imageControl id="BillboardHotmailRowTwpBullet" image="BillboardBullet"/>
                               <labelControl id="BillboardHotmailRowTwpLabel" label="Recipients get the document from your Windows Live Hotmail address."/>
                           </layoutContainer>
                        </layoutContainer>
                     </layoutContainer>
                  </bottomItems>
               </group>
      </task> 
    </category>
</taskFormGroup>

在内置选项卡中插入自定义任务

在下一个示例中,将 taskFormGroup 控件插入内置"共享"选项卡。向内置 SendUsingEmail 任务添加组。通过使用嵌套的 layoutContainer 控件在该选项卡上排列各个控件。

备注

此示例还说明用于获取多个内置组中使用的带项目符号的文本的方法。通过将表示该带项目符号的文本的自定义图像置于标签旁边来执行此操作。

下面的图示和示例与上一个示例类似,它说明用于设置从 taskFormGroup 控件显示的控件的布局的另一种方式。此处定义了项目符号列表,并使用了一个按钮。

图 8. 另一个控件布局示例

布局示例

<task id="ButtonTaskSaveToFacebook" insertAfterMso="SendUsingEmail" label="Post to Facebook" imageMso="HelpContactMicrosoft">
   <group id="GroupSaveToFacebook" label="Post to Facebook">
      <topItems>
         <labelControl id="BillboardFacebookRowOne" label="Post to Facebook to make this document available to all of your friends."/>
         <layoutContainer id="BillboardFacebookRowTwo" layoutChildren="horizontal">
            <imageControl id="BillboardFacebookRowTwoBullet" getImage="GetBillboardBullet"/>
            <labelControl id="BillboardFacebookRowTwoLabel" label="Use a Web browser to view and edit documents from anywhere."/>
         </layoutContainer>
         <layoutContainer id="BillboardFacebookRowThree" layoutChildren="horizontal">
            <imageControl id="BillboardFacebookRowThreeBullet" getImage="GetBillboardBullet"/>
            <labelControl id="BillboardFacebookRowThreeLabel" label="Receive notifications when documents change."/>
         </layoutContainer>
         <button id="ButtonSignIn" style="large" label="Sign in" imageMso="HelpContactMicrosoft"/>
      </topItems>
   </group>
</task>

动态更改组的可视性

下面的示例说明如何动态更改两个组的可视性,使其看上去就像您从一个组的显示切换到另一个组的显示一样。如果两个组是互相排斥的,这样做会很有用。图 9 和图 10 中显示了切换的结果。

图 9. 最初显示"Marketing"(市场营销)组

市场营销组显示

图 10. 组的可视性更改为显示"Engineering"(工程)组

工程组显示

XML 包含一个 primaryItem 控件,此控件包含一个由两个按钮组成的菜单组。单击第一个按钮可开始切换。切换操作将影响 marketingGroupDetails 组和 engineeringGroupDetails 组。

<primaryItem>
   <menu id="switchMenu" label="Groups" imageMso="ControlLayoutStacked" >
      <menuGroup id="switchMenuGroup">
         <button id="switchGroups" label="Switch for Group Status" onAction="SwitchGroupsBtn"/>
      </menuGroup>
   </menu>
</primaryItem>

<group id="marketingGroupDetails" label="Marketing Group" getVisible="GetMarketingGroupVisibility">
   <primaryItem>
      <button id="marketingButton" label="Marketing" imageMso="OutlookGlobe" />
   </primaryItem> 
   <topItems>
      <editBox id="marketingManager" label=" Manager:              " getText="GetMarketingDetail"/>
      <editBox id="marketingBudget" label=" Budget:                 " getText="GetMarketingDetail"/>
      <editBox id="marketingEndDate" getText="GetMarketingDetail" label="Completion Date: "/>
   </topItems>
</group>
<group id="engineeringGroupDetails" label="Engineering Group" getVisible="GetEngineeringGroupVisibility" >
   <primaryItem>
      <button id="engineeringButton" label="Engineering" imageMso="TableDesign" />
   </primaryItem>
   <topItems>
      <editBox id="engineeringManager" label=" Manager:              " getText="GetEngineeringDetail"/>
      <editBox id="engineeringBudget" label=" Budget:                 " getText="GetEngineeringDetail"/>
      <editBox id="engineeringEndDate" getText="GetEngineeringDetail" label="Completion Date: "/>
      <layoutContainer id="hyperlinkLayout" layoutChildren="horizontal" >
         <labelControl id="hyperlinkLabel" label=" Check Parts Availability:" />
         <hyperlink id="checkPartsHyperlink" label="https://www.microsoft.com" getTarget="GetHyperLink"/>
      </layoutContainer>
   </topItems>
</group>
Sub SwitchGroupsBtn(control As IRibbonControl)
    engGrpVisible = Not engGrpVisible
    If (engGrpVisible = False) Then
      mrktGrpVisible = True
    Else
      mrktGrpVisible = False
    End If
    processRibbon.Invalidate
End Sub

XML 和 VBA 代码按如下方式协作:

  1. 在单击按钮时,将触发 onAction="SwitchGroupsBtn" 回调。

  2. SwitchGroupsBtn 子例程将 engGrpVisible 变量设置为其相反的值。此变量最初设置为 True,以使 engineeringGroupDetails 组在首次显示"Contoso Process"(Contoso 过程)选项卡时显示。

  3. 紧接着,对 engGrpVisible 变量的值进行测试,根据其值将 mrktGrpVisible 变量设置为其相反的值。这意味着,在重置 UI 时(在执行 processRibbon.Invalidate 方法时),设置为 True 的变量将确定显示的组。

    Sub GetMarketingGroupVisibility(control As IRibbonControl, ByRef returnedVal)
        returnedVal = engGrpVisible
    End Sub
    
    Sub GetEngineeringGroupVisibility(control As IRibbonControl, ByRef returnedVal)
        returnedVal = mrktGrpVisible
    End Sub
    
  4. 在重置 UI 时,将触发 getVisible="GetMarketingGroupVisibility" 属性和 getVisible="GetEngineeringGroupVisibility" 属性。由于两个值互为相反值,因此等于 True 的值将确定各个组的可视性。

指定控件的布局

利用 layoutContainer 控件,您可以为其包含的控件指定水平方向或垂直方向。通过将 layoutChildren 属性的值设置为 vertical 或 horizontal 可做到这一点。

图 11. 垂直或水平控件布局的示例

垂直和水平布局

下面的 XML 创建水平控件和垂直控件,如图 11 所示。

<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>

<layoutContainer id="getSpecDetailsControls" layoutChildren="horizontal">
   <button id="getCostBasis" label="Get Cost Basis Info" screentip="Display Cost Basis List" />
   <button id="getCostCodes" label="Get Cost Codes" screentip="Display Cost Code List"/>
   <button id="getTeamCodes" label="Get Team Codes" screentip="Display Team Code List"/>
</layoutContainer>

动态设置控件的样式以强调其状态

可能存在这样的实例,即您需要基于某个条件强调特定组。通过使用 getStyle 属性,您可以从 BackstageGroupStyle 对象的某个枚举返回样式(上一节已对此进行说明)。

图 12. 使用 BackstageGroupStyleError 样式给予强调的组的示例

BackstageGroupStyleError 样式

<group id="openDesignIssuesGroup" label="Open Design Issues" getStyle="GetIssuesStyle" getHelperText="GetIssuesHelperText" >
   <primaryItem>
      <button id="resolveIssuesButton" label="Click to Resolve" imageMso="AcceptInvitation" onAction="ResolveIssues" />
   </primaryItem>
   <topItems>
      <labelControl id="delayIssue" label="Issue: Delay in Material Delivery" getVisible="getIssueVisibility" />
      <labelControl id="equipmentDownIssue" label="Issue: Equipment Down Time" getVisible="getIssueVisibility" />
      <labelControl id="laborDisputeIssue" label="Issue: Labor Dispute" getVisible="getIssueVisibility" />
   </topItems>
</group>
Sub GetIssuesStyle(control As IRibbonControl, ByRef returnedVal)
    If (Not issueResolved) Then
        returnedVal = BackstageGroupStyle.BackstageGroupStyleError
    Else
        returnedVal = BackstageGroupStyle.BackstageGroupStyleNormal
    End If
End Sub

Sub ResolveIssues(control As IRibbonControl)
    issueResolved = True
    issueVisibility = False
    processRibbon.Invalidate
End Sub

Sub getIssueVisibility(control As IRibbonControl, ByRef returnedVal)
    returnedVal = issueVisibility
End Sub

XML 和 VBA 组合的工作方式如下:

  • openDesignIssuesGroup 组周围的区域首先显示为红色 (BackstageGroupStyle.BackstageGroupStyleError),因为 issueResolved 变量为 false。此外, issueVisibility 变量为 true,以便显示所有 labelControls 控件的文本。当您单击 primaryItem 按钮时,将触发 ResolveIssues 回调过程。

  • 此操作将 issueResolved 变量将设置为 True,并将 issueVisiblity 变量设置为 False。然后,使用 processRibbon.Invalidate 方法(此方法会再次触发 ResolveIssues 回调)重置 UI。

  • 这一次, issueResolved 变量为 true,这会使 BackstageGroupStyle.BackstageGroupStyleNormal 值返回 Office。这会导致该组周围的区域切换到默认值(即无任何颜色值)。

  • 此外,当再次调用 ResolveIssues 回调过程时, issueVisiblity 变量(此变量等于 False)将由 getIssueVisibility 过程返回。这会隐藏 labelControls 控件中的文本。

从一组控件同步另一组控件的可视性

可能存在这样的实例,即您可能需要从 Backstage 视图中的其他位置控制一组控件的可视性。例如,您可能需要在其他任务完成之前一直显示签署签名文本框。在下面的示例中,您必须在另一组任务显示之前完成两个任务(通过单击这些任务中的按钮来指示)。完成此第二组任务,然后触发其他控件的显示。此操作将产生级联效果,如图 13 和图 14 所示。

图 13. 显示了前两个任务

显示两个任务

图 14. 完成前两个任务后将触发其他任务的显示

级联效果

<taskGroup id="bidProcessTaskGroup" label="Contract Bid Process Checklist" >
   <category id="defineWorkScopeCategory" getLabel="GetCatHelperText"  >
      <task id="defineScope" label="Define the Scope of Work." tag="Work scope" imageMso="_1" onAction="GetCalcCostCatVisibility"/>
      <task id="assignTasks" label="Assign the Tasks" tag="Task assignments" imageMso="_2" onAction="GetCalcCostCatVisibility"/>
   </category>
   <category id="calculateCostsCategory" getLabel="GetCatHelperText" getVisible="GetCatVisibility" >
      <task id="calcManHours" label="Calculate Total Man-Hours" tag="Calculate Man-Hours" imageMso="_3" onAction="GetTaskCompleteVisibility"/>
      <task id="calcOverheadCosts" label="Determine Overhead Costs" tag="Calculate Overhead Costs" imageMso="_4" onAction="GetTaskCompleteVisibility"/>
  </category>
</taskGroup>
<group id="tasksCompleteImageGroup" >
   <topItems>
      <layoutContainer id="taskCompleteImageLayout" layoutChildren="horizontal" >
         <imageControl id="checkMarkImage" imageMso="AcceptInvitation" getVisible="GetTaskCompleteImageVisibility"/>
         <labelControl id="completionLabel" label="The proposal is ready for review."  getVisible="GetTaskCompleteImageVisibility" />
      </layoutContainer>
   </topItems>
</group>
Sub GetCalcCostCatVisibility(control As IRibbonControl)
    If (control.ID = "defineScope") Then
        taskOneComplete = True
        If (taskOneComplete And taskTwoComplete) Then
            catTwoVisible = True
            processRibbon.InvalidateControl ("calculateCostsCategory")
        End If
    Else
        taskTwoComplete = True
        If (taskOneComplete And taskTwoComplete) Then
            catTwoVisible = True
            processRibbon.InvalidateControl ("calculateCostsCategory")
        End If
    End If
End Sub

此示例中使用的主控件为 taskGroup 控件,该控件包含各类任务。完成一类任务(通过依次单击任务控件可做到这一点)可使另一类任务可见。依次完成这些任务可使 imageControl 控件和 labelControl 控件可见,从而发出所有任务已完成的信号。

按如下方式执行此操作:

  1. 在初始化选项卡时,bidProcessTaskGrouptaskGroup 控件的 defineWorkScopeCategory 类别是可见的。其包含的两个任务控件也是可见的。在单击 defineScope 任务控件时,将调用 GetCalcCostCatVisibility 回调过程。

  2. GetCalcCostCatVisibility 过程将 taskOneComplete 变量将设置为 True,然后它会执行测试以查看 taskOneComplete 变量和 taskTwoComplete 变量是否为 true。因为 taskTwoComplete 变量未设置为 True,所以测试无法进行循环。

  3. 紧接着,在单击 assignTasks 任务控件时,将再次调用 GetCalcCostCatVisibility 过程,并测试 If Then 语句的 Else 部分。发生的第一个事件是, taskTwoComplete 变量将设置为 True。此时,在测试 taskOneComplete 变量和 taskTwoComplete 变量时,二者都为 true,因此 catTwoVisible 变量将设置为 True。然后,对 calculateCostsCategory 类别控件进行重置,这将触发其 GetCatVisibility 回调。

  4. 该子例程将返回 catTwoVisible 变量(此变量之前已设置为 True),以便显示类别。在单击 calcManHours 任务时,将为 calculateCostsCategory 类别中的任务再次启动过程(此次除外)。唯一的区别是,显示 checkMarkImageimageControl 和 completionLabellabelControl 控件以发出所有任务已完成的信号,而不是在任务完成时显示另一个类别。

结论

本文中显示的示例提供了可使用 Backstage 视图执行的一些方案。从概念上说,对于功能区视图和 Backstage 视图而言,用于定义 UI 并使 UI 具有功能性的技术是相同的。我鼓励您使用 UI 自定义进行更多的实践,以了解如何在您的组织中创建有用的应用程序。

其他资源

有关本文中讨论的主题的详细信息,请参阅以下资源:

针对开发人员的 Office 2010 Backstage 视图介绍

为开发人员自定义 2007 Office Fluent 功能区

自定义 UI 编辑器

下载:Office 2010 架构:Fluent 用户界面架构

感谢我的编辑 Linda Cannon 在我撰写此文时为我提供了帮助。