Now that you have seen-what is included in VSTO, it is time to look at the more practical side of things, and how you can build VSTO projects. The techniques demonstrated in this section are general ones that apply to all types of VSTO projects.
In this section, you will look at the following:
- Office object model
- VSTO namespaces
- Host items and-host controls
- Basic VSTO project structure
- The Globals class
- Event handling
Office Object Model
The Office 2007 suite of applications exposes its functionality through a COM object model. You can use this object model directly from VBA to control just about any aspect of Office functionality. The Office object model was introduced in Office 97, and has evolved since then as functionality in Office
There are a huge number of classes in the Office object model, some of which are used across the suite of Office applications and some of which are specific to individual applications. For example, the Word 2007 object model includes a Documents collection representing the currently loaded objects, each of which is represented by a Document object. In VBA code, you can access documents by name or index and call methods to perform operations on them. For example, the following VBA code closes the document with the name My Document without saving changes:
The Office object model includes named constants (such as wdDoNotSaveChanges in the preceding code and enumerations to make it easier to use.
VSTO contains a collection of namespaces, which contain types that you can use to program against the Office object model. Many of the classes and enumerations in these namespaces map directly to objects and enumerations in the Office object model. These are accessed through Office PIAs. However, VSTO also contains types that do not map directly, or are unrelated to the Office object model. For example, there are a lot of classes that are used for designer support in VS.
The types that do wrap or communicate with objects in the Office object model are divided into namespaces containing types for use with Office 2003 and those for use with Office 2007. ‘The namespaces that you will use for Office 2007 development are summarized in the following table.
Host Items and Host Controls
Host items and host controls are classes that have been extended to make it easier for document-level customizatlons to interact with Office documents. These classes simplify your code as they expose
.NET-style events and are fully managed. The “host” part of the name of host items and host classes references the fact that these classes wrap and extend the native Office objects that are accessed
Often when you use host items and host controls, you will find that it is necessary to use the underlying PIA interop types as well. For example, if you create a new Word document, then you receive a reference to the interop Word document type rather than the Word document host item. Youneed to be aware of
this and write your code accordingly.
There are host items and host controls for both Word and Excel document-level customizations.
There is a single host item for Word, Microsoft .Office. Tools. Word. Document. This represents a Word document. As you might expect, this class has an enormous number of methods and properties that you can use to interact with Word documents.
There are 12 host controls for Word, as shown in the following table, all of which are found in the Microsoft .Office. Tools .Word namespace.
There are three host items and four host controls for Excel, all of which are contained in the Microsoft. Office. Tools. Excel namespace.
The Excel host items are shown in the following table.
The Excel host controls are shown in the following table.
Basic VSTO Project Structure
When you first create a VSTO project, the files you start with vary according to the project type, but there are some common features. In this section, you will see what constitutes a VSTO project.
Document-Level Customizatlon Project Structure
when you create a document-level customization project, you will see an entry in Solution Explorer that represents the document type. This may be:
- A .docx file for a Word document
- A .dotx file for a Word template
- A .xlsx file for an Excel workbook
- A .xltx file for an Excel template
Each of these has a designer view and a code file, which you will see if you expand the item in Solution Explorer. The Excel templates also include sub-items representing the workbook as a whole and each spreadsheet in the workbook. This structure enables you to provide custom functionality on a per- or per-workbook basis.
If you view the hidden files in one of these projects, you will see several designer files that you can look at to see the template-generated code. Each Office document item has an associated class from the VSTO narnespaces, and the classes in the code files derive from these classes. These classes are defined as partial class definitions so that your custom code is separated from the code generated by the visual designer, similar to the structure of Windows Forms applications.
For example, the Word document template provides a class that derives from the host item Microsoft. Office.Tools. Word.Document. This code is contained in This Document.cs as follows:
This template-generated code includes aliases for the two main namespaces that you will use when creating a document-level customization for Word, Microsoft. Office. Core for the main VSTO Office classes and Microsoft. Office. Interop. Word for Word-specific classes. Note that if you want to use Word host controls, then you would also add a using statement for the Microsoft .Office. Tools. Word namespace. The template-generated code also defines two event handler hooks that you can use to execute code when the document is loaded or unloaded.
ThisDocument_Startup () and ThisDocument_Shutdown ().
Every one of the document-level customization project types has a similar structure in its code file (or, in the case of Excel, code files). There are namespace aliases defined for you and handlers for the various Startup and Shutdown events that the VSTO classes define. From this starting point, you add dialog boxes, action panes, ribbon controls, event handlers, and custom code to define the behavior of your customization.
With document-level customizations, you can also customize the document or documents through the document designer. Depending on the type of solution you are creating, this might involve adding boilerplate content to templates, interactive content to documents, or something else. The designers are effectively hosted versions of Office applications, and you can use them to enter content just as you can in the applications themselves. However, you can also ‘add controls such as host controls and Windows Forms controls to documents, and code around these controls.
Application-Level Add-In Project Structure
When you create an application-level add-in, there will be no document or documents in Solution Explorer. Instead, y,ou will see an item representing the application that you are creating an add-in for, and if you expand this item, you will see a file called ThisAddIn. cs. This file contains a partial class definition for a class called This AddIn, which provides the entry point for your add-in. This class
derives from Microsoft . Office. Tools. AddIn, which provides code add-in functionality, and implements the Microsoft. Visual Studio. Tools. Office. IOfficeEntryPoint interface, which is an infrastructure interface.
As you can see, this structure is very similar to the structure used in document-level customizations. It includes aliases for the same Microsoft. Office. Core and Microsoft .Office. Interop. Word namespaces, and gives you event handlers for Startup and Shutdown events (ThisAddIn_Startup() and This AddIn_Shutdown ()) These events are slightly different from the document ones, as they are raised when the add-in is loaded or unloaded rather than when individual documents are opened or closed.
You proceed to customize application-level add-ins much as you do document-level customizations by adding ribbon controls, task panes, and additional code.
The Globals Class .
All VSTO project types define a class called Globals that gives you global access to the following:
- For document-level customizations, all documents in the solution. These are exposed through members with names that match the document class names – for example, Globals .
This workbook and Globals.Sheet1.
- For application-level add-ins, the add-in object. This is exposed through Globals.ThisAddln.
- For Outlook add-in projects, all Outlook form regions.
- All ribbons in the solution, through the Globals. Ribbons property.
Behind the scenes, the Globals class is created through a series of partial definitions in the various designer-maintained code files in your solution. For example, the default Sheetl worksheet in an Excel
Workbook project includes the following designer-generated code:
Earlier in this chapter, you saw how the host item and host control classes expose events that you can handle. Unfortunately, this is not the case for the interop classes. There are a few events that you can use, but for the most part, you will find it difficult to create event-driven solutions by using these events. Most often” to respond to events you should focus on the events exposed by host items and host controls.
The obvious problem here is that there are no host items or host controls for application-level add-in projects. Sadly, this is a problem that you must learn to live with when you use VSTO. However, the
most common events that you are likely to listen for in add-ins are those associated with ribbon menu and task pane interaction. You design ribbons with the integrated ribbon designer, and you can respond to any events generated by the ribbon to make the control interactive. Task panes are usually implemented as Windows Forms user controls (although you can use WPF), and you can use Windows Forms events here rather than PIA interop events. This means that you will not often encounter situations in which there is no event available for the functionality you require.
When you do need to use a PIA-exposed event, you will find that events are exposed through interfaces – on the PIA objects. Consider a Word Add-In project. The ThisAddln class in this project exposes a property called Application through which you can obtain a reference to the Office application. This property is of type Microsoft .Office. Interop. word. Application, and exposes events
through the Microsoft .Office. Interop. Word. ApplicationEvents4_Event interface. This interface exposes a total of 29 events (which really doesn’t seem to be a lot for an application as complex as Word, does it?). You can handle, for example, the DocumentBeforeClose event to respond to Word document close requests.