Customizing the Office 2010 Backstage View for Developers

Summary: Microsoft Office 2010 introduces a new interface named the Backstage view. Examine samples that show you how you can extend the user interface for your own applications. (17 Printed pages)

Applies to: Excel 2010 | Office 2007 | Office 2010 | Open XML | PowerPoint 2010 | SharePoint Server 2010 | VBA | Word 2010

In this article
Introduction to the Microsoft Office Backstage View
Initializing the Custom UI
Performing Actions When the Backstage View is First Displayed or Hidden
Creating a Fast Command Button
Creating the Three Types of Column Layouts in the Backstage View
Inserting a Custom Group into a Built-in Tab
Inserting a Custom Task into a Built-in Tab
Dynamically Changing the Visibility of Groups
Specifying the Layout of Controls
Dynamically Setting the Style of a Control to Emphasize Its Status
Synchronizing the Visibility of a Set of Controls from another Set of Controls
Conclusion
Additional Resources

Published:   November 2009

Provided by:   Mirko Mandic, Microsoft Corporation

Contents

  • Introduction to the Microsoft Office Backstage View

  • Initializing the Custom UI

  • Performing Actions When the Backstage View is First Displayed or Hidden

  • Creating a Fast Command Button

  • Creating the Three Types of Column Layouts in the Backstage View

  • Inserting a Custom Group into a Built-in Tab

  • Inserting a Custom Task into a Built-in Tab

  • Dynamically Changing the Visibility of Groups

  • Specifying the Layout of Controls

  • Dynamically Setting the Style of a Control to Emphasize Its Status

  • Synchronizing the Visibility of a Set of Controls from another Set of Controls

  • Conclusion

  • Additional Resources

Introduction to the Microsoft Office Backstage View

One of the newest features of the Microsoft Office 2010 system is the Microsoft Office Backstage view. This user interface (UI), available from the File tab, combines file-level tasks and actions, and replaces similar functionality available from the Microsoft Office button in previous releases of the Microsoft Office system.

Note

You can find more introductory information that include the element and attribute descriptions and callback signatures, in the article titled Introduction to the Office 2010 Backstage View for Developers.

Like the Microsoft Office Fluent Ribbon UI, the Backstage view is fully extensible by using XML to define the structure and components, and programming code, known as callback procedures, to give those components functionality. If you are comfortable extending the Ribbon UI, you will have little problem updating existing tabs and creating a custom Backstage view UI.

You can create custom Backstage views by using Office Open XML formatted files for document-specific customizations, or application-level customizations by using COM add-ins. You can find much more information about these two UI extensibility methods in the series of article titled Customizing the 2007 Office Fluent Ribbon for Developers.

Note

You can find the sample code described in this article in the downloadable file at https://code.msdn.microsoft.com.

The following scenarios describe the XML and the Microsoft Visual Basic for Applications (VBA) code to customize the Backstage view in Microsoft Excel 2010.

Note

To assist you in adding XML and images to your Microsoft Office 2010 programs, you should consider using the Custom UI Editor. You can find the download link to the editor at the end of this article.

Initializing the Custom UI

The onLoad attribute of the <customUI> element is the place to point to code to reference the UI and initialize any variables used in your code. You specify the callback for this event by setting the onLoad attribute of the <customUI> element.

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

The following callback procedure first references the UI through the RibbonUI object. Then several variables that are used throughout the sample code described in this article are initialized.

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

Performing Actions When the Backstage View is First Displayed or Hidden

There may be instances where you want to do something when the Backstage view is displayed or when it is no longer displayed. For example, you may want to display or hide a tab based on some event such as exceeding a specific date. The onShow attribute and the onHide attribute of the <backstage> element can point to code that performs that kind of action. The following is an example of how to use the onShow attribute to set the style of a button in a group.

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

Looking at the VBA code that follows, depending on the value of the date, the showGrpStyle variable is set to one of the following three values:

  • BackstageGroupStyle.BackstageGroupStyleNormal. The group has no special visual treatment,

  • BackstageGroupStyle.BackstageGroupStyleWarning. The group is highlighted in yellow,

  • BackstageGroupStyle.BackstageGroupStyleError. The group is highlighted in red.

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

The XML and code work together as follows:

  1. The Backstage view is displayed which triggers the OnShow callback procedure.

  2. The code in the OnShow procedure tests the date and, depending on its value, sets the showGrpStyle string variable to one of the three enumerations of the BackstageGroupStyle object.

  3. The code then executes the processRibbon.Invalidate method which causes the UI to reset, therefore,, executing the callbacks for each control on the Backstage view.

  4. The getStyle attribute of the workStatusGroup group points to the callback GetWorkStatusStyle which returns the value of the variable showGrpStyle, which, in this case, is one of the enumerated values. This sets the style of the group.

Creating a Fast Command Button

Fast commands are useful for options that you must frequently use. The following XML is used to create a custom Fast Command button that saves the current workbook. It also uses the isDefinitive attribute to close the Backstage view and return to the worksheet. Figure 1 shows the Fast Command created by the XML markup.

Figure 1. The Save and Close Fast command

Save and Close

Looking at the XML, the insertAfterMso="FileSaveAs" attribute assignment inserts the custom button immediately after the Save As command. Notice how the ampersand (&) symbol is inserted into the label by using two &amp;&amp; concatenated tokens.

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

The onAction attribute points to a callback that uses the Save method of the active workbook to save the workbook.

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

Creating the Three Types of Column Layouts in the Backstage View

In the Backstage view, you have three options available when you add custom content. You can specify a single column by using the <firstColumn> element. This option is useful when you want to present information horizontally. You can also specify two columns of information by using both the <firstColumn> and <secondColumn> elements. This is the most typical option. And finally, you have the option to create additional sub-navigation by using the taskFormGroup control. For example, you click different controls in the first column and different groups are displayed in the pane next to it.

A single column layout is created by using just the <firstColumn> element as shown in Figure 2.

Figure 2. An example of a single column layout

Single Column Layout

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

The next segment of XML uses the <firstColumn> and <secondColumn> elements to define two columns of information as shown in Figure 3.

Figure 3. An example of two column layout

Two Column Layout

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

The taskFormGroup control enables you to display groups based on selections in the control. The control uses tasks within categories to contain the group definitions. When you click a task in the taskFormGroup control, the group or groups that are defined inside the <task> element are displayed in the pane next to the task control. Figures 4 and 5 show examples using the taskFormGroup control described in the following XML markup.

Figure 4. Selecting the first group displays one group to its right

First Group Display

Figure 5. Selecting the next group displays a different group to its right

Next Group Display

The following XML demonstrates how to use the taskFormGroup control.

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

When you click the engineeringTeamTasks task in the first column, the engineeringTeamTasksGroup group is displayed in the pane next to the first column. When you click the manufacturingTeamTasks task in column one, the manufacturingTeamTasksGroup group replaces the engineeringTeamTasksGroup group to the right of the column. Therefore, selecting different task controls toggle the display of one or more the groups next to that column. This enables you to display more information in a smaller space.

Inserting a Custom Group into a Built-in Tab

Inserting a group inside a built-in tab resembles inserting a group into a Ribbon tab. You refer to the built-in tab by using the idMso attribute (any attribute using the Mso suffix refers to a built-in control or image). To insert the custom group after a built-in control, you use the insertAfterMso attribute. In the following example, you insert a custom group customPrinter after the built-in group GroupPrintSettings on the built-in Print tab.

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

The use of this XML produces the results shown in Figure 6.

Figure 6. The custom printer group is added to the Print tab

Custom Printer Group

You can also add custom groups to tasks inside built-in tabs. Figure 7 shows what addition of a custom group to a built-in task looks like and the XML following this figure shows how you do this.

Figure 7. The results of adding a custom group to a built-in task

Results of Adding a Custom Group

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

Inserting a Custom Task into a Built-in Tab

In the next example, the taskFormGroup control is inserted into the built-in Share tab. A group is added to the built-in SendUsingEmail task. Different controls are oriented on the tab by using nested layoutContainer controls.

Note

This example also shows a method to get the bulleted text that is used in several built-in groups. It is performed by positioning a custom image representing the bullet next to the label.

The following figure and example resembles the previous example and shows another way to layout controls displayed from a taskFormGroup control. Here the bullet list is defined and then a button is used.

Figure 8. Another example of the layout of controls

Layout Example

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

Dynamically Changing the Visibility of Groups

The following example shows how to dynamically change the visibility of two groups so that it appears as if you are switching the display from one group to another group. This is helpful if the two groups are mutually exclusive. The results of the switch are shown in Figures 9 and 10.

Figure 9. The Marketing group is initially displayed

Marketing Group Display

Figure 10. The visibility of the groups is changed to display the Engineering group

Engineering Group Display

The XML consists of a primaryItem control that contains a menu group of two buttons. Clicking the first button begins the switch. The marketingGroupDetails group and engineeringGroupDetails group are affected by the switch.

<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

The XML and VBA code work together as follows:

  1. When you click the button, the onAction="SwitchGroupsBtn" callback is triggered.

  2. The SwitchGroupsBtn subroutine sets the engGrpVisible variable to its opposite value. Initially this variable is set to True so that the engineeringGroupDetails group is displayed when the Contoso Process tab is first displayed.

  3. Next, the value of the engGrpVisible variable is tested and, depending on its value, the mrktGrpVisible variable is set to its opposite value. This means that when the UI is reset (when the processRibbon.Invalidate method is executed), whichever variable is set to True determines which group is displayed.

    Sub GetMarketingGroupVisibility(control As IRibbonControl, ByRef returnedVal)
        returnedVal = engGrpVisible
    End Sub
    
    Sub GetEngineeringGroupVisibility(control As IRibbonControl, ByRef returnedVal)
        returnedVal = mrktGrpVisible
    End Sub
    
  4. When the UI is reset, the getVisible="GetMarketingGroupVisibility" attribute and the getVisible="GetEngineeringGroupVisibility" attribute are triggered. Because the values are the opposite value of one another, whichever value is equal to True determines the visibility of that respective group.

Specifying the Layout of Controls

The layoutContainer control enables you to specify the horizontal or vertical orientation of the controls it contains. You do this by setting the value of the layoutChildren attribute to either vertical or horizontal.

Figure 11. An example of vertical and horizontal control layout

Vertical and Horizontal Layout

The following XML creates the horizontal and vertical controls shown in Figure 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>

Dynamically Setting the Style of a Control to Emphasize Its Status

There may be instances where you want to call attention to a particular group based on some condition. By using the getStyle attribute, you can return a style from one of the enumerations of the BackstageGroupStyle object (these are described in a previous section).

Figure 12. An example of a group using the BackstageGroupStyleError style to provide emphasis

BackstageGroupStyleError Style

<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

The XML and VBA combination work as follows:

  • The area surrounding the openDesignIssuesGroup group is at first shown as red (BackstageGroupStyle.BackstageGroupStyleError) because the issueResolved variable is false. Also, the issueVisibility variable is true so the text for all of the labelControls controls is displayed. When you click the primaryItem button, this triggers the ResolveIssues callback procedure.

  • This action sets the issueResolved variable to True and the issueVisiblity variable to False. The UI is then reset by using the processRibbon.Invalidate method which again triggers the ResolveIssues callback.

  • This time, the issueResolved variable is true which causes the BackstageGroupStyle.BackstageGroupStyleNormal value to be returned to Office. This causes the area surrounding the group to switch to the default no color value.

  • Additionally, when the ResolveIssues callback procedure is called again, the issueVisiblity variable, which is equal to False, is returned by the getIssueVisibility procedure. This hides the text in the labelControls controls.

Synchronizing the Visibility of a Set of Controls from another Set of Controls

There may be instances where you may want to control the visibility of a set of controls from elsewhere on the Backstage view. For example, you may not want to display a signoff signature text box until other tasks have been completed. In the following example, you must complete two tasks (denoted by clicking the buttons in those tasks) before another set of tasks are displayed. Completing this second set of tasks then triggers the display of other controls. This action produces a cascading effect as shown in Figures 13 and 14.

Figure 13. The first two tasks are displayed

Display Two Tasks

Figure 14. Completing the first two tasks triggers the display of other tasks

Cascading Effect

<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

The primary controls that are used in this example are a taskGroup control, which consists of categories of tasks. Completing one category of tasks, achieved by clicking the tasks controls in sequence, causes another category of tasks to be visible. Completing those tasks in sequence causes an imageControl control and labelControl control to be visible, and therefore signaling that all tasks are complete.

This action is performed as follows:

  1. When the tab is initialized, the defineWorkScopeCategory category of the bidProcessTaskGrouptaskGroup control is visible. The two task controls it contains are also visible. When you click the defineScope task control, the GetCalcCostCatVisibility callback procedure is called.

  2. The GetCalcCostCatVisibility procedure sets the taskOneComplete variable to True. It then tests to see whether taskOneComplete variable and taskTwoComplete variable are true. Because the taskTwoComplete variable is not set to True, the test falls through the loop.

  3. Next, when you click the assignTasks task control, the GetCalcCostCatVisibility procedure is called again and the Else part of the If Then statement is tested. The first thing that happens is that the taskTwoComplete variable is set to True. Now when the taskOneComplete variable and the taskTwoComplete variable are tested, both are true so the catTwoVisible variable is set to True. Then the calculateCostsCategory category control is reset which triggers its GetCatVisibility callback.

  4. This subroutine returns the catTwoVisible variable, which was set to True previously, so that the category is displayed. When you click the calcManHours task, the process starts again, except this time, for the tasks in the calculateCostsCategory category. The only difference is that instead of displaying another category when both tasks are completed, the checkMarkImageimageControl and completionLabellabelControl controls are displayed, signaling that all tasks are completed.

Conclusion

The examples shown in this article offer some scenarios that you can perform with the Backstage view. The techniques for defining the UI and giving it functionality are conceptually same for the Ribbon and the Backstage view. I encourage you to experiment more with UI customization to see how you can create useful application in your organization.

Additional Resources

For more information about the topics discussed in this article, see the following resources:

Introduction to the Office 2010 Backstage View for Developers

Customizing the 2007 Office Fluent Ribbon for Developers

Download: Office 2010 Schema: Fluent User Interface Schema

Special thanks to my editor Linda Cannon for her help with this article.