Volume 3: Programming with the Visio Object Model disclaimer



Download 0.78 Mb.
Page36/36
Date29.01.2017
Size0.78 Mb.
#11974
1   ...   28   29   30   31   32   33   34   35   36

61.Getting started


As shown in Figure 1, any UI modifications made using the UIObject APIs or the CommandBar APIs are aggregated within a new tab on the Visio 2010 ribbon named “Add-Ins”. Because both the UIObject and the CommandBars support the idea of Menus and Toolbars you see separate ribbon groups, one for each menu and toolbar created thru these legacy APIs. This is good news for both users and solution developers as existing add-ins are still compatible and accessible with the new Ribbon interface.

The sample projects for this section are written in C# (Visual Studio 2008) for Visio 2007 using the Visual Studio Tools for Office (VSTO) 3.0 framework and runtime. The following software is required for this scenario:



  • Visual Studio 2008

  • VSTO 3.0 (installed with Visual Studio 2008)

  • Visio 2007 with .NET Programmability Support installed (PIA)

VSTO is the preferred and supported framework for building add-ins for all Office applications. Prior to the release of VSTO, Office add-ins were developed as COM components implementing the IDExtensibility2 interface, commonly referred to as Shared Add-ins from the managed code world. Either framework supports Ribbon extensibility by simply implementing the IRibbonExtensibility interface. It is up to the host application to call the implemented interface in order to retrieve Ribbon customizations.

62.Updating References


For the purpose of this article it is not necessary to reference the Visio 2010 type library. Existing Visio 2007 add-ins can continue to reference the Visio 2007 type library in order to support both Visio 2007 and Visio 2010 as well as provide a rich Ribbon based interface when running in Visio 2010.

63.Preparing the add-in for Ribbon support


In order for your add-in to support the new Ribbon interface when loaded by Visio 2010, your add-in must be updated to support the IRibbonExtensibility interface. This interface is defined in the Office PIA. Add this reference to your project if it does not already exist.

From the Add Reference menu select Office, 12.0.0.0 from the .NET tab. This is the Primary Interop Assembly for Office Core which provides the interfaces for IRibbonExtensibility as well as the APIs and interfaces for CommandBars, so if you are using CommandBars you probably already have this reference in your project.





Figure 2 - Adding a reference to Office.dll

After adding the reference you will need to implement the IRibbonExtensibility interface in order to provide the host application with an instance of an object that provides your ribbon implementation.

For a VSTO based add-in start by creating a separate class that will implement the IRibbonExtensibility interface. I prefer to name this class Ribbon (in a separate file, Ribbon.cs). Here is a sample definition of this class:

using Office = Microsoft.Office.Core;

[ComVisible(true)]

public class Ribbon : Office.IRibbonExtensibility

{…}

A single method needs to be implemented from the IRibbonExtensibility interface:



#region IRibbonExtensibility Members

public string GetCustomUI(string RibbonID)

{

return GetResourceText("DataLinkedOrgChart.Ribbon.xml");



}

#endregion

The GetCustomUI method is used to return the XML that defines your Ribbon to the host application. This xml is compiled into the add-in as a resource which is retrieved by the GetResourceText method. Using this XML the host application generates the Ribbon and displays it to the user. We will generate the XML for the ribbon later in this article.

Application level Ribbon

In order to create a single Application-Level Ribbon you need to override the CreateRibbonExtensibility method. This method is called by the VSTO runtime to retrieve an instance of your class that implements the IRibbonExtensibility interface, passing it to the host application which will then make the call to the GetRibbonUI method.

protected override Microsoft.Office.Core.IRibbonExtensibility CreateRibbonExtensibilityObject()

{

// create a new instance of our Ribbon



this.ribbon = new Ribbon();

// return the ribbon to the VSTO runtime caller

return this.ribbon;

}

As you can see this method simply creates a new instance of your Ribbon class and returns it to the caller.


Document level Ribbon

To implement a Document-Level Ribbon you do not override the CreateRibbonExtensibility method as described above as you will need to create an instance of your Ribbon for each document on an as needed basis.

RegisterRibbonX and UnRegisterRibbonX are two new methods on the Visio.Application class that allow you to attach and detach a Ribbon to a specific open document.

To create a Ribbon for a specific document you would create a new instance of the Ribbon class and pass that along with the Visio.Documentinstance that you want to attach it to as parameters to the RegisterRibbonXmethod.

// add our UI for this document

Globals.ThisAddIn.Application.RegisterRibbonX(

ribbon,

visioDocument,

Visio.VisRibbonXModes.visRXModeDrawing,

"My Ribbon");

It is important to perform cleanup operations as documents close so you should manage each instance of the Ribbon class that you create and as documents are closed you should call the UnRegisterRibbonX method.

Globals.ThisAddIn.Application.UnregisterRibbonX( this.ribbon, this.visioDocument);


Note for Shared add-ins

If you are using the Shared add-in framework you simply implement the IRibbonExtensibility interface directly on the Connect class and provide the implementation for the GetCustomUI method as described above.

public class Connect : Object, Extensibility.IDTExtensibility2, Microsoft.Office.Core.IRibbonExtensibility


64.Creating the Ribbon


If you have created add-ins for Word or Excel you know that the add-in project template in Visual studio provides a very easy mechanism for creating a Ribbon using the Ribbon Designer. From the Add New Item dialog select the Ribbon Designer



Figure 3 - Adding the Ribbon (Visual Designer) to your project
And you will be able to visual design the layout of your ribbon using ribbon controls just as you would with a WinForm.



Figure 4 - Using the Visual Designer for the Ribbon
The problem is that the project template that is used to create add-ins for Visio 2007 knows that Visio does not support the Ribbon interface so this option is not available to you. You can skip the designer and just write the XML from scratch but it is much easier to work with the designer and then have the designer generate the XML when you have your ribbon laid out. To do this, create a new add-in project for Word 2007. Then from the Add New Item dialog choose the Ribbon Designer. Once the new Ribbon Designer is added to this temporary project you can copy the necessary files to your Visio add-in project and discard this temporary Word add-in project.

To copy the ribbon designer files to your Visio add-in project:



  1. Close and save changes to the temporary Word add-in project/solution.

  2. From your Visio add-in project, choose the Add Existing Items menu and navigate to the temporary Word add-in project folder, selecting the following files:

    1. RibbonDesign.cs

    2. RibbonDesign.designer.cs

    3. RibbonDesign.resx

This will copy the ribbon designer files to your Visio add-in project. Once these files are added to your Visio add-in project you can continue to the next step which would be to actually design the ribbon.



  1. Double-click the RibbonDesigner.cs item in the Project Explorer window. This will open the Visual Designer for the ribbon as shown in Figure 4

Once you are happy with the design and layout of your ribbon it is time to generate the XML that will be embedded as a resource in your project. This is the XML that is passed to the host application from the GetCustomUI method described above.

To generate the XML from the Visual Designer:



  1. Open the Visual Designer as shown in Figure 4 above.

  2. Right-click on the ribbon and from the context menu choose „Export Ribbon to XML‟



Figure 5 - Export Ribbon to XML
This will add a new file to your Visio add-in project named „Ribbon.xml‟. If you open this XML file in the editor you will see that it is a very simple schema.

Figure 6 - View of XML generated by the Visual Designer
After the Ribbon.xml file is generated and added to the project, verify that the Build Action for this file is set to Embedded Resource or the call to GetCustomUI will fail to return the XML.



Figure 7 - Build Action set to Embedded Resource


Tip:

If you want to duplicate built in buttons on your Ribbon, such as the Refresh All button, you can use the idMso attribute in your XML.

Make sure to set the Build Actions for the Ribbon Designer files to None. It you compile these files into your project they could conflict with the Ribbon class. Make sure to set it for all three designer files:





Tip:

These files can be removed from your project once you are finished with the design of your Ribbon or they can be left for future design changes.

65.Callbacks


At this point you could actually compile and run your add-in and you should see your ribbon however the ribbon controls will not do anything (unless linked to build in commands).

In order for the ribbon controls to perform custom actions you need to implement callback methods on the Ribbon class that can be called by the host application or the ribbon controls. These callbacks are assigned to ribbon controls using attributes in the ribbon xml.





Figure 8 - Sample XML showing callback attributes
The onAction callback should be defined as follows:

public void OnAction(

Office.IRibbonControl control)

{

switch (control.Id)



{

case "buttonCreate":

{

// do any work necessary for the selected control



break;

}

// define a case for each button that needs a handler



}

}

66.Manage Ribbon control state


In addition to creating a Ribbon with controls that perform actions within your add-in, you will also want to manage the state of the controls on your Ribbon so that users have access to each control when appropriate.

When the host application receives the XML from the GetCustomUI method it generates a new Ribbon tab. We can get a handle to this Ribbon when the host application creates it if we provide a callback to the onLoad attribute of the Ribbon XML.


Callback defined in XML


Figure 9 - Sample XML showing definition for onLoad callback

Callback defined in the Ribbon class

public void Ribbon_Load(Office.IRibbonUI ribbonUI)

{

// hold on to the instance of our ribbon



this.ribbon = ribbonUI;

if (Globals.ThisAddIn.Application != null)

{

VisioEvents_Connect();



}

}

Not only do we get the instance of the Ribbon that was created by the host application but in this callback we will connect to a few Visio events so that we can determine when Ribbon control states need to be updated.



private void VisioEvents_Connect()

{

if (Globals.ThisAddIn.Application != null)



{

Globals.ThisAddIn.Application.AppObjActivated += new Microsoft.Office.Interop.Visio.EApplication_AppObjActivatedEventHandler(Application_AppObjActivated);

Globals.ThisAddIn.Application.AfterModal += new Microsoft.Office.Interop.Visio.EApplication_AfterModalEventHandler(Application_AfterModal);

Globals.ThisAddIn.Application.WindowOpened += new Microsoft.Office.Interop.Visio.EApplication_WindowOpenedEventHandler(Application_WindowOpened);

Globals.ThisAddIn.Application.WindowActivated += new Microsoft.Office.Interop.Visio.EApplication_WindowActivatedEventHandler(Application_WindowActivated);

Globals.ThisAddIn.Application.WindowChanged += new Microsoft.Office.Interop.Visio.EApplication_WindowChangedEventHandler(Application_WindowChanged);

Globals.ThisAddIn.Application.BeforeWindowClosed += new Microsoft.Office.Interop.Visio.EApplication_BeforeWindowClosedEventHandler(Application_BeforeWindowClosed);

}

}



Within each Visio event handler we can call the Invalidate method on our Ribbon to notify the Ribbon that it needs to get the state for each control.

void Application_WindowChanged(Microsoft.Office.Interop.Visio.Window Window)

{

this.ribbon.Invalidate();



}

However, for each control to update its new state each control must have a callback defined that returns true for Enabled or false for Disabled.


Callback defined in XML



Figure 10 - Sample XML showing getEnabled callback

getEnabled defined in Ribbon class

public bool GetEnabled(

Microsoft.Office.Core.IRibbonControl control)

{

bool retVal = false; // default to false until we prove this enabled



switch (control.Id)

{

case "buttonCreate":



{

// create is always available

retVal = true;

break;


}

case "buttonGenerate":

{

// only enabled if the active document is our document



retVal = this.IsOurDocument(Globals.ThisAddIn.Application.ActiveDocument);

break;


}

// additional cases for all controls that have state

}

return retVal;



}

After Invalidate is called, each Ribbon control that has its getEnabled attribute set will execute its callback and set its state based on the return value of the callback. At this point you can test the ActiveDocument or the Selection to see if the control should be enabled or disabled.


Additional callbacks
getImage

If you do not find an image from Office (ex. imageMso="Refresh") to use on your control you can provide your own. The getImage attribute can be set on each control so that it will retrieve its own image from the specified callback in your add-in. As you can see in the sample below you can easily add your image to your add-in project as a resource and then return it to the caller based on the control.Id property.

public System.Drawing.Bitmap GetImage(

Microsoft.Office.Core.IRibbonControl control)

{

switch (control.Id)



{

case "buttonApplyDataGraphics":

{

return Properties.Resources.OperationsManagerProductIcon_32;



}

}

// we should not get here for these buttons



return null;

}

67.CommandBars and Ribbon


After implementing the Ribbon as described above there is only one more step you should take, add a conditional statement around your existing UI code so that you do not build your legacy UI using CommandBars if the user is running Visio 2010. To do this add this simple check when initializing your add-in:

if (this.Application.TypelibMinorVersion <= 12)

{

// code to provide CommandBars



}

else


{

// do nothing, VSTO will call into the defined

// IRibbonExtensibility interface

}

With this check in place your add-in will now run in both Visio 2007 and Visio 2010, providing the user with the best UI experience available to each.


68.Sample Code


There are four Visual Studio projects included with this training which demonstrate the above concepts.
Try it! Creating Office Fluent UI for Visio Addins

  1. Using Visual Studio 2008 open the project in \Samples\Office Fluent UI\ Basic Ribbon

    1. Review the example

  2. Using Visual Studio 2008 open the project in \Samples\Office Fluent UI\ Enhanced Ribbon

    1. Review the example

  3. Using Visual Studio 2008 open the project in \Samples\Office Fluent UI\ Doc Level Ribbon

    1. Review the example

  4. Using Visual Studio 2008 open the project in \Samples\Office Fluent UI\ Command Bars Only

    1. Review the example



Microsoft Visio 2010 Developer Training © 2010 Microsoft Corporation. All rights reserved.

Volume 3: Programming with the Visio Object Model



footer-visio.jpg



Download 0.78 Mb.

Share with your friends:
1   ...   28   29   30   31   32   33   34   35   36




The database is protected by copyright ©ininet.org 2024
send message

    Main page