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:
The Backstage view is displayed which triggers the OnShow callback procedure.
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.
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.
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
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 && concatenated tokens.
<button id="saveBtn" label="Save && 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
<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
<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
Figure 5. Selecting the next group displays a different group to its right
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
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
<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
<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
Figure 10. The visibility of the groups is changed to display the Engineering group
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:
When you click the button, the onAction="SwitchGroupsBtn" callback is triggered.
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.
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
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
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
<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
Figure 14. Completing the first two tasks triggers the display of other tasks
<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:
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.
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.
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.
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.