Dynamically Changing the Visibility of Groups and Controls in the Office 2010 Backstage View

Office Visual How To

Summary:  Learn to dynamically change the visibility of controls that are based on actions taken in other controls in the Office 2010 Backstage View.

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

Published:  May 2010

Provided by:  Michael Case, iSoftStone

Overview

The Microsoft Office Backstage view, new to Office 2010, replaces the traditional File menu to provide a centralized space for file management tasks such as opening new or existing files, defining document properties, and sharing information. Like the Microsoft Office Fluent ribbon, the Backstage view is fully extensible by using XML to define the structure, components, and callback procedures to give those components functionality.

In certain instances you may want to hide or display Backstage view controls based on actions the customer takes from other controls in the Backstage view. This article illustrates techniques for dynamically changing the visibility of a Backstage view group control and dynamically changing the visibility of individual controls based on customer actions.

This article uses Trang Luu's Custom UI Editor to simplify adding custom user interface (UI) XML to the Microsoft Excel 2010 workbook. You must download and install the Custom UI Editor to follow the steps provided in this article.

Code It

This article customizes the Backstage view for a Microsoft Excel 2010 workbook by using a combination of XML and Microsoft Visual Basic for Applications (VBA) code. The XML defines a custom tab and the controls to display in the Backstage view. The VBA code provides the functionality required by the callback procedures defined in the custom UI XML. It also walks you through the following steps to show how to create a customized Backstage view in an Excel 2010 workbook:

  1. Create a sample Excel workbook with a Backstage view.

  2. Add the custom UI XML.

  3. Add the VBA callback code.

  4. View the custom Backstage view page.

Creating the Sample Excel Workbook

In this Visual How To, you add custom UI XML and VBA code to an Excel 2010 workbook.

Note

You must create the Excel workbook as a macro-enabled workbook (.xlsm) to support the VBA code.

To create the workbook

  1. Start Microsoft Excel 2010.

  2. On the File menu, click Save As.

  3. In the Save As dialog box, in the Save as type drop-down list, select Excel macro-enabled workbook (*.xlsm).

  4. Save the document as C:\Temp\BackstageViewDynamicVisibility.xlsm.

Adding the Custom UI XML

The Custom UI Editor simplifies adding custom UI XML to the workbook that you created in the previous step.

To add the custom UI XML

  1. Start the Custom UI Editor.

  2. On the File menu, click Open.

  3. Select the C:\Temp\BackstageViewDynamicVisibility.xlsm file created in the previous step and click the Open button.

  4. On the Insert menu, click Office 2010 Custom UI Part. This creates a CustomUI14.xml file in the document.

  5. Select the CustomUI14.xml file and copy the following XML into the file.

    <?xml version="1.0" encoding="utf-8"?>
    <!-- customUI is the root tag of all Fluent UI customizations -->
    <customUI xmlns="https://schemas.microsoft.com/office/2009/07/customui"
              onLoad="onLoad">
      <!-- Backstage defines custom structure of the Backstage UI. -->
      <backstage>
        <!-- Tab defines the name to display in the Backstage
             view tab and the controls to display on the page when 
             the tab is selected. -->
        <tab id="dynamicVisibilityTab" label="Dynamic Visibility" 
             insertAfterMso="TabInfo">
          <!-- The controls in the first column illustrate
               how to dynamically set the visibility of a group control 
               based on an action taken in another control. -->
          <firstColumn>
            <group id="specDetailsGroup" label="Specification Details" 
                   helperText="Keep the following information up to date.">
              <primaryItem>
                <menu id="switchMenu" label="Groups" 
                      imageMso="ControlLayoutStacked" >
                  <menuGroup id="menuGroup">
                    <!-- The onAction callback switches between
                         displaying the Marketing Group or the Engineering
                         Group. -->
                    <!-- The getLabel callback changes the
                         text on the button based on the group that is 
                         currently displayed. -->
                    <button id="switchGroups" 
                            getLabel="GetSwitchGroupsLabel" 
                            onAction="SwitchGroups"/>
                  </menuGroup>
                </menu>
              </primaryItem>
              <topItems>
                  <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"/>
              </topItems>
            </group>
            <!-- The getVisible callback determines whether to 
                 display the Marketing Group displayed based on the current 
                 switchGroups button selection. -->
            <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" 
                         label="Completion Date: " 
                         getText="GetMarketingDetail"/>
              </topItems>
            </group>
            <!-- The getVisible callback determines whether the 
                 Engineering Group should display based on the 
                 current switchGroups button selection. -->
            <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" 
                         label="Completion Date: " 
                         getText="GetEngineeringDetail"/>
              </topItems>
            </group>
          </firstColumn>
          <!-- The controls in the second column illustrate how to 
               dynamically set the visibility of individual controls
               based on actions taken in other controls. -->
          <secondColumn>
            <taskGroup id="bidProcessTaskGroup" 
                       label="Contract Bid Process Checklist" >
              <!-- The first task category always displays. -->
              <!-- The onAction callback marks tasks as 
                   completed when the task is clicked. -->
              <category id="defineWorkScopeCategory" 
                        label="Define work and tasks - Complete tasks in order.">
                <task id="defineScope" label="Define the Scope of Work." 
                      imageMso="_1" onAction="SetTaskComplete"/>
                <task id="assignTasks" label="Assign the Tasks" 
                      imageMso="_2" onAction="SetTaskComplete"/>
              </category>
              <!-- The getVisible callback only displays the 
                   second task category after the tasks in the first 
                   category complete. -->
              <!-- The onAction callback marks tasks as 
                   complete when the task is clicked. -->
              <category id="calculateCostsCategory" 
                        label="Calculate costs - Complete tasks in order."
                        getVisible="GetCalculateCostsVisibility" >
                <task id="calcManHours" label="Calculate Total Man-Hours" 
                      imageMso="_3" onAction="SetTaskComplete"/>
                <task id="calcOverheadCosts" label="Determine Overhead Costs" 
                      imageMso="_4" onAction="SetTaskComplete"/>
              </category>
            </taskGroup>
            <group id="tasksCompleteGroup" >
              <topItems>
                <layoutContainer id="tasksCompleteLayout" 
                                 layoutChildren="horizontal" >
                  <!-- The getVisible callback only displays 
                       this set of individual controls after all tasks 
                       complete. -->
                  <imageControl id="tasksCompleteImage" 
                                imageMso="AcceptInvitation" 
                                getVisible="GetTasksCompleteVisibility"/>
                  <labelControl id="tasksCompleteLabel" 
                                label="The proposal is ready for review."
                                getVisible="GetTasksCompleteVisibility" />
                </layoutContainer>
              </topItems>
            </group>
          </secondColumn>
        </tab>
      </backstage>
    </customUI>
  6. On the File menu, click Save.

  7. Close the Custom UI Editor.

Adding the VBA Callback Code

The VBA callback procedures add functionality to the custom Backstage view components that you added by using custom UI XML in the previous procedure.

To add the VBA callback code

  1. Start Microsoft Excel 2010.

  2. On the File tab, click Open.

  3. Open the C:\Temp\BackstageViewDynamicVisibility.xlsm workbook.

  4. Select the Developer tab.

  5. Click Visual Basic.

  6. On the Insert menu, click Module.

  7. Select Module1 and copy the following VBA code into the file.

    'Reference to the ribbon for refreshing the UI.
    Public processRibbon As IRibbonUI
    
    'Variables that track the group that is displayed.
    Public engineeringGroupVisible As Boolean
    Public marketingGroupVisible As Boolean
    
    'Variables that track the completed tasks.
    Public taskOneComplete As Boolean
    Public taskTwoComplete As Boolean
    Public taskThreeComplete As Boolean
    Public taskFourComplete As Boolean
    
    'Callback for customUI.onLoad.
    Sub onLoad(ribbon As IRibbonUI)
      'Store a reference to the ribbon for refreshing the UI.
      Set processRibbon = ribbon
        
      'Initialize to display the Engineering Group first.
      engineeringGroupVisible = True
    End Sub
    
    'Visibility for the Engineering Group group control.
    Sub GetEngineeringGroupVisibility(control As IRibbonControl, _
                                      ByRef returnedVal)
      returnedVal = engineeringGroupVisible
    End Sub
    
    'Visibility for the Marketing Group group control.
    Sub GetMarketingGroupVisibility(control As IRibbonControl, _
                                    ByRef returnedVal)
      returnedVal = marketingGroupVisible
    End Sub
    
    'Called when the Switch Groups button is clicked.
    'The variables tracking the visible group are swapped
    ' to switch the display between the two groups.
    Sub SwitchGroups(control As IRibbonControl)
      engineeringGroupVisible = Not engineeringGroupVisible
      marketingGroupVisible = Not engineeringGroupVisible
      
      'Invalidate resets the UI. This causes all controls
      ' to redisplay and execute all relevant callbacks.
      processRibbon.Invalidate
    End Sub
    
    'Label to display for the Switch Groups button.
    'Text returned is based on the current group that is displayed.
    Sub GetSwitchGroupsLabel(control As IRibbonControl, ByRef returnedVal)
      If (engineeringGroupVisible) Then
        returnedVal = "Switch to Marketing Group"
      Else
        returnedVal = "Switch to Engineering Group"
      End If
    End Sub
    
    'Returns the text to display for each Specification Detail editBox.
    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
    
    'Returns the text to display for each Marketing editbox.
    Sub GetMarketingDetail(control As IRibbonControl, ByRef returnedVal)
      Select Case control.ID
        Case "marketingManager"
          returnedVal = "Janet Leverling"
        Case "marketingBudget"
          returnedVal = "$144,078"
        Case "marketingEndDate"
          returnedVal = Date + 20
      End Select
    End Sub
    
    'Returns the text to display for each Engineering editbox.
    Sub GetEngineeringDetail(control As IRibbonControl, ByRef returnedVal)
      Select Case control.ID
        Case "engineeringManager"
          returnedVal = "Robert Jones"
        Case "engineeringBudget"
          returnedVal = "$197,955"
        Case "engineeringEndDate"
          returnedVal = Date + 10
      End Select
    End Sub
    
    'Visibility for the second task category.
    'The second task category does not display until tasks in the 
    ' first task category are marked complete.
    Sub GetCalculateCostsVisibility(control As IRibbonControl, _
                                    ByRef returnedVal)
      If (taskOneComplete And taskTwoComplete) Then
        returnedVal = True
      Else
        returnedVal = False
      End If
    End Sub
    
    'Visibility for the task complete controls.
    'The task complete controls do not display until all tasks 
    ' are marked complete.
    Sub GetTasksCompleteVisibility(control As IRibbonControl, _
                                   ByRef returnedVal)
      If (taskOneComplete And taskTwoComplete _
          And taskThreeComplete And taskFourComplete) Then
        returnedVal = True
      Else
        returnedVal = False
      End If
    End Sub
    
    'Called when a task is clicked.
    'Marks the task as complete and then calls the InvalidateControl method to
    ' redisplay only the controls impacted by the change in status.
    Sub SetTaskComplete(control As IRibbonControl)
      Select Case control.ID
        Case "defineScope"
          taskOneComplete = True
          'Redisplay the second category control
          processRibbon.InvalidateControl("calculateCostsCategory")
        Case "assignTasks"
          taskTwoComplete = True
          'Redisplay the second category control
          processRibbon.InvalidateControl("calculateCostsCategory")
        Case "calcManHours"
          taskThreeComplete = True
          'Redisplay the task complete controls
          processRibbon.InvalidateControl("tasksCompleteImage")
          processRibbon.InvalidateControl("tasksCompleteLabel")
        Case "calcOverheadCosts"
          taskFourComplete = True
          'Redisplay the task complete controls
          processRibbon.InvalidateControl("tasksCompleteImage")
          processRibbon.InvalidateControl("tasksCompleteLabel")
      End Select
    End Sub
  8. On the File menu, click Save.

  9. Close the Visual Basic for Applications Editor and return to the workbook.

View the Custom Backstage View Page

To view the custom Backstage view page defined above, display the Backstage view by selecting the File tab. This is the new Backstage view. After the Backstage view is displayed, select the Dynamic Visibility tab, which is located on the built-in Info tab. When you select the Dynamic Visibility tab, the custom Backstage view page defined in the previous steps is displayed.

Figure 1. Custom Backstage view page

Custom Backstage view page

 

Read It

Extending the Office 2010 Backstage view to include custom pages and controls requires a combination of adding custom UI XML to the Office document and adding VBA code to provide functionality for the callbacks specified in the custom UI XML.

The sample code shows how to dynamically change the visibility of a Backstage view group control or the visibility of individual controls based on actions taken using other controls in the Backstage view.

Initialize the Custom UI

In some cases, a callback procedure makes a change that requires redisplaying Backstage view controls. To redisplay Backstage view controls, call the Invalidate method or the InvalidateControl method of the RibbonUI object.

The following code example shows how to store a reference to the RibbonUI control when the custom UI is loaded. The customUI element contains the onLoad attribute. In this instance, the attribute specifies the OnLoad callback. The OnLoad callback stores a reference to the RibbonUI object. The RibbonUI object is used in callbacks to redisplay the Backstage view controls. The onLoad callback also initializes variables used in the code.

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

'Variables that track the group that is displayed.
Public engineeringGroupVisible As Boolean
Public marketingGroupVisible As Boolean

'Variables that track the completed tasks.
Public taskOneComplete As Boolean
Public taskTwoComplete As Boolean
Public taskThreeComplete As Boolean
Public taskFourComplete As Boolean

'Callback for customUI.onLoad.
Sub onLoad(ribbon As IRibbonUI)
  'Store a reference to the ribbon for refreshing the UI.
  Set processRibbon = ribbon
    
  'Initialize to display the Engineering Group first.
  engineeringGroupVisible = True
End Sub

Dynamically Change the Visibility of a Group Control

Sometimes you may want to display a Backstage view group control that is based on actions taken by the user using other controls. This article discusses switching between displaying the Engineering Group group or the Marketing Group group based on the selection made in the Groups menu of the Specification Detail.

The following custom UI XML examples show how to specify the callbacks to dynamically switch the display between the two groups. The Groups button specifies an onAction callback that switches between the Engineering Group controls and Marketing Group controls. The Marketing Group control and Engineering Group control specify the getVisibility callbacks. These callbacks determine whether the group should be displayed or hidden.

<primaryItem>
  <menu id="switchMenu" label="Groups" 
        imageMso="ControlLayoutStacked" >
    <menuGroup id="menuGroup">
      <!-- The onAction callback switches between
           displaying the Marketing Group or the Engineering
           Group below. -->
      <button id="switchGroups" 
              getLabel="GetSwitchGroupsLabel" 
              onAction="SwitchGroups"/>
    </menuGroup>
  </menu>
</primaryItem>
...
<!-- The getVisible callback determines if the 
     Marketing Group should display based on the current 
     switchGroups button selection. -->
<group id="marketingGroupDetails" label="Marketing Group" 
       getVisible="GetMarketingGroupVisibility">
  ...
</group>
<!-- The getVisible callback determines if the 
     Engineering Group should display based on the 
     current switchGroups button selection. -->
<group id="engineeringGroupDetails" label="Engineering Group" 
       getVisible="GetEngineeringGroupVisibility" >
  ...
</group>

The following code example shows how the onAction callback of the Groups menu in the Specification Detail, SwitchGroups, switches between displaying the Engineering Group control or the Marketing Group control. The SwitchGroups callback reverses the Boolean values of the engineeringGroupVisible variable and marketingGroupVisible variable that determine whether the group control should be displayed. After the variables are changed, the Invalidate method of the RibbonUI object is called to redisplay the Backstage view controls. When the Invalidate method is called, the getVisible callbacks for the Engineering Group control and Marketing Group control are re-executed causing a switch in which group displayed.

'Called when the Switch Groups button is clicked.
'The variables tracking which group is visible are swapped
' to switch the display between the two groups.
Sub SwitchGroups(control As IRibbonControl)
  engineeringGroupVisible = Not engineeringGroupVisible
  marketingGroupVisible = Not engineeringGroupVisible
  
  'The Invalidate method resets the UI causing all controls
  ' to redisplay and executing all relevant callbacks.
  processRibbon.Invalidate
End Sub

The following code example shows how the GetVisible callback and the GetEngineeringGroupVisibility callback of the Engineering Group control, and the getVisible callback and the GetMarketingGroupVisibilty callback of the Marketing Group control, control the display of the groups. Both callbacks work by returning the Boolean value of the variable that tracks if the group should be visible.

'Visibility for the Engineering Group control.
Sub GetEngineeringGroupVisibility(control As IRibbonControl, _
                                  ByRef returnedVal)
  returnedVal = engineeringGroupVisible
End Sub

'Visibility for the Marketing Group control.
Sub GetMarketingGroupVisibility(control As IRibbonControl, _
                                ByRef returnedVal)
  returnedVal = marketingGroupVisible
End Sub

Dynamically Change the Visibility of Individual Controls

There may be instances where you want to display individual Backstage view controls that are based on actions taken by the user using other controls. This article displays an initial set of tasks for defining work scope. After these initial tasks are marked as complete, a second set of tasks are displayed for calculating costs. After all tasks are marked as complete, an image and label identifying that all tasks are completed are displayed.

The following custom UI XML example shows how to specify the callbacks to dynamically display individual controls that are based on user actions in other controls. The getVisible callback of the Calculate Costs task of the category is specified to only display these tasks after the category control tasks of the Define Work Scope are marked as completed. The task complete image and task complete label controls set their getVisible callback to only display the controls after all tasks are completed. Each task control sets its onAction callback to mark the task as complete.

<taskGroup id="bidProcessTaskGroup" 
           label="Contract Bid Process Checklist" >
  <!-- The first task category always displays -->
  <!-- The onAction callback marks tasks as 
       completed when the task is clicked. -->
  <category id="defineWorkScopeCategory" 
            label="Define work and tasks - Complete tasks in order.">
    <task id="defineScope" label="Define the Scope of Work." 
          imageMso="_1" onAction="SetTaskComplete"/>
    <task id="assignTasks" label="Assign the Tasks" 
          imageMso="_2" onAction="SetTaskComplete"/>
  </category>
  <!-- The getVisible callback only displays the 
       second task category after the tasks in the first 
       category are complete. -->
  <!-- The onAction callback marks tasks as 
       complete when the task is clicked -->
  <category id="calculateCostsCategory" 
            label="Calculate costs - Complete tasks in order."
            getVisible="GetCalculateCostsVisibility" >
    <task id="calcManHours" label="Calculate Total Man-Hours" 
          imageMso="_3" onAction="SetTaskComplete"/>
    <task id="calcOverheadCosts" label="Determine Overhead Costs" 
          imageMso="_4" onAction="SetTaskComplete"/>
  </category>
</taskGroup>
<group id="tasksCompleteGroup" >
  <topItems>
    <layoutContainer id="tasksCompleteLayout" 
                     layoutChildren="horizontal" >
      <!-- The getVisible callback only displays 
           this set of individual controls after all tasks 
           are complete. -->
      <imageControl id="tasksCompleteImage" 
                    imageMso="AcceptInvitation" 
                    getVisible="GetTasksCompleteVisibility"/>
      <labelControl id="tasksCompleteLabel" 
                    label="The proposal is ready for review."
                    getVisible="GetTasksCompleteVisibility" />
    </layoutContainer>
  </topItems>
</group> <!-- The getStyle callback and getHelperText callback 
      dynamically set the Open Design Issues Group style 
      and text based on if there are any open issues. -->
<group id="openDesignIssuesGroup" label="Open Design Issues"
       getStyle="GetIssuesStyle" 
       getHelperText="GetIssuesHelperText">
  <topItems>
    <!-- The layoutChildren attribute lays out 
          each set of issues controls horizontally. -->
    <!-- The onAction callback marks issues as resolved 
          when the "Click to Resolve" button is clicked. -->
    <!-- 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>

The following code example shows how the getVisible callback and the GetCalculateCostsVisibility callback of the Calculate Costs task category control, control the display of the Calculate Costs category. Initially no tasks are completed and the GetCalculateCostsVisibility method returns False to hide the category control of the Calculate Costs task. When all tasks in the Define Work Scope category are completed, the GetCalculateCostsVisibility method returns True to display the Calculate Costs task category.

'Visibility for the second task category.
'The second task category does not display until tasks in the 
' first task category are marked as complete.
Sub GetCalculateCostsVisibility(control As IRibbonControl, _
                                ByRef returnedVal)
  If (taskOneComplete And taskTwoComplete) Then
    returnedVal = True
  Else
    returnedVal = False
  End If
End Sub

The following code example shows how the getVisible callback of the imageControl control and labelControl control, the GetTasksCompleteVisibility method, hides the tasks complete controls until all tasks are marked as completed. Initially no tasks are completed and the GetTasksCompleteVisibility method returns False to hide the tasks complete controls. After all tasks in both the Define Work Scope category and Calculate Costs category are marked as complete the GetTasksCompleteVisibility method returns True to display the tasks complete controls.

'Visibility for the task complete controls.
'The task complete controls do not display until all tasks '
' are marked as complete.
Sub GetTasksCompleteVisibility(control As IRibbonControl, _
                               ByRef returnedVal)
  If (taskOneComplete And taskTwoComplete _
      And taskThreeComplete And taskFourComplete) Then
    returnedVal = True
  Else
    returnedVal = False
  End If
End Sub

The following code fragment shows how the onAction callback of the task control, SetTaskComplete, marks tasks as completed. The SetTaskComplete callback identifies which task was clicked and sets the appropriate task complete variable to True. After the task is marked as complete, the InvalidateControl method of the RibbonUI object is called to limit the redisplay and re-execution of callbacks to only those Backstage view controls affected by the change. Tasks in the Define Work Scope category can only affect the display of the Calculate Costs category control so the control identifier for the category control for the Calculate Costs control, calculateCostsCategory, is passed to the InvalidateControl method when these tasks are marked as completed. Tasks in the Calculate Costs category can only affect the display of the task complete imageControl object and labelControl object so the InvalidateControl method is called for each control when the tasks are marked as completed.

'Called when a task is clicked.
'Marks the task as complete and then calls the InvalidateControl method to
' redisplay only the controls impacted by the change in status.
Sub SetTaskComplete(control As IRibbonControl)
  Select Case control.ID
    Case "defineScope"
      taskOneComplete = True
      'Redisplay the second category control.
      processRibbon.InvalidateControl ("calculateCostsCategory")
    Case "assignTasks"
      taskTwoComplete = True
      'Redisplay the second category control.
      processRibbon.InvalidateControl ("calculateCostsCategory")
    Case "calcManHours"
      taskThreeComplete = True
      'Redisplay the task complete controls.
      processRibbon.InvalidateControl ("tasksCompleteImage")
      processRibbon.InvalidateControl ("tasksCompleteLabel")
    Case "calcOverheadCosts"
      taskFourComplete = True
      'Redisplay the task complete controls.
      processRibbon.InvalidateControl ("tasksCompleteImage")
      processRibbon.InvalidateControl ("tasksCompleteLabel")
  End Select
End Sub 
'Called when a resolve issue button is clicked.
'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 method is called to reset the UI causing all controls
  ' to redisplay and executing all relevant callbacks.
  processRibbon.Invalidate
End Sub
See It

Watch the video

> [!VIDEO https://www.microsoft.com/en-us/videoplayer/embed/6ea37be8-69f8-42ef-a4a6-9700f4fb9dc3]

Length: 00:08:02

Click to grab code

Grab the Code

Explore It

 

About the Author

Michael Case is a Senior Software Developer at iSoftStonewhere he works with clients creating custom software solutions. He has over 16 years of experience developing both desktop solutions and Web-based solutions using Microsoft technologies and the Microsoft .NET Framework.