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

You can use an application-level add-in to customize Word documents and Excel workbooks in the following ways:

  • Add managed controls to any open document or worksheet.

  • Convert an existing list object on an Excel worksheet to an extended ListObject 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 an object at run time that extends the document or workbook.

Applies to: The information in this topic applies to application-level projects for the following applications: Excel 2010; Word 2010. For more information, see Features Available by Office Application and Project Type.

Extended objects are instances of types provided by the Visual Studio Tools for Office runtime that add functionality to objects that exist natively in the Word or Excel object models (called native Office objects). To generate an extended object for a Word or Excel object, use the GetVstoObject method. The first time you call the GetVstoObject method for a specified Word or Excel object, it returns a new object that extends the specified object. Each time you call the method and specify the same Word or Excel 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, if you call the GetVstoObject method to extend a Microsoft.Office.Interop.Word.Document object, the method returns a Microsoft.Office.Tools.Word.Document object.

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.

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

When you use the GetVstoObject to extend a document-level object (that is, a Microsoft.Office.Interop.Excel.Workbook, Microsoft.Office.Interop.Excel.Worksheet, or Microsoft.Office.Interop.Word.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 managed controls to the document, workbook, or worksheet. For more information, see Adding Managed Controls to Documents and Worksheets.

To generate a host item for a Word document

  • The following code example demonstrates how to generate a host item for the active document.

    if (Globals.ThisAddIn.Application.Documents.Count > 0)
    {
        Microsoft.Office.Interop.Word.Document nativeDocument =
            Globals.ThisAddIn.Application.ActiveDocument;
        Microsoft.Office.Tools.Word.Document vstoDocument =
            Globals.Factory.GetVstoObject(nativeDocument);
    }
    

To generate a host item for an Excel workbook

  • The following code example demonstrates how to generate a host item for the active workbook.

    Microsoft.Office.Interop.Excel.Workbook nativeWorkbook = 
        Globals.ThisAddIn.Application.ActiveWorkbook;
    if (nativeWorkbook != null)
    {
        Microsoft.Office.Tools.Excel.Workbook vstoWorkbook = 
            Globals.Factory.GetVstoObject(nativeWorkbook);
    }
    

To generate a host item for an Excel worksheet

  • The following code example demonstrates how to generate a host item for the active worksheet in a project.

    Microsoft.Office.Interop.Excel.Worksheet nativeWorksheet =
        Globals.ThisAddIn.Application.ActiveSheet;
    if (nativeWorksheet != null)
    {
        Microsoft.Office.Tools.Excel.Worksheet vstoSheet = 
            Globals.Factory.GetVstoObject(nativeWorksheet);
    }
    

When you use the GetVstoObject method to extend a Microsoft.Office.Interop.Excel.ListObject, the method returns a Microsoft.Office.Tools.Excel.ListObject. The Microsoft.Office.Tools.Excel.ListObject has all of the features of the original Microsoft.Office.Interop.Excel.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

  • The following code example demonstrates how to generate a Microsoft.Office.Tools.Excel.ListObject for the first Microsoft.Office.Interop.Excel.ListObject in the active worksheet in a project.

    Microsoft.Office.Interop.Excel.Worksheet sheet =
        Globals.ThisAddIn.Application.ActiveSheet;
    if (sheet.ListObjects.Count > 0)
    {
        Excel.ListObject listObject = 
            sheet.ListObjects[1];
        Microsoft.Office.Tools.Excel.ListObject vstoListObject =
            Globals.Factory.GetVstoObject(listObject);
    }
    

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 control provided by the Visual Studio Tools for Office runtime 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 Note

You cannot add a XmlMappedRange control to a worksheet, or a 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.

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 Microsoft.Office.Interop.Excel.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.

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 Microsoft.Office.Interop.Word.Application class, rather than the Microsoft.Office.Interop.Word.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.

The following code example demonstrates how to handle an application-level event for Word documents. The CreateDocument method 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 Microsoft.Office.Interop.Word.Application object, the event handler must compare the Doc parameter with the document1 object to determine if document1 represents the saved document.

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;
    }
}

The following code examples simplify this process by handling the BeforeSave event of a Microsoft.Office.Tools.Word.Document host item. The CreateDocument2 method in these examples generate 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.

The following code example demonstrates this task.

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 = Globals.Factory.GetVstoObject(document2);
    vstoDocument.BeforeSave += new SaveEventHandler(vstoDocument_BeforeSave);
}

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

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

Use the Globals.Factory.HasVstoMethod method. Pass in the native Word or Excel object, such as a Microsoft.Office.Interop.Word.Document or Microsoft.Office.Interop.Excel.Worksheet, that you want to test for an extended object.

The HasVstoObject method 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.

Was this page helpful?
(1500 characters remaining)
Thank you for your feedback
Show:
© 2014 Microsoft