Extending Word Documents and Excel Workbooks in Application-Level Add-ins at Run Time

Applies to

The information in this topic applies only to the specified Visual Studio Tools for Office projects and versions of Microsoft Office.

Project type

  • Application-level projects

Microsoft Office version

  • Excel 2007

  • Word 2007

For more information, see Features Available by Application and Project Type.

Starting in Visual Studio 2008 Service Pack 1 (SP1), you can use an application-level add-in to customize documents and workbooks in the following ways:

  • Add managed controls to any open document or worksheet.

  • Create smart tags that are recognized in a specific document or workbook.

  • Convert an existing list object on an Excel worksheet to a Visual Studio Tools for Office list object that exposes events and can be bound to data by using the Windows Forms data binding model.

  • Access application-level events that are exposed by Word and Excel for specific documents, workbooks, and worksheets.

To use this functionality, you generate a Visual Studio Tools for Office object at run time that extends the document or workbook.

Generating Extended Objects in Add-Ins

Extended objects are Visual Studio Tools for Office objects that add functionality to objects that exist natively in the Word or Excel object models (called native Office objects). To generate an extended object in your add-in, use the GetVstoObject method of an instance of one of the following types in the Excel and Word primary interop assemblies:

The first time you call the GetVstoObject method of a native Office object, it returns a new Visual Studio Tools for Office object that extends the object. Each time you call the method on the same native Office object, it returns the same extended object. 

The type of the extended object has the same name as the type of the native Office object, but the type is defined in the Microsoft.Office.Tools.Excel or Microsoft.Office.Tools.Word namespace. For example, the GetVstoObject method of a Document object returns a Microsoft.Office.Tools.Word.Document.

To determine whether a Visual Studio Tools for Office object has already been generated for a particular native Office object, use the HasVstoObject method of the Office object. For more information, see Determining Whether an Office Object Has Been Extended.

The GetVstoObject methods are intended to be used primarily in application-level projects. You can also use these methods in document-level projects, but they behave differently, and have fewer uses. For more information, see Getting Extended Objects from Native Office Objects in Document-Level Customizations.

Note

To use the GetVstoObject and HasVstoObject methods in a code file other than ThisAddIn.cs or ThisAddIn.vb, or in a project that you created before installing SP1, you must modify your project. For more information, see Configuring Your Project to Use the GetVstoObject and HasVstoObject Methods.

Generating Host Items

When you use the GetVstoObject method of a document-level object, that is, a Workbook, Worksheet, or Document, the returned object is called a host item. A host item is a type that can contain other objects, including other extended objects and controls. It resembles the corresponding type in the Word or Excel primary interop assembly, but it has additional features. For more information about host items, see Host Items and Host Controls Overview.

After you generate a host item, you can use it to add smart tags or managed controls to the document, workbook, or worksheet. For more information, see Adding Smart Tags to Documents and Workbooks and Adding Managed Controls to Documents and Worksheets.

To generate a host item for a Word document

  • Use the GetVstoObject method of a Document. The following code example generates a host item for the active document.

    If Globals.ThisAddIn.Application.Documents.Count > 0 Then 
        Dim NativeDocument As Microsoft.Office.Interop.Word.Document = _
            Globals.ThisAddIn.Application.ActiveDocument
        Dim VstoDocument As Microsoft.Office.Tools.Word.Document = _
            NativeDocument.GetVstoObject()
    End If
    
    if (Globals.ThisAddIn.Application.Documents.Count > 0)
    {
        Microsoft.Office.Interop.Word.Document nativeDocument =
            Globals.ThisAddIn.Application.ActiveDocument;
        Microsoft.Office.Tools.Word.Document vstoDocument =
            nativeDocument.GetVstoObject();
    }
    

To generate a host item for an Excel workbook

  • Use the GetVstoObject method of a Workbook. The following code example generates a host item for the active workbook.

    Dim NativeWorkbook As Microsoft.Office.Interop.Excel.Workbook = _
        Globals.ThisAddIn.Application.ActiveWorkbook
    
    If NativeWorkbook IsNot Nothing Then 
        Dim VstoWorkbook As Microsoft.Office.Tools.Excel.Workbook = _
            NativeWorkbook.GetVstoObject()
    End If
    
    Microsoft.Office.Interop.Excel.Workbook nativeWorkbook =
        Globals.ThisAddIn.Application.ActiveWorkbook;
    
    if (nativeWorkbook != null)
    {
        Microsoft.Office.Tools.Excel.Workbook vstoWorkbook =
            nativeWorkbook.GetVstoObject();
    }
    

To generate a host item for an Excel worksheet

  • Use the GetVstoObject method of a Worksheet. The following code example generates a host item for the active worksheet.

    Dim NativeSheet As Microsoft.Office.Interop.Excel.Worksheet = _
        TryCast(Globals.ThisAddIn.Application.ActiveSheet,  _
        Microsoft.Office.Interop.Excel.Worksheet)
    
    If NativeSheet IsNot Nothing Then 
        Dim VstoSheet As Microsoft.Office.Tools.Excel.Worksheet = _
            NativeSheet.GetVstoObject()
    End If
    
    Microsoft.Office.Interop.Excel.Worksheet nativeSheet =
        Globals.ThisAddIn.Application.ActiveSheet as
        Microsoft.Office.Interop.Excel.Worksheet;
    
    if (nativeSheet != null)
    {
        Microsoft.Office.Tools.Excel.Worksheet vstoSheet =
            nativeSheet.GetVstoObject();
    }
    

Generating ListObject Host Controls

When you use the GetVstoObject method of a ListObject, the method returns a Microsoft.Office.Tools.Excel.ListObject. The generated Microsoft.Office.Tools.Excel.ListObject has all of the features of the original ListObject, but it also has additional functionality, such as the ability to be bound to data by using the Windows Forms data binding model. For more information, see ListObject Control.

To generate a host control for a ListObject

  • Use the GetVstoObject method of a ListObject. The following code example generates a Microsoft.Office.Tools.Excel.ListObject for the first ListObject in the active worksheet.

    Dim sheet As Excel.Worksheet = Globals.ThisAddIn.Application.ActiveSheet
    
    If sheet.ListObjects.Count > 0 Then 
        Dim listObject As Excel.ListObject = sheet.ListObjects(1)
        Dim vstoListObject As Microsoft.Office.Tools.Excel.ListObject = _
            listObject.GetVstoObject()
    End If
    
    Microsoft.Office.Interop.Excel.Worksheet sheet =
        Globals.ThisAddIn.Application.ActiveSheet as
        Microsoft.Office.Interop.Excel.Worksheet;
    
    if (sheet.ListObjects.Count > 0)
    {
        Excel.ListObject listObject = sheet.ListObjects[1];
        Microsoft.Office.Tools.Excel.ListObject vstoListObject =
            listObject.GetVstoObject();
    }
    

Adding Smart Tags to Documents and Workbooks

After you generate a Microsoft.Office.Tools.Word.Document or Microsoft.Office.Tools.Excel.Workbook, you can create a smart tag that is recognized in the context of the document or workbook that these objects represent. To do this, use the VstoSmartTags property of the Microsoft.Office.Tools.Word.Document or Microsoft.Office.Tools.Excel.Workbook. For more information, see the following topics:

Adding Managed Controls to Documents and Worksheets

After you generate a Microsoft.Office.Tools.Word.Document or Microsoft.Office.Tools.Excel.Worksheet, you can add controls to the document or worksheet that these extended objects represent. To do this, use the Controls property of the Microsoft.Office.Tools.Word.Document or Microsoft.Office.Tools.Excel.Worksheet. For more information, see Adding Controls to Office Documents at Run Time.

You can add Windows Forms controls or host controls. A host control is a Visual Studio Tools for Office control that wraps a corresponding control in the Word or Excel primary interop assembly. A host control exposes all of the behavior of the underlying native Office object, but it also raises events and can be bound to data by using the Windows Forms data binding model. For more information, see Host Items and Host Controls Overview.

Note

You cannot add an XmlMappedRange control to a worksheet, or an XMLNode or XMLNodes control to a document, by using an add-in. These host controls cannot be added programmatically. For more information, see Programmatic Limitations of Host Items and Host Controls.

Persisting and Removing Controls

When you add managed controls to a document or worksheet, the controls are not persisted when the document is saved and then closed. All host controls are removed so that only the underlying native Office objects are left behind (for example, a Microsoft.Office.Tools.Excel.ListObject becomes a ListObject). All Windows Forms controls are also removed, but ActiveX wrappers for the controls are left behind in the document. You must include code in your add-in to clean up the controls, or to recreate the controls the next time the document is opened. For more information, see Persisting Dynamic Controls in Office Documents.

Accessing Application-Level Events on Documents and Workbooks

Some document, workbook, and worksheet events in the native Word and Excel object models are raised only at the application level. For example, the DocumentBeforeSave event is raised when a document is opened in Word, but this event is defined in the Application class, rather than the Document class.

When you use only native Office objects in your add-in, you must handle these application-level events and then write additional code to determine whether the document that raised the event is one that you have customized. Host items provide these events at the document level, so that it is easier to handle the events for a specific document. You can generate a host item and then handle the event for that host item.

Example That Uses Native Word Objects

The following code example demonstrates how to handle an application-level event for Word documents. The CreateDocument1 method in this example creates a new document, and then defines a DocumentBeforeSave event handler that prevents this document from being saved. Because this is an application-level event that is raised for the Application object, the event handler must compare the Doc parameter with the document1 object to determine if document1 represents the saved document.

Private document1 As Word.Document = Nothing 

Private Sub CreateDocument1()
    document1 = Me.Application.Documents.Add()
End Sub 

Private Sub Application_DocumentBeforeSave(ByVal Doc As Word.Document, _
    ByRef SaveAsUI As Boolean, ByRef Cancel As Boolean) _
    Handles Application.DocumentBeforeSave
    If Type.ReferenceEquals(Doc, document1) Then
        Cancel = True 
    End If 
End Sub
private Word.Document document1 = null;

private void CreateDocument1()
{
    document1 = this.Application.Documents.Add(ref missing,
        ref missing, ref missing, ref missing);
    this.Application.DocumentBeforeSave += 
        new Word.ApplicationEvents4_DocumentBeforeSaveEventHandler(
        Application_DocumentBeforeSave);
}

private void Application_DocumentBeforeSave(Word.Document Doc, 
    ref bool SaveAsUI, ref bool Cancel)
{
    if (Type.ReferenceEquals(Doc, document1)) 
    {
        Cancel = true;
    }
}

Example That Uses a Host Item

The following code example simplifies this process by handling the BeforeSave event of a Microsoft.Office.Tools.Word.Document host item. The CreateDocument2 method in this example generates a Microsoft.Office.Tools.Word.Document that extends the document2 object, and then it defines a BeforeSave event handler that prevents the document from being saved. Because this event handler is called only when document2 is saved, the event handler can cancel the save action without doing any extra work to verify which document was saved.

Private document2 As Word.Document = Nothing 
Private WithEvents vstoDocument As Microsoft.Office.Tools.Word.Document = Nothing 

Private Sub CreateDocument2()
    document2 = Me.Application.Documents.Add()
    vstoDocument = document2.GetVstoObject()
End Sub 

Private Sub vstoDocument_BeforeSave(ByVal sender As Object, _
    ByVal e As SaveEventArgs) Handles vstoDocument.BeforeSave
    e.Cancel = True 
End Sub
private Word.Document document2 = null;
private Microsoft.Office.Tools.Word.Document vstoDocument = null;

private void CreateDocument2()
{
    document2 = this.Application.Documents.Add(ref missing,
        ref missing, ref missing, ref missing);
    vstoDocument = document2.GetVstoObject();
    vstoDocument.BeforeSave += new SaveEventHandler(vstoDocument_BeforeSave);
}

private void vstoDocument_BeforeSave(object sender, SaveEventArgs e)
{
    e.Cancel = true;
}

Determining Whether an Office Object Has Been Extended

To determine whether a Visual Studio Tools for Office object has already been generated for a particular native Office object, use the HasVstoObject method of the Office object. This method returns true if an extended object has already been generated; otherwise, it returns false.

This is useful when you want to run code only when a specified Office object has an extended object. For example, if you have a Word add-in that handles the DocumentBeforeSave event to remove managed controls from a document before it is saved, you can use the HasVstoObject method to determine whether the document has been extended. If the document has not been extended, it cannot contain managed controls, and therefore the event handler can simply return without trying to clean up controls on the document.

Configuring Your Project to Use the GetVstoObject and HasVstoObject Methods

When you create an application-level project after you install Visual Studio 2008 SP1, the project is automatically configured for you to use the GetVstoObject and HasVstoObject methods in the ThisAddIn.cs or ThisAddIn.vb code files.

To use these methods in a code file other than ThisAddIn.cs or ThisAddIn.vb, you must make the following changes to the code file.

To modify a code file in an Excel project to create extended objects

  • Add the following using (for C#) or Imports (for Visual Basic) statements to the top of the code file in which you want to use the GetVstoObject and HasVstoObject methods.

    Imports Microsoft.Office.Tools.Excel.Extensions
    
    using Microsoft.Office.Tools.Excel.Extensions;
    

To modify a code file in a Word project to create extended objects

  • Add the following using (for C#) or Imports (for Visual Basic) statements to the top of the code file in which you want to use the GetVstoObject and HasVstoObject methods.

    Imports Microsoft.Office.Tools.Word.Extensions
    
    using Microsoft.Office.Tools.Word.Extensions;
    

To use these methods in an application-level project that you created before installing SP1, you must make the following changes to your project.

To modify an existing Excel add-in to create extended objects

  1. Add a reference to the Microsoft.Office.Tools.Excel.v9.0.dll assembly.

  2. Add the following using (for C#) or Imports (for Visual Basic) statements to the top of the code file in which you want to use the GetVstoObject and HasVstoObject methods.

    Imports Microsoft.Office.Tools.Excel.Extensions
    
    using Microsoft.Office.Tools.Excel.Extensions;
    

To modify an existing Word add-in to create extended objects

  1. Add a reference to the Microsoft.Office.Tools.Word.v9.0.dll assembly.

  2. Add the following using (for C#) or Imports (for Visual Basic) statements to the top of the code file in which you want to use the GetVstoObject and HasVstoObject methods.

    Imports Microsoft.Office.Tools.Word.Extensions
    
    using Microsoft.Office.Tools.Word.Extensions;
    

These changes are required because the GetVstoObject and HasVstoObject methods are implemented as extension methods. Although you use the GetVstoObject and HasVstoObject methods as though they were defined in types in the Excel or Word primary interop assemblies, they are actually defined in types in the Microsoft.Office.Tools.Excel.Extensions and Microsoft.Office.Tools.Word.Extensions namespaces of the Visual Studio Tools for Office runtime. For more information about extension methods, see Extension Methods (C# Programming Guide) and Extension Methods (Visual Basic).

See Also

Tasks

Excel Add-In Dynamic Controls Sample

Word Add-In Dynamic Controls Sample

Concepts

Programming Application-Level Add-Ins

Adding Controls to Office Documents at Run Time

Host Items and Host Controls Overview

Smart Tags Overview

Getting Extended Objects from Native Office Objects in Document-Level Customizations

Change History

Date

History

Reason

August 2008

Fixed the code examples for the procedure "To modify a code file in a Word project to create extended objects" to specify the correct namespace for Word.

Content bug fix.

July 2008

Added topic.

SP1 feature change.