Using VSTO Document Features in Application-Level Add-Ins

One commonly asked for feature in VSTO is the ability to use Word document and Excel workbook features in Application-level add-in projects. Starting with Visual Studio 2008 SP1, there is now a mechanism to use many of the document-level features in your application-level add-in projects.

Using this new mechanism, you can get a VSTO host item object for a document, worksheet, or workbook from a PIA object like Microsoft.Office.Interop.Word.Document, Microsoft.Office.Interop.Excel.Worksheet, or Microsoft.Office.Interop.Excel.Workbook. Once you have the VSTO host item object, you can then use features like the Controls collection to add host item controls to the document that can be data bound. You can also use features like smart tags at a document or workbook level.

Preparing a pre-Visual Studio 2008 SP1 project

To prepare an add-in project that was created prior to Visual Studio 2008 SP1 to use document level features, you must first add a reference to Microsoft.Office.Tools.Excel.v9.0 if it is an Excel add-in project and Microsoft.Office.Tools.Word.v9.0 if it is a Word add-in project. This reference contains the definitions for document level types for Excel and Word respectively. 

Once you’ve added the correct reference, make sure your ThisAddin.cs file has the following line of code added at the top of the file with the other using statements. For an Excel add-in, this using statement is required:

 using Microsoft.Office.Tools.Excel.Extensions;

For a Word add-in, this using statement is required:

 using Microsoft.Office.Tools.Word.Extensions;

If you create a new add-in project in Visual Studio 2008 SP1, all these things will be added automatically.

Getting a VSTO Host Item Object for a Document, Worksheet, or Workbook

Once you have the project prepared properly, you now can directly obtain a VSTO host item object from the PIA object for a Document, Worksheet, and Workbook using the method GetVstoObject. VSTO uses a new language feature called extension methods to extend the Microsoft.Office.Interop.Excel.Worksheet, Microsoft.Office.Interop.Excel.Workbook, and Microsoft.Office.Interop.Word.Document with a new method called GetVstoObject. GetVstoObject returns the corresponding VSTO host item object: Microsoft.Office.Tools.Excel.Worksheet, Microsoft.Office.Tools.Excel.Workbook, and Microsoft.Office.Tools.Word.Document respectively.

So to get a VSTO host item object for the Microsoft.Office.Tools.Word.Document object returned by the ActiveDocument property of Word’s Application object, you would write code like this in a Word add-in project:

 Microsoft.Office.Tools.Word.Document vstoDocument =  
  Globals.ThisAddIn.Application.ActiveDocument.GetVstoObject();

To get a VSTO host item object for the Microsoft.Office.Tools.Excel.Workbook object returned by the ActiveWorkbook property of Excel’s Application object, you would write code like this in an Excel VSTO add-in project:

 Microsoft.Office.Tools.Excel.Workbook vstoWorkbook = 
  Globals.ThisAddIn.Application.ActiveWorkbook.GetVstoObject();

To get a VSTO host item object for the Microsoft.Office.Tools.Excel.Worksheet object returned by the ActiveSheet property of Excel’s Application object, you would write the code shown below. The code is slightly more complex because ActiveSheet returns an object that must be cast to a Microsoft.Office.Interop.Excel.Worksheet object before calling GetVstoObject.

 Microsoft.Office.Interop.Excel.Worksheet sheet = 
  Globals.ThisAddIn.Application.ActiveSheet as 
  Microsoft.Office.Interop.Excel.Worksheet;

Microsoft.Office.Tools.Excel.Worksheet vstoWorksheet =
  sheet.GetVstoObject();

Getting a VSTO Host Item Control for ListObject and Other Host Item Controls

Visual Studio 2008 SP1 also adds support to get a host item control directly for a Microsoft.Office.Interop.Excel.ListObject object by adding the GetVstoObject method to this type via extension methods. This means you can write code like the following to get a Microsoft.Office.Tools.Excel.ListObject host item control object, assuming that the active worksheet has at least one list object:

 Microsoft.Office.Interop.Excel.Worksheet sheet = 
  Globals.ThisAddIn.Application.ActiveSheet as 
  Microsoft.Office.Interop.Excel.Worksheet;

Microsoft.Office.Tools.Excel.ListObject vstoList =
  sheet.ListObjects[1].GetVstoObject();

To get to the other host item controls object, you can first get a VSTO host item object for a Document or Worksheet and use the Controls collection to dynamically create host item controls, e.g.:

 Microsoft.Office.Tools.Word.Document vstoDocument =
  Globals.ThisAddIn.Application.ActiveDocument.GetVstoObject();

Microsoft.Office.Tools.Word.PlainTextContentControl vstoTextControl =
  vstoDocument.Controls.AddPlainTextContentControl(
  vstoDocument.Range(ref missing, ref missing), "My Control");

Other Applications and Limitations

Given a host item for a document, worksheet, or workbook you have a lot of VSTO document functionality available to you. You can dynamically create host item controls like NamedRange and ListObject and data bind to those controls.  You can add Windows Forms controls or WPF controls to the document. You can also add document level smart tags as described in my previous post.

Also it is important to note the document level features that are not accessible via this feature. It is not possible to create a document level ribbon in an Application add-in or access the document level ActionsPane that document level VSTO customizations enable. It is also not possible to work with controls that cannot be added dynamically to the Controls collection (XMLNode, XMLNodes, and XMLMappedRange).