Exercise 1: Customizing Office with Ribbons and Backstage
Backstage is a perfect place to put UI elements that take up space but are not necessary when actively editing the document. In this case you will be using Backstage and a Ribbon together to create multiple parts of a complete add-in.
Task 1 – Add Export Backstage tab
In this first task, you will create a new Backstage tab named Export to manage the quick export functionality.
- Add a new XML Ribbon item to the existing ExportAddIn project
- Open VisualStudio 2010 and open the starter lab at %Office2010DeveloperTrainingKitPath%\Labs\OfficeUI\Source\[language]\Starter\ExportAddIn\ExportAddIn.sln
- Right click ExportAddIn in the Solution Explorer and choose Add -> New Item.
- In the Add New Item dialog, select the Office category.
- Choose the Ribbon (XML) item type and enter a name of Ribbon.vb(in case of VB) & Ribbon.cs(in case of C#)
- Click Add to create the new ribbon
.png)
Figure 1(a)-In case of C#Add Ribbon (XML) Item
.png)
Figure 1(b)-In case of VBAdd Ribbon (XML) Item
- Open the Ribbon.xml file located in the Solution Explorer
- Add XML Markup to the Ribbon.xml file to define the Export Backstage tab
- Remove the current ribbon node from the Ribbon.xml file
- Add the following markup to define the Backstage tab and the first column of information
<backstage>
<tab id="tabExport" label="Export" insertAfterMso="TabInfo">
<firstColumn>
</firstColumn>
</tab>
</backstage>
- Inside the firstColumn element, add the following markup to define the group containing the XPS export controls
<group id="grpExportXPS" label="Export as XPS"
helperText="Exports the current document as XPS.">
<primaryItem>
<button id="btnBackStageXPS" label="To XPS"
getImage="GetButtonImage" />
</primaryItem>
<topItems>
<checkBox id="chkEnableXPS" label="Allow XPS Export" />
<editBox id="txtXPSPath" label="Export Path"
sizeString="WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW" />
</topItems>
</group>
The XPS output controls are made up of a button to perform the export, a check box to enable or disable exporting to XPS and a edit box to define the filename of the exported file.
- Immediately following the previous group, add the following markup to define the PDF export controls
<group id="grpExportPDF" label="Export as PDF"
helperText="Exports the current document as PDF.">
<primaryItem>
<button id="btnBackStagePDF" label="To PDF"
getImage="GetButtonImage" />
</primaryItem>
<topItems>
<checkBox id="chkEnablePDF" label="Allow PDF Export" />
<editBox id="txtPDFPath" label="Export Path"
sizeString="WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW" />
</topItems>
</group>
- Define the code that will load images for the export buttons
- Open Ribbon.vb(in case of VB) & Ribbon.cs(in case of C#) by double clicking it in the Solution Explorer
- Add the following GetButtonImage method to the Ribbon class
public System.Drawing.Bitmap GetButtonImage(
Office.IRibbonControl control)
{
switch (control.Id)
{
case "btnBackStageXPS":
return Properties.Resources.XPS;
case "btnBackStagePDF":
return Properties.Resources.PDF;
default:
return null;
}
}
Public Function GetButtonImage(ByVal control As Office.IRibbonControl) As System.Drawing.Bitmap
Select Case control.Id
Case "btnBackStageXPS"
Return My.Resources.XPS
Case "btnBackStagePDF"
Return My.Resources.PDF
Case Else
Return Nothing
End Select
End Function
The getImage attribute in the button elements define a public method Office will call any time a button loads. This method uses a switch command to differentiate between the different buttons.
- Override the CreateRibbonExtensibilityObject method in the add-in to define the ribbon to load
- Open the ThisAddIn class by double clicking it in the Solution Explorer
- In the ThisAddIn class, override the CreateRibbonExtensibilityObject method and return a new Ribbon object
protected override
Office.IRibbonExtensibility CreateRibbonExtensibilityObject()
{
return new Ribbon();
}
Protected Overrides Function CreateRibbonExtensibilityObject() As Office.IRibbonExtensibility
Return New Ribbon()
End Function
- Run the add-in and verify the Backstage tab looks correct
- In the Debug menu, click Start Without Debugging
- Once Word 2010 loads, click the Backstage button (labeled as File)
- In Backstage switch to the Export tab and verify it looks like the image below
.png)
Figure 2Custom Backstage Export tab
Task 2 – Connect Backstage tab to document properties
In this task, you will connect the controls in the Export tab to the CustomDocumentProperties object in the active document. This will allow the state of the controls to be persisted in the document and loaded when the document is loaded later.
- Define the code behind that will determine when the button and editBox controls are enabled
- Open Ribbon.xml by double clicking it in the SolutionExplorer
- Add a getEnabled attribute to the button and editBox controls
<button id="btnBackStageXPS"
... />
You should find 2 button controls and 2 editBox controls
- Open Ribbon.vb(in case of VB) & Ribbon.cs(in case of C#) by double clicking it in the Solution Explorer
- Add the following private field to the class
private ExportProperties m_properties = new ExportProperties();
Private m_properties As New ExportProperties()
The ExportProperties class is a wrapper provided for you that wraps the CustomDocumentProperties collection of the current ActiveDocument.
- Create a GetEnable method to determine the enable state of other controls.
public bool GetEnable(Office.IRibbonControl control)
{
switch (control.Id)
{
case "btnBackStageXPS":
case "txtXPSPath":
return m_properties.XpsEnabled;
case "btnBackStagePDF":
case "txtPDFPath":
return m_properties.PdfEnabled;
default:
return false;
}
}
Public Function GetEnable(ByVal control As Office.IRibbonControl) As Boolean
Select Case control.Id
Case "btnBackStageXPS", "txtXPSPath"
Return m_properties.XpsEnabled
Case "btnBackStagePDF", "txtPDFPath"
Return m_properties.PdfEnabled
Case Else
Return False
End Select
End Function
- Add code to populate and respond to events from the enabled checkboxes
- Open Ribbon.xml by double clicking it in the SolutionExplorer
- Add a getPressed and onAction attribute to every checkBox element in the Backstage markup
<checkBox id="chkEnablePDF"
getPressed="IsEnableChecked"
onAction="EnableChecked"
.../>
You should find 2 checkBox controls
- Open Ribbon.vb(in case of VB) & Ribbon.cs(in case of C#) by double clicking it in the Solution Explorer
- Create an IsEnableChecked method that will respond to requests from check box controls to get their current state
public bool IsEnableChecked(Office.IRibbonControl control)
{
if (control.Id == "chkEnableXPS")
return m_properties.XpsEnabled;
else if (control.Id == "chkEnablePDF")
return m_properties.PdfEnabled;
else
return false;
}
Public Function IsEnableChecked(ByVal control As Office.IRibbonControl) As Boolean
If control.Id = "chkEnableXPS" Then
Return m_properties.XpsEnabled
ElseIf control.Id = "chkEnablePDF" Then
Return m_properties.PdfEnabled
Else
Return False
End If
End Function
- Create an EnableChecked method that will respond to the checking of a check box
public void EnableChecked(Office.IRibbonControl control, bool value)
{
if (control.Id == "chkEnableXPS")
{
m_properties.XpsEnabled = value;
ribbon.InvalidateControl("btnBackStageXPS");
ribbon.InvalidateControl("txtXPSPath");
}
else if (control.Id == "chkEnablePDF")
{
m_properties.PdfEnabled = value;
ribbon.InvalidateControl("btnBackStagePDF");
ribbon.InvalidateControl("txtPDFPath");
}
}
Public Sub EnableChecked(ByVal control As Office.IRibbonControl, ByVal value As Boolean)
If control.Id = "chkEnableXPS" Then
m_properties.XpsEnabled = value
ribbon.InvalidateControl("btnBackStageXPS")
ribbon.InvalidateControl("txtXPSPath")
ElseIf control.Id = "chkEnablePDF" Then
m_properties.PdfEnabled = value
ribbon.InvalidateControl("btnBackStagePDF")
ribbon.InvalidateControl("txtPDFPath")
End If
End Sub
The calls to ribbon.InvalidateControl force those controls to reevaluate their state. This will lead to another call to GetEnabled that will now have a different result.
- Add code to populate and respond to events from the path edit boxes
- Open Ribbon.xml by double clicking it in the SolutionExplorer
- Add a getText and onChange attribute to every editBox element
<editBox id="txtPDFPath"
getText="GetExportPath"
onChange="SetExportPath"
... />
You should find 2 editBox controls
- Open Ribbon.vb(in case of VB) & Ribbon.cs(in case of C#) by double clicking it in the Solution Explorer
- Create a GetExportPath method that will retrieve the current export path for the editBox controls
public string GetExportPath(Office.IRibbonControl control)
{
if (control.Id == "txtXPSPath")
return m_properties.XpsExportPath;
else if (control.Id == "txtPDFPath")
return m_properties.PdfExportPath;
else
return string.Empty;
}
Public Function GetExportPath(ByVal control As Office.IRibbonControl) As String
If control.Id = "txtXPSPath" Then
Return m_properties.XpsExportPath
ElseIf control.Id = "txtPDFPath" Then
Return m_properties.PdfExportPath
Else
Return String.Empty
End If
End Function
- Create a SetExportPath method that will respond to the change event of the editBox control
public void SetExportPath(Office.IRibbonControl control, string value)
{
if (control.Id == "txtXPSPath")
m_properties.XpsExportPath = value;
else if (control.Id == "txtPDFPath")
m_properties.PdfExportPath = value;
}
Public Sub SetExportPath(ByVal control As Office.IRibbonControl, ByVal value As String)
If control.Id = "txtXPSPath" Then
m_properties.XpsExportPath = value
ElseIf control.Id = "txtPDFPath" Then
m_properties.PdfExportPath = value
End If
End Sub
- Run the add-in and verify the enable checkboxes work
- In the Debug menu, click Start Without Debugging
- Once Word 2010 loads, click the Backstage button (labeled as File)
- In Backstage switch to the Export tab
- Check and uncheck the enabled checkboxes and verify the related controls are enabled and disabled
.png)
Figure 1Enable check box in Backstage tab
Task 3 – Add quick export buttons to the Home ribbon tab
In this task, you will add a Quick Export ribbon button to the Home ribbon tab. It will tie into the same functionality as the buttons on Backstage.
- Add the ribbon markup to the Ribbon.xml file
- Open Ribbon.xml by double clicking it in the SolutionExplorer
- Add the markup that will create a new Quick Export group in the Home tab
- Make sure the ribbon xml element is added before the backstage xml element
<ribbon>
<tabs>
<tab idMso="TabHome">
<group id="grpQuickExport" autoScale="true">
</group>
</tab>
</tabs>
</ribbon>
The use of the idMso attribute tells Office to put the following group in the existing tab.
- Inside the grpQuickExport group element, add a menu control using an existing image within Office
<menu id="btnQuickExport" size="large" itemSize="large"
label="Quick Export" imageMso="PageMenu" >
</menu>
The use of imageMso tells Office to use an built in Office image
- Inside the menu element, add the two button controls to perform the export as XPS or PDF
<button id="btnRibbonXPS" label="XPS" getEnabled="GetEnable"
getImage="GetButtonImage" />
<button id="btnRibbonPDF" label="PDF" getEnabled="GetEnable"
getImage="GetButtonImage" />
- Update the code behind to update the Ribbon buttons as well as the Backstage buttons
- Open Ribbon.vb(in case of VB) & Ribbon.cs(in case of C#) by double clicking it in the Solution Explorer
- Locate the GetButtonImage method and add cases for the ribbon buttons
case "btnRibbonXPS":
case "btnRibbonPDF":
case "btnBackStageXPS":
return Properties.Resources.XPS;
case "btnRibbonXPS":
case "btnRibbonPDF":
case "btnBackStagePDF":
return Properties.Resources.PDF;
Case "btnRibbonXPS", "btnBackStageXPS"
Case "btnRibbonPDF", "btnBackStagePDF"
Return My.Resources.XPS
Case "btnRibbonXPS", "btnBackStageXPS"
Case "btnRibbonPDF", "btnBackStagePDF"
Return My.Resources.PDF
- Locate the GetEnable method and add cases for the ribbon buttons
case "btnRibbonXPS":
case "btnRibbonPDF":
case "btnBackStageXPS":
case "txtXPSPath":
return m_properties.XpsEnabled;
case "btnRibbonXPS":
case "btnRibbonPDF":
case "btnBackStagePDF":
case "txtPDFPath":
return m_properties.PdfEnabled;
Case "btnRibbonXPS", "btnBackStageXPS", "txtXPSPath"
Case "btnRibbonPDF", "btnBackStagePDF", "txtPDFPath"
Return m_properties.XpsEnabled
Case "btnRibbonXPS", "btnBackStageXPS", "txtXPSPath"
Case "btnRibbonPDF", "btnBackStagePDF", "txtPDFPath"
Return m_properties.PdfEnabled
- Locate the EnableChecked method and add InvalidateControl calls for the ribbon buttons
if (control.Id == "chkEnableXPS")
{ m_properties.XpsEnabled = value;
ribbon.InvalidateControl("btnRibbonXPS");
ribbon.InvalidateControl("btnRibbonPDF");
ribbon.InvalidateControl("btnBackStageXPS"); ribbon.InvalidateControl("txtXPSPath");}
else if (control.Id == "chkEnablePDF")
{ m_properties.PdfEnabled = value;
ribbon.InvalidateControl("btnRibbonXPS");
ribbon.InvalidateControl("btnRibbonPDF");
ribbon.InvalidateControl("btnBackStagePDF"); ribbon.InvalidateControl("txtPDFPath");}
If control.Id = "chkEnableXPS" Then
m_properties.XpsEnabled = value
ribbon.InvalidateControl("btnRibbonXPS")
ribbon.InvalidateControl("btnRibbonPDF")
ribbon.InvalidateControl("btnBackStageXPS")ribbon.InvalidateControl("txtXPSPath")ElseIf control.Id = "chkEnablePDF" Then
m_properties.PdfEnabled = value
ribbon.InvalidateControl("btnRibbonXPS")
ribbon.InvalidateControl("btnRibbonPDF")
ribbon.InvalidateControl("btnBackStagePDF")ribbon.InvalidateControl("txtPDFPath")End If
- Create the method that will perform the export when the buttons are clicked
- Open Ribbon.vb(in case of VB) & Ribbon.cs(in case of C#) by double clicking it in the Solution Explorer
- Add the following using statements to the file
using Microsoft.Office.Interop.Word;
Imports Microsoft.Office.Interop.Word
- Create a new method named ExportDocument that will use the ExportAsFixedFormat document method to export the current document
public void ExportDocument(Office.IRibbonControl control)
{
switch (control.Id)
{
case "btnRibbonXPS":
case "btnBackStageXPS":
Globals.ThisAddIn.Application.ActiveDocument.
ExportAsFixedFormat(
m_properties.XpsExportPath,
WdExportFormat.wdExportFormatXPS);
break;
case "btnRibbonPDF":
case "btnBackStagePDF":
Globals.ThisAddIn.Application.ActiveDocument.
ExportAsFixedFormat(
m_properties.PdfExportPath,
WdExportFormat.wdExportFormatPDF);
break;
}
}
Public Sub ExportDocument(ByVal control As Office.IRibbonControl)
Select Case control.Id
Case "btnRibbonXPS", "btnBackStageXPS"
Globals.ThisAddIn.Application.ActiveDocument.ExportAsFixedFormat(m_properties.XpsExportPath, WdExportFormat.wdExportFormatXPS)
Case "btnRibbonPDF", "btnBackStagePDF"
Globals.ThisAddIn.Application.ActiveDocument.ExportAsFixedFormat(m_properties.PdfExportPath, WdExportFormat.wdExportFormatPDF)
End Select
End Sub
- Add the onAction attributes to all of the buttons in the Ribbon and Backstage
- Open Ribbon.xml by double clicking it in the Solution Explorer
- Add a onAction attribute to every button element
<button id="btnRibbonXPS"
onAction="ExportDocument"
... />
You should find 4 button controls
Exercise 1 Verification
In order to verify that you have correctly performed all steps in the above exercise, proceed as follows:
Test the Add-in
Test your add-in to confirm that the export ribbon and backstage buttons work as expected.
- Run the add-in and verify the enable checkboxes work
- In the Debug menu, click Start Without Debugging
- Once Word 2010 loads, type a phrase in the document and click the Backstage button (labeled as File)
- In Backstage switch to the Export tab
- Check the Allow XPS Export check box
- Enter an Export Path of %Office2010DeveloperTrainingKitPath%\Labs\OfficeUI\Source\[language]\Starter\Export.xps
.png)
- Click the To XPS button and using Windows Explorer navigate to the folder and open the Export.xps document. Close the .xps file.
- Verify the Home ribbon contains a new Quick Format button
- Switch to the Home ribbon tab and type an additional phrase into the document
- Click the Quick Export button and click the XPS button. Navigate to the .xps document and view it again to see your changes.
.png)
Figure 5Quick Export Ribbon Button
- When you are done cleanup and remove the add-in
- Close Word 2010
- In the Solution Explorer, right click Word2010AddIn and click Clean