Customizing the Ribbon in Visio 2010 by Using a Visual Studio 2010 Add-In
Summary: Learn how to use Microsoft Visual Studio 2010 to create a Microsoft Visio 2010 add-in that programmatically customizes the ribbon component of the Microsoft Office Fluent user interface (UI).
Applies to: Office 2010 | SharePoint Server 2010 | Visio 2010 | Visio Premium 2010 | Visual Studio
In this article
Introduction
Creating a Visio 2010 Add-in Project in Visual Studio 2010
Adding a Ribbon Extensibility Item to the Project
Creating an XML Resource
Adding a Custom UI Class File to the Project
Enabling the Ribbon (XML) Item
Building the Project and Publishing the Add-in to Visio
Running the Add-in in Visio and Testing the New Ribbon UI
Conclusion
Additional Resources
Published: February 2011
Provided by: Saul Candib, Microsoft Corporation
Contents
Introduction
Creating a Visio 2010 Add-in Project in Visual Studio 2010
Adding a Ribbon Extensibility Item to the Project
Creating an XML Resource
Adding a Custom UI Class File to the Project
Enabling the Ribbon (XML) Item
Building the Project and Publishing the Add-in to Visio
Running the Add-in in Visio and Testing the New Ribbon UI
Conclusion
Additional Resources
Introduction
In the article Customizing the 2007 Office Fluent Ribbon for Developers (Part 1 of 3), the authors introduced the ribbon component of the then brand-new Microsoft Office Fluent user interface (UI), as follows:
"Developers have taken advantage of the tools and programming structures in earlier versions of Office to extend the Fluent UI in creative ways. For example, the command bars object model enabled developers to build rich solutions in their custom Office applications. Continuing in that tradition, UI extensibility introduces an innovative model that you can use to enhance the user experience. You use extensible markup language (XML) and one of several conventional programming languages to manipulate the components that make up the Fluent UI. Because XML is plain text, you can create customization files in any text editor, which simplifies work with the Fluent UI. You can also reuse custom Fluent UI files with a minimum of adjustments because each application uses the same programming model."
In Microsoft Office 2007, applications that used the Office Fluent UI included Word, Excel, PowerPoint, and Outlook. For 2010, Visio also has adopted the Office Fluent UI and the ribbon. In this article, you will learn how to use a Microsoft Visual Studio 2010 managed-code add-in project (that contains an XML resource) and some additional sample code from the Visio 2010 SDK Code Samples Library to customize the ribbon in Visio 2010.
Note
This sample code is included in the article, so you do not need to download it separately from the Visio 2010 SDK.
When the project is built and published to Microsoft Visio 2010, running the add-in makes the following changes to the Visio UI:
It adds a new tab to the ribbon, containing a custom button that, when clicked, performs a custom action.
It changes the function of the existing built-in Bold and Copy ribbon commands.
It adds a new command to the shortcut menu of all shapes.
It adds a new tab to Microsoft Office Backstage view, which opens when you click the File tab. The new tab contains a custom button and a custom command.
In general, the following steps are required to customize the UI. Each step is explained in more detail in the corresponding sections of the article:
Create a Visio 2010 add-in project in Visual Studio 2010.
Add a ribbon extensibility item to the project.
Create an XML resource.
Add a custom UI file to the project.
Enable the ribbon extensibility item.
Build the project and publish the add-in to Visio.
Run the add-in in Visio and test the new ribbon UI.
Creating a Visio 2010 Add-in Project in Visual Studio 2010
Visual Studio 2010 provides project templates that create basic add-ins for most Office 2010 applications, in both of the most common Microsoft managed-code programming languages: Visual Basic and Visual C#.
To create a Visio 2010 add-in project in Visual Studio 2010
On the File tab in Visual Studio 2010, point to New, and then click Project.
In the Installed Templates list, double-click the managed language of your choice, either Visual Basic or Visual C#.
Expand the Office node, and then click 2010.
Click Visio 2010 Add-in.
Name the project RibbonCustomization, specify the location where you want to save the project, and then click OK.
Adding a Ribbon Extensibility Item to the Project
After creating a basic add-in project, you must make various modifications and additions to the project to make it functional.
To add a ribbon extensibility item to the project
In Solution Explorer, right-click the project name (RibbonCustomization), point to Add, and then click New Item.
Select Ribbon (XML), and then click Add.
Visual Studio adds two files to the project:
A class file, named Ribbon1.cs or Ribbon1.vb.
An XML file, named Ribbon1.xml.
The Ribbon.xml file contains markup that specifies a simple customized UI. The new Ribbon1.cs or Ribbon1.vb file contains a set of instructions for enabling the Ribbon (XML) item and the Ribbon1 class declaration.
Creating an XML Resource
It is easiest to use the new XML file if you treat it as a resource within the project's resource file. The resulting resource file is accessed, and the XML markup it contains is read, by the GetResourceText method of the Ribbon1 class.
To create an XML resource
In Solution Explorer, right-click the project name (RibbonCustomization), and then click Properties.
Click the Resources tab.
From Solution Explorer, drag Ribbon1.xml onto the Resources design surface.
This action creates a new file-based resource that contains the XML content. From now on, Visual Studio 2010 automatically stores Ribbon1.xml as an application resource, and you can retrieve this content by using Visual Basic or Visual C# language features.
Close the Properties window. When prompted, click Yes to save the resources.
Adding a Custom UI Class File to the Project
In the Microsoft Visio Code Samples Library, the Visio 2010 SDK provides a sample class, named CustomUI (shown in the following code example), which loads the custom UI from the Ribbon1.xml file and, optionally, associates that UI with a particular Visio document. You will add this class file to the RibbonCustomization project.
To add a custom UI class file to the project
In Solution Explorer, right-click the project name, point to Add, and then click Class.
In the Add New Item dialog box, name the class CustomUI, and then click Add.
In Solution Explorer, double-click the CustomUI file.
Paste the following code into the file in the RibbonCustomization namespace, replacing the existing blank CustomUI class declaration.
/// <summary>This class demonstrates how to import custom UI and display it /// only for a specific Visio document. The custom UI is shown when the /// document is active, and is not shown in other contexts, such as when /// other documents are active or in other views such as Print Preview. /// </summary> public class CustomUI { /// <summary>A reference to the sample class that creates and manages /// the custom UI.</summary> private Ribbon1 customRibbon; /// <summary>This constructor is intentionally left blank.</summary> public CustomUI() { // No initialization is required. } /// <summary>This method loads custom UI from an XML file and /// associates it with the document object passed in.</summary> /// <param name="targetDocument">An open document in a running /// Visio application</param> public void DemoCustomUIStart( Microsoft.Office.Interop.Visio.Document targetDocument) { Microsoft.Office.Interop.Visio.Application visioApplication = targetDocument.Application; customRibbon = new Ribbon1(); // Passing in null rather than targetDocument would make the custom // UI available for all documents. visioApplication.RegisterRibbonX( customRibbon, targetDocument, Microsoft.Office.Interop.Visio.VisRibbonXModes.visRXModeDrawing, "RegisterRibbonX example"); } /// <summary>This method removes custom UI from a document.</summary> /// <param name="targetDocument">An open document in a running /// Visio application that has custom UI associated with it</param> public void DemoCustomUIStop( Microsoft.Office.Interop.Visio.Document targetDocument) { Microsoft.Office.Interop.Visio.Application visioApplication = targetDocument.Application; visioApplication.UnregisterRibbonX(customRibbon, targetDocument); } }
'// <summary>This class demonstrates how to import custom UI and display it '// only for a specific Visio document. The custom UI is shown when the '// document is active, and is not shown in other contexts, such as when '// other documents are active or in other views such as Print Preview. '// </summary> Public Class CustomUI '// <summary>A reference to the sample class that creates and manages '// the custom UI.</summary> Private customRibbon As Ribbon '// <summary>This constructor is intentionally left blank.</summary> Public Sub New() ' No initialization is required. End Sub '// <summary>This method loads custom UI from an XML file and '// associates it with the document object passed in.</summary> '// <param name="targetDocument">An open document in a running '// Visio application</param> Public Sub DemoCustomUIStart( _ ByVal targetDocument As Global.Microsoft.Office.Interop.Visio.Document) Dim visioApplication As Global.Microsoft.Office.Interop.Visio.Application = _ targetDocument.Application customRibbon = New Ribbon() ' Passing in null rather than targetDocument would make the custom ' UI available for all documents. visioApplication.RegisterRibbonX(customRibbon, _ targetDocument, _ Global.Microsoft.Office.Interop.Visio.VisRibbonXModes.visRXModeDrawing, _ "RegisterRibbonX example") End Sub '// <summary>This method removes custom UI from a document.</summary> '// <param name="targetDocument">An open document in a running '// Visio application that has custom UI associated with it</param> Public Sub DemoCustomUIStop( _ ByVal targetDocument As Global.Microsoft.Office.Interop.Visio.Document) Dim visioApplication As Global.Microsoft.Office.Interop.Visio.Application = _ targetDocument.Application visioApplication.UnregisterRibbonX(customRibbon, _ targetDocument) End Sub
Save the project.
Understanding the Purpose of the CustomUI Class
The CustomUI class imports the custom UI that is defined in the Ribbon1.xml file and the Ribbon1 class into the specified Visio document. It includes two methods:
DemoCustomUIStart—Loads the custom UI defined in the Ribbon1.xml file and the Ribbon1 class into the Visio target document that is passed in, assuming that same document is, in turn, passed to the built-in Application.RegisterRibbonX method of the Visio object model. If, instead of the target document, you pass null for the second parameter of the RegisterRibbonX method, the custom UI is loaded into all Visio documents.
DemoCustomUIStop—Removes the custom UI from the target document by calling the built-in VisioApplication.UnregisterRibbonX method.
Enabling the Ribbon (XML) Item
To enable the Ribbon (XML) item that you previously added to the project, you need to complete the following three steps (which are also listed in the commented-out TODO section of the Ribbon1.cs or Ribbon1.vb file):
Add the CreateRibbonExtensibilityObject() method to the ThisAddIn class.
Create callback methods in the Ribbon Callbacks region of the Ribbon1 class to handle user actions.
Assign attributes to the control tags in the Ribbon1.xml file to identify the appropriate callback methods in your code.
Adding the CreateRibbonExtensibilityObject Method to the ThisAddIn Class
The first step just requires some copying and pasting. It defines the CreateRibbonExtensibilityObject method in the ThisAddIn class. This method initializes a new Ribbon1 class instance and returns that instance to the ThisAddIn class.
To add the CreateRibbonExtensibilityObject method to the ThisAddIn class
In Solution Explorer, double-click the Ribbon1.cs or Ribbon1.vb file to open it.
Copy the following code from the commented-out TODO section of the Ribbon1 file to the ThisAddIn class, below the ThisAddIn_Shutdown method.
protected override Microsoft.Office.Core.IRibbonExtensibility CreateRibbonExtensibilityObject() { return new Ribbon1(); }
Protected Overrides Function CreateRibbonExtensibilityObject() As Microsoft.Office.Core.IRibbonExtensibility Return New Ribbon1() End Function
Save the project.
Creating Callback Methods to Handle User Actions in the Ribbon Callbacks Region of the Ribbon1 Class
You can respond to user actions, such as clicking a button on the ribbon, by creating callback methods. Callback methods resemble events in Windows Forms controls, but they are identified by an attribute in the XML of the UI element. You write methods in the ribbon class, and a control calls the method that has the same name as the attribute value.
Two steps are required to create a callback method:
Assign attributes to controls in the Ribbon1.xml file that identify callback methods in your code. You will do that in the next section.
Define callback methods in the Ribbon1 class.
The Visio 2010 SDK Code Samples Library provides sample code especially intended to create these callbacks in a Visio add-in project. In the code that follows, for example, the OnAction callback method specifies the action that takes place when a user clicks a control in the custom user interface that has the OnAction attribute defined in the Ribbon1.xml file, thus calling the method. In this case, the specified action is to display a message box.
To create callback methods to handle user actions in the Ribbon Callbacks region of the Ribbon1 class
Click the Ribbon1.cs or Ribbon1.vb class tab.
Expand the Ribbon Callbacks region.
Paste the following code into this region.
/// <summary>This method is a callback specified in the onLoad attribute /// of the customUI element in the custom UI XML file. It is called by /// Visio when the custom UI is first loaded.</summary> /// <param name="ribbonUI">A reference to the object representing the /// custom UI loaded by Visio</param> public void OnRibbonLoad(Microsoft.Office.Core.IRibbonUI ribbonUI) { // Do something with the newly constructed ribbon, such as capture // a local reference to it for later use. this.ribbon = ribbonUI; MessageBox.Show("Capturing local reference to new ribbon."); } /// <summary>This method is a callback specified in the custom UI XML /// file. It is called by Visio when the associated button defined /// in the XML is clicked.</summary> /// <param name="control">The Ribbon UI control that was activated</param> public void OnAction(Microsoft.Office.Core.IRibbonControl control) { System.Windows.Forms.MessageBox.Show("OnAction"); } /// <summary>This method is a callback specified in the custom UI XML /// file. It is called by Visio when the associated repurposed ribbon /// control is clicked.</summary> /// <param name="control">The Ribbon UI control that was clicked</param> /// <param name="cancelDefault">If true, call the built-in command after /// the custom code is complete</param> public void CommandOnAction(Microsoft.Office.Core.IRibbonControl control, bool cancelDefault) { // Take a custom action when the user clicks Copy. System.Windows.Forms.MessageBox.Show("CommandOnAction called: User clicked Copy."); cancelDefault = false; } /// <summary>This is a helper method that reads the content of a /// text file resource embedded in the project.</summary> /// <param name="resourceName">The name of the resource</param> private static string getResourceText(string resourceName) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); Stream resourceStream = executingAssembly.GetManifestResourceStream( resourceName); if (resourceStream != null) { StreamReader resourceReader = new StreamReader(resourceStream); return resourceReader.ReadToEnd(); } else { return null; } }
'// <summary>This method is a callback specified in the onLoad attribute '// of the customUI element in the custom UI XML file. It is called by '// Visio when the custom UI is first loaded.</summary> '// <param name="ribbonUI">A reference to the object representing the '// custom UI loaded by Visio</param> Public Sub OnRibbonLoad(ByVal ribbonUI As Global.Microsoft.Office.Core.IRibbonUI) ' Do something with the newly constructed Ribbon, such as capture ' a local reference to it for later use. this.ribbon = ribbonUI System.Windows.Forms.MessageBox.Show("Capturing local reference to new ribbon.") End Sub '// <summary>This method is a callback specified in the custom UI XML '// file. It is called by Visio when the associated button defined '// in the XML is clicked.</summary> '// <param name="control">The Ribbon UI control that was activated</param> Public Sub OnAction(ByVal control As Global.Microsoft.Office.Core.IRibbonControl) System.Windows.Forms.MessageBox.Show("OnAction") End Sub '// <summary>This method is a callback specified in the custom UI XML '// file. It is called by Visio when the associated repurposed ribbon '// control is used.</summary> '// <param name="control">The Ribbon UI control that was clicked</param> '// <param name="cancelDefault">If true, call the built-in command after '// the custom code is complete</param> Public Sub CommandOnAction( _ ByVal control As Global.Microsoft.Office.Core.IRibbonControl, _ ByVal cancelDefault As Boolean) ' Take a custom action when the user clicks Copy. System.Windows.Forms.MessageBox.Show("CommandOnAction called: User clicked Copy.") cancelDefault = False End Sub '// <summary>This method is a helper that reads the content of a '// text file resource embedded in the project.</summary> '// <param name="resourceName">The name of the resource</param> Private Shared Function getResourceText(ByVal resourceName As String) As String Dim executingAssembly As Assembly = Assembly.GetExecutingAssembly() Dim resourceStream As Stream = executingAssembly.GetManifestResourceStream(resourceName) If resourceStream IsNot Nothing Then Dim resourceReader As New StreamReader(resourceStream) Return resourceReader.ReadToEnd() Else Return Nothing End If End Function
Add the following directive to the top of the Ribbon1.cs or Ribbon1.vb file.
using System.Windows.Forms;
Imports System.Windows.Forms
This directive is necessary because some of the callback methods call the MessageBox.Show method.
Save the project.
Assigning Attributes to the Control Tags in the Ribbon1.xml File
The Ribbon1.xml file defines the custom user interface, including a custom ribbon tab, a custom ribbon group, a custom ribbon button control, a custom shortcut menu control, and a custom control on the File menu. It also specifies callback methods that are called when a user accesses controls in the custom user interface. In addition, the custom UI modifies the action of two existing controls in the built-in user interface: the Bold button and the Copy button. The Visio 2010 SDK provides sample XML markup that creates these controls, as shown in the following procedure.
To assign attributes to the control tags in the Ribbon1.xml file
In Solution Explorer, double-click the Ribbon1.xml file to open it.
Select the existing XML markup in the file, and then paste the following XML markup into the file, overwriting the existing markup.
<?xml version="1.0" encoding="UTF-8"?> <!--RibbonXML.xml <copyright>Copyright (c) Microsoft Corporation. All rights reserved. </copyright> <summary>This XML file demonstrates how to define custom UI and its associated callbacks.</summary> --> <customUI onLoad="OnRibbonLoad" xmlns="https://schemas.microsoft.com/office/2009/07/customui"> <!--This section repurposes built-in commands.--> <commands> <!--Disables the Bold command--> <command idMso="Bold" enabled="false"/> <!--Redirects the built-in Copy ribbon button to a custom callback--> <command idMso="Copy" onAction="CommandOnAction"/> </commands> <!--This section defines custom ribbon controls.--> <ribbon> <tabs> <tab id="tab1" label="Custom Tab"> <group id="group1" label="Custom Group"> <button id="button1" size="large" label="Custom Button" imageMso="AddOnsMenu" onAction="OnAction"/> </group> </tab> </tabs> </ribbon> <!--This section defines custom Backstage controls.--> <backstage> <tab id="tab2" label="Custom Tab"> <firstColumn> <group id="group2" label="Custom Group"> <primaryItem> <button id="button2" label="Custom Button" imageMso="AddOnsMenu" onAction="OnAction"/> </primaryItem> </group> </firstColumn> </tab> <button id="button3" label="Custom Fast Command" imageMso="AddOnsMenu" onAction="OnAction"/> </backstage> <!--This section defines custom context menu controls.--> <contextMenus> <contextMenu idMso="ContextMenuShape"> <button id="button4" label="Custom Button" onAction="OnAction"/> </contextMenu> </contextMenus> </customUI>
Save the project.
Building the Project and Publishing the Add-in to Visio
Now that all the files in the project are complete, the next step is to build the add-in project and publish the add-in to Visio. Publishing the add-in makes it readily available in Visio without a lot of extra work.
To build the project and publish the add-in to Visio
On the Build menu in Visual Studio 2010, click Build Solution.
In Solution Explorer, right-click the project name (RibbonCustomization) and then click Publish.
Click Next to accept the default publishing location.
Click Finish.
Save the project.
Running the Add-in in Visio and Testing the New Ribbon UI
You are now ready to run the add-in in Visio and test the new ribbon UI you created. The custom UI should look like Figures 1 and 2.
Figure 1. Custom tab on the ribbon
Figure 2. Custom tab in Backstage view
To run the add-in in Visio and test the new ribbon UI
Open Visio 2010.
When the New section of the File tab opens, Visio displays the message "Capturing local reference to new ribbon", the action you specified in the OnRibbonLoad callback method, in the Ribbon1 class file.
Click OK to close the message box.
In the Choose a Template pane, under Template Categories, click General, select Basic Diagram, and then click Create to create a new basic diagram.
Drag a shape from the Basic Shapes stencil onto the drawing page.
Double-click the shape and type the phrase "This is bold text."
Select the text you typed, and then click the Bold button on the ribbon.
Note that the Bold button is unavailable and that the text remains roman (not bold). This is the result of the markup in the Ribbon1.xml file that disables the built-in Bold command.
Select the shape and click Copy.
Visio displays the message "CommandOnAction called: Copy was clicked." If you subsequently attempt to paste, nothing happens, because you have replaced the built-in action of the Copy ribbon button with the new action you specified in the custom callback.
Click the new ribbon tab labeled Custom Tab, and then click the Custom Button it contains.
Visio displays the message "OnAction," to indicate that the OnAction callback method has been called.
Right-click the shape and, on the shortcut menu, click Custom Button.
Once again, Visio displays the message "OnAction," because the onAction attribute of the ContextMenuShape control is set to OnAction in the Ribbon1.xml file.
Click the File tab, and then click Custom Tab.
Visio displays a custom tab in Backstage view that contains a custom button and a custom command. You can experiment with those controls to verify that they perform the expected actions.
Conclusion
Visio 2010 adopts the ribbon component of the Office Fluent user interface that was introduced in Office 2007. You can create Visio 2010 add-in solutions in Visual Studio 2010 that use XML markup to customize the Visio ribbon by adding custom ribbon tabs and controls, as well as custom buttons and controls elsewhere in the user interface. This article shows how to use managed code from the Visio 2010 SDK Code Samples Library to create these solutions and then run and test them in Visio.
Additional Resources
Visio 2010: Software Development Kit
Overview of Add-ons and COM Add-ins in Visio 2007
Customizing the 2007 Office Fluent Ribbon for Developers (Part 1 of 3)