49第 章
VSTO
本章内容:
● 可以用 VSTO 创建的项目类型,在这些项目中可以包含的功能
● 应用于所有 VSTO 解决方案类型的基础技术
● 使用宿主项和宿主控件
● 构建带自定义 UI 的 VSTO 解决方案
Visual Studio Tools for Office(VSTO)技术可以使用.NET Framework 定制和扩展 Microsoft Office
应用程序和文档。它包含的工具还可以使在 Visual Studio 中简化这个自定义过程,例如,用于 Office
Ribbon 控件的可视化设计器。
VSTO 是 Microsoft 发布的一系列产品中的最新产品,可以定制 Office 应用程序。用于访问 Office
应用程序的对象模型随时间逐步演化。如果读者过去曾使用过它,就会熟悉它的某些部分。如果读
者以前为 Office 应用程序编写过 VBA 插件,就为本章讨论的技术做好了准备。但 VSTO 提供的、
便于与 Office 交互的类已经扩展到 Office 对象模型之外。例如,VSTO 类包括.NET 数据绑定功能。
在 Visual Studio 2008 推出之前,VSTO 一直是一个独立下载的软件包,如果要开发 Office 解决
方案,就可以得到它。从 Visual Studio 2008 开始,VSTO 集成到 Visual Studio IDE 中。VSTO 的这
个版本也称为 VSTO 3,包含对 Office 2007 的全部支持,还包括许多新功能。例如,可以与 Word
内容控件交互,前面提及的 ribbon 可视化设计器等。
在 Visual Studio 2010 中,VSTO 4 扩展并改进了以前的版本,它更便于部署,且不再需要在客
户端 PC 上安装主互操作程序集(Primary Interop Assembly,PIA),这通过 CLR 4 类型嵌入功能实现。
还包含对 Office 2010 的支持。
本章不需要 VSTO 或其以前版本的任何预备知识。
49.1 VSTO 概述
VSTO 包含如下组件:
● 一组项目模板,可用于创建各种类型的 Office 解决方案
● 设计器,支持 ribbons、动作面板和自定义任务面板的可视化布局
● 建立在 Office 对象模型基础之上的类,它们还提供扩展功能
C#高级编程(第 7 版)
VSTO 支持 Office 2003、2007 和 2010。VSTO 类库有多种形式,分别用于这几种 Office 版本,
它们分别使用不同集的程序集。为了简单起见,本章主要介绍 2007 版。
VSTO 解决方案的一般体系结构如图 49-1 所示。
VSTO 解决方案
.NET
Framework
VSTO
PIA
仅用于设计期间
Office 应用程序
图 49-1
注意,当面向.NET 4 时,在设计期间仅需要如图 49-1 所示的 PIA,当部署到客户端时这用作内嵌
的类型。这对于面向.NET 3.5的VSTO解决方案不成立,此时在开发计算机和目标计算机上都需要PIA。
49.1.1 项目类型
图 49-2 显示了 VS for Office 2007 中的项目模板(Office 2010 中可用的列表与此类似)。本章主要
讨论 Office 2007。
图 49-2
E52
第 49 章 VSTO
VSTO 项目模板可以分为如下类别:
● 文档级自定义
● 应用程序级的插件
● SharePoint 工作流模板(在图 49-2 中未显示,因为它们位于有关单独的模板类别中)
注意,VSTO 的以前版本包含第 4 类:InfoPath 窗体模板,它在 VSTO 4 中不再可用。
本章主要讨论最常用的项目类型,即文档级自定义和应用程序级的插件。
1. 文档级自定义
创建这种类型的项目时,会生成一个链接到单个文档上的程序集,如 Word 文档、Word 模板或
Excel 工作簿。加载该文档时,关联的 Office 应用程序会检测到该自定义,加载程序集,使 VSTO
定制可用。
这类项目可以给某个特定业务范围的文档提供附加功能,或者在文档模板中添加自定义功
能,为整类文档添加附加功能。所包含的代码可以操作文档和文档的内容,包括嵌入对象。还
可以提供自定义菜单,包括可以用 Visual Studio Ribbon 设计器创建的功能区菜单。
创建文档级的项目时,可以选择创建新文档,或者复制已有的文档,作为开发的起点。也可以
选择要创建的文档类型。例如,对于 Word 文档,就可以选择创建.docx(默认)、.doc 或.docm 文档(.docm
是启用宏的文档)。其对话框如图 49-3 所示。
图 49-3
2. 应用程序级的插件
应用程序级的插件不同于文档级的自定义,因为前者可用于整个目标 Office 应用程序。我们可
以访问插件代码,而无论加载什么文档,其中都可能包含菜单、文档操作等。
启动某个 Office 应用程序(如 Word)时,它会寻找已在注册表中有注册项的关联插件,并加载它
需要的任何程序集。
E53
C#高级编程(第 7 版)
3. SharePoint 工作流模板
这些项目提供了创建 SharePoint 工作流应用程序的模板。它们用于管理 SharePoint 进程中的文
档流。创建这类项目后,就可以在文档的生命周期中,在重要的时刻执行自定义代码。
49.1.2 项目功能
在各种 VSTO 项目类型中有几个可以使用的功能,如交互面板和控件。我们使用的项目类型决
定了可用的功能。表 49-1~49-3 根据项目类型列出了这些功能。
功 能
动作面板
数据缓存
VBA 代码
的端点
宿主控件
智能标记
可视化文档
设计器
表 49-1
说 明
动作面板是驻留在 Word 或 Excel 的动作面板中的对话框。可以在这里显示任意控件,这是扩展文档和
应用程序的一种通用方式
数据的缓存可以在文档外部的缓存数据岛上存储在文档中使用的数据。这些数据岛可以从数据源中更新
或手工更新,在数据源脱机或不可用时,允许 Office 文档访问数据
如前所述,VSTO 支持与 VBA 的交互操作。在文档级的自定义中,可以提供从 VBA 代码中调用的端
点方法
宿主控件是 Office 对象模型中已有控件的扩展包装器。可以操作这些对象,并把数据绑定到这些对象上
智能标记是嵌入在 Office 文档中、有类型化内容的对象。它们在 Office 文档的内容中自动检测,例如,
应用程序检测到相应的文本时,就会自动添加股票报价智能标记。可以创建自己的智能标记类型,定义
可以在该类标记上执行的操作
处理文档自定义项目时,要使用 Office 对象模型创建一个可视化设计界面,用于交互式地排放控件。设
计器中显示的工具栏和菜单(如本章后面所述)功能齐全
表 49-2 列出了应用程序级的插件功能
功 能
自定义任务面板
跨应用程序的
通信
Outlook 窗体区域
表 49-2
说 明
任务面板一般停靠在 Office 应用程序的一个边界上,并提供各种功能。例如,Word 的一个任
务面板用于操作样式。与动作面板一样,它们也提供了很大的灵活性
一旦为某个 Office 应用程序创建了插件,就可以把这个功能提供给其他插件。例如,可以在 Excel
中创建一个财务计算服务,再从 Word 中使用该服务——无需创建一个单独的插件
可以创建在 Outlook 中使用的窗体区域
表 49-3 列出了所有项目类型可用的功能
表 49-3
说 明
可以通过 ClickOnce 部署方法把自己创建的任意 VSTO 项目发布给最终用户,让用户检测对应用
程序集清的变化,拥有文档级和应用程序级解决方案的最新版本
功能区菜单在所有的 Office 应用程序中使用。VSTO 提供了创建自定义功能区菜单的两种方式。
可以使用 XML 定义功能区,也可以使用功能区设计器,后者更容易使用,尽管采用 XML 版本可
以保证向后兼容性
功 能
ClickOnce 部署
功能区菜单
E54
第 49 章 VSTO
49.2 VSTO 项目基础
既然知道了 VSTO 包含的内容,就该查看 VSTO 更实用的一面了,并学习如何构建 VSTO 项目。
本节介绍的技术可以应用于所有 VSTO 项目类型。
本节介绍如下内容:
● Office 对象模型
● VSTO 名称空间
● 宿主项和宿主控件
● 基本 VSTO 项目结构
● Globals 类
● 事件处理
49.2.1 Office 对象模型
Office 应用程序的 2007 和 2010 套件通过一个 COM 对象模型提供其功能。可以从 VBA 中直接
使用这个对象模型,来控制 Office 功能的任意方面。Office 对象模型在 Office 97 中引入,之后有了
许多演变,Office 中的功能也有许多改变。
Office 对象模型有大量类,其中一些类在 Office 应用程序的套件中使用,一些类专门用于个别
应用程序。例如,Word 2007 对象模型包含一个 Documents 集合,它表示当前加载的对象,每个对
象都用一个 Document 对象表示。在 VBA 代码中,可以根据名称或索引访问文档,调用方法对它们
执行操作。例如,下面的 VBA 代码关闭名称为 My Document 的文档,且不保存修改的内容:
Documents("My Document").Close SaveChanges:= wdDoNotSaveChanges
Office 对象模型包含命名常量(如上述代码中的 wdDoNotSaveChanges)和枚举,更便于使用。
49.2.2 VSTO 名称空间
VSTO 包含一个名称空间集合,该集合包含的类型可用于给 Office 对象模型编写程序。这些名
称空间中的许多类型直接映射到 Office 对象模型中的类型上。可以通过 Office PIA 在设计期间访问
它们,在部署解决方案时则通过嵌入的类型信息来访问。由于嵌入的类型,因此主要使用用于访问
Office 对象模型的接口。VSTO 还包含不能直接映射的类型,或者与 Office 对象模型无关的类型。
例如,有许多类用于 Visual Studio 中支持的设计器。
包装 Office 对象模型中的对象或与它们通信的类型分别放在不同的名称空间中。用于 Office 开
发的名称空间如表 49-4 所示。
名 称 空 间
Microsoft.Office.Core
Microsoft.Office.Interop.*
Microsoft.Office.Tools
表 49-2
说 明
因为这些名称空间包含 Office 对象模型的接口和瘦包装器,所以提供了处理
Office 类的基本功能。在 Microsoft.Office.Interop 名称空间中有几个嵌套的名称空
间,用于每个 Office 产品
这个名称空间包含的通用类型提供了VSTO功能和用于嵌套名称空间中的许多类
的基类。例如,这个名称空间包含实现文档级自定义中的动作面板所需的类,以
及应用程序级插件的基类
E55
C#高级编程(第 7 版)
名 称 空 间
Microsoft.Office.Tools.Excel
Microsoft.Office.Tools.Excel.*
Microsoft.Office.Tools.Outlook
Microsoft.Office.Tools.Ribbon
Microsoft.Office.Tools.Word
Microsoft.Office.Tools.Word.*
Microsoft.VisualStudio.Tools.*
49.2.3 宿主项和宿主控件
(续表)
这些名称空间包含的类型用于与 Excel 应用程序和 Excel 文档交互
说 明
这个名称空间包含的类型用于与 Outlook 应用程序交互
这个名称空间包含的类型用于处理和创建功能区菜单
这些名称空间包含的类型用于与 Word 应用程序和 Word 文档交互
这些名称空间提供的 VSTO 基础结构可以在 Visual Studio 中开发 VSTO 解决方案
时使用
宿主项和宿主控件是经过扩展的接口,使文档级的自定义更容易与 Office 文档交互。这些接口
简化了代码,因为它们提供了.NET 样式的事件,且进行了全面地管理。宿主项和宿主控件中的“宿
主”表示,这些接口封装和扩展了本地 Office 对象。
在使用宿主项和宿主控件时,也需要使用底层的交互操作类型。例如,如果创建了一个新的
Word 文档,就会接收到对交互操作 Word 文档类型的引用,而不是 Word 文档宿主项。必须注意这
一点,并据此编写代码。
Word 和 Excel 文档级自定义都有宿主项和宿主控件。
1. Word
Word 只有一个宿主项 Microsoft.Office.Tools.Word.Document。这表示一个 Word 文档。果然,这
个接口有许多方法和属性,可用于与 Word 文档交互。
Word 有 12 个宿主控件,如表 49-5 所示,所有宿主控件都在 Microsoft.Office.Tools.Word 名称空
间中。
控 件
Bookmark
XMLNode、XmLNodes
ContentControl
BuildingBlockGallery-
ContentControl
表 49-5
说 明
这个控件表示 Word 文档中的一个位置,它可以是单个位置,或一个字符范围
当文档有一个附加的XML 架构时使用这两个控件,它们允许通过文档内容的XML
节点位置来引用文档内容。也可以用这两个控件操作文档的 XML 结构
这个接口与本表中剩余 8 个控件有相同的基接口(ContentControlBase),允许处理
Word 内容控件。内容控件把内容表示为控件,或者启用文档中纯文本没有提供的
功能
这个控件允许添加和处理文档构建模块,如格式化的表、封面等
ComboBoxContentControl
这个控件表示格式化为组合框的内容
DatePickerContentControl
这个控件表示格式化为日期拾取器的内容
DropDownListContentControl
这个控件表示格式化为下拉列表的内容
E56
第 49 章 VSTO
(续表)
控 件
GroupContentControl
PictureContentControl
RickTextContentControl
PlainTextContentControl
2. Excel
这个控件表示的内容是其他内容项的分组集合,包括文本和其他内容控件
说 明
这个控件表示一幅图像
这个控件表示一块格式文本内容
这个控件表示一块纯文本内容
Excel 有 3 个宿主项和 4 个宿主控件,它们都包含在 Microsoft.Office.Tools.Excel 名称空间中。
Excel 宿主项如表 49-6 所示。
主 机 项
Workbook
Worksheet
Chartsheet
表 49-6
说 明
这个宿主项表示整个 Excel 工作簿,它可以包含多个工作表和图表
这个宿主项用于工作簿中的单个工作表
这个宿主项用于工作簿中的单个图表
Excel 宿主控件如表 49-7 所示。
控 件
Chart
ListObject
NamedRange
表 49-7
说 明
这个控件表示嵌入到工作表中的图表
这个控件表示工作表中的一个列表
这个控件表示工作表中的一个命名区域
XmlMappedRange
当 Excel 电子表格有附加的架构时使用这个控件,它用于处理映射到 XML 架构元素上的范围
49.2.4 基本的 VSTO 项目结构
第一次创建 VSTO 项目时,系统创建的文件随项目类型的不同而不同,但有一些共同的功能。
本节介绍 VSTO 项目的组成。
1. 文档级自定义项目结构
创建文档级自定义项目时,在 Solution Explorer 窗口中有一项表示文档类型。它可以是:
● 表示 Word 文档的.docx 文件
● 表示 Word 模板的.dotx 文件
● 表示 Excel 工作簿的.xlsx 文件
● 表示 Excel 模板的.xltx 文件
每个文档类型都有一个设计器视图和一个代码文件,如果在 Solution Explorer 窗口中展开该项,
就会看到它们。Excel 模板还包含子项,它们表示整个工作簿和工作簿中的每个工作表。这个结构
可以在每个工作表或工作簿的基础上提供自定义功能。
E57
C#高级编程(第 7 版)
如果查看上述项目类型的隐藏文件,就会看到几个设计器文件,查看这些设计器文件,还会看
到模板生成的代码。每个 Office 文档项都在 VSTO 名称空间中有关联的类,代码文件中的类派生自
这些类。这些类定义为部分类,这样自定义代码会与可视化设计器生成的代码分隔开,类似于
Windows 窗体应用程序的结构。
例如,Word 文档模板提供了一个派生自 Microsoft.Office.Tools.Word.Document 宿主项的类。这
个类通过 Base 属性提供 Document 宿主项,这个类包含在 ThisDocument.cs 中,如下所示:
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Linq;
using Microsoft.VisualStudio.Tools.Applications.Runtime;
using Office = Microsoft.Office.Core;
using Word = Microsoft.Office.Interop.Word;
namespace WordDocument1
{
public partial class ThisDocument
{
private void ThisDocument_Startup(object sender, System.EventArgs e)
{
}
private void ThisDocument_Shutdown(object sender, System.EventArgs e)
{
}
#region VSTO Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InternalStartup()
{
this.Startup += new System.EventHandler(ThisDocument_Startup);
this.Shutdown += new System.EventHandler(ThisDocument_Shutdown);
}
#endregion
}
}
这些模板生成的代码包含两个主要名称空间的别名,在为 Word 创建文档级自定义时,需要使
用这两个名称空间。Microsoft.Office.Core 用于主要的 VSTO Office 类,Microsoft.Office.Interop.Word
用于 Word 专用的类。注意如果要使用 Word 宿主控件,那么还要为 Microsoft.Office.Tools.Word 名称
空间添加一条 using 语句。模板生成的代码还定义两个事件处理程序挂钩——ThisDocument_Startup()
和 ThisDocument_Shutdown(),用于在加载或卸载文档时执行代码。
每个文档级自定义项目类型的代码文件(或者,对于 Excel 文件或代码文件)都有类似的结构,还
定义了名称空间别名以及 VSTO 类中各个 Startup 和 Shutdown 事件的处理程序。以此为起点,可以
添加对话框、动作面板、ribbon 控件、事件处理程序和自定义代码,来定义自定义行为。
E58