使用文档属性
    DocumentProperties集合和DocumentProperty对象位于Microsoft Office 11.0 Object Library(office.dll)中,该对象库包含所有Office应用程序共享的对象。 这些对象位于Microsoft.Office.Core命名空间中,通常会以Office命名空间别名进入您的代码,如下所示:
    using Office = Microsoft.Office.Core;
    迭代DocumentProperties集合
    清单5-15显示了一个在Workbook.CustomDocumentProperties和Workbook.BuiltInDocumentProperties返回的DocumentProperties集合中进行迭代的示例。
    清单5-15 在DocumentProperties集合上迭代的VSTO定制
    VSTO:使用C#开发Excel、Word【15】 - 图1
    private void ThisWorkbook_Startup(object sender, EventArgs e)
    {
    Office.DocumentProperties customProps = this.
    CustomDocumentProperties as Office.DocumentProperties;

    Office.DocumentProperties builtinProps = this.
    BuiltinDocumentProperties as Office.DocumentProperties;

    foreach (Office.DocumentProperty builtinProp in builtinProps)
    {
    MessageBox.Show(String.Format(
    “{0} {1}”, builtinProp.Name, builtinProp.Value));
    }

    foreach (Office.DocumentProperty customProp in customProps)
    {
    MessageBox.Show(String.Format(
    “{0} {1}”, customProp.Name, customProp.Value));
    }
    }
    VSTO:使用C#开发Excel、Word【15】 - 图2
    在DocumentProperties集合中访问DocumentProperty
    要访问DocumentProperties集合中的DocumentProperty,请使用C#索引语法docProperty [object],该对象返回一个DocumentProperty对象。索引器采用类型对象的Index参数。您可以传递一个int表示您要访问的集合中DocumentProperty的基于1的索引。或者,您可以传递一个表示您要访问的DocumentProperty的名称的字符串。与其他集合一样,Count属性返回集合中有多少DocumentProperty对象。
    DocumentProperty对象具有一个Name属性,它返回一个包含该属性名称的字符串。它还具有返回属性值的type对象的Value属性。您可以通过使用返回MsoDocProperties枚举成员的Type属性来检查该类型的值:msoPropertyTypeBoolean,msoPropertyTypeDate,msoPropertyTypeFloat,msoPropertyTypeNumber或msoPropertyTypeString。
    清单5-16显示了如何访问DocumentProperty。
    清单5-16 使用索引器访问DocumentProperty的VSTO自定义
    VSTO:使用C#开发Excel、Word【15】 - 图3
    private void ThisWorkbook_Startup(object sender, EventArgs e)
    {
    Office.DocumentProperties builtinProps = this.
    BuiltinDocumentProperties as Office.DocumentProperties;

    Office.DocumentProperty authorProp = builtinProps[“Author”];

    MessageBox.Show(String.Format(
    “Property {0} is {1}”, authorProp.Name, authorProp.Value));

    Office.DocumentProperty thirdProp = builtinProps[3];

    MessageBox.Show(String.Format(
    “Property {0} is {1}”, thirdProp.Name, thirdProp.Value));
    }
    VSTO:使用C#开发Excel、Word【15】 - 图4
    添加DocumentProperty
    您可以使用Add方法添加自定义DocumentProperty。 Add方法采用表5-10所示的参数。
    表5-10 DocumentProperties集合的添加方法的参数
    VSTO:使用C#开发Excel、Word【15】 - 图5
    清单5-17显示了添加msoPropertyTypeString类型的自定义DocumentProperty的示例。 请注意,Excel将允许您将该值设置为长字符串,但会将其截断为255个字符。 幸运的是,VSTO为开发人员提供了一种通过称为缓存数据的功能在文档中存储大量数据的方法。 有关VSTO的缓存数据功能的更多信息,请参见第18章“服务器数据方案”。
    清单5-17 添加自定义DocumentProperty的VSTO自定义
    VSTO:使用C#开发Excel、Word【15】 - 图6
    private void ThisWorkbook_Startup(object sender, EventArgs e)
    {
    Office.DocumentProperties props = this.
    CustomDocumentProperties as Office.DocumentProperties;

    Office.DocumentProperty prop = props.Add(“My Property”,
    false, Office.MsoDocProperties.msoPropertyTypeString,
    “My Value”, missing);

    MessageBox.Show(String.Format(
    “Property {0} has value {1}.”, prop.Name, prop.Value));
    }
    VSTO:使用C#开发Excel、Word【15】 - 图7
    使用Windows集合
    Application.Windows属性返回一个Windows集合,该集合允许您迭代和访问在Excel中打开的所有窗口。 同样,Workbook.Windows属性允许您访问与特定工作簿关联的窗口。 这些集合提供了安排打开窗口的方法。 Windows集合没有添加新窗口的方法。 而是必须调用Workbook.NewWindow方法。
    重复打开Windows
    Windows集合具有GetEnumerator方法,可以使用C#中的foreach关键字进行迭代,如清单5-18所示。
    清单5-18 VSTO定制在Windows集合中迭代
    VSTO:使用C#开发Excel、Word【15】 - 图8
    private void ThisWorkbook_Startup(object sender, EventArgs e)
    {
    Excel.Workbooks workbooks = this.Application.Workbooks;

    Excel.Workbook workbook1 = workbooks.Add(missing);
    Excel.Workbook workbook2 = workbooks.Add(missing);

    for (int i = 0; i < 10; i++)
    {
    workbook1.NewWindow();
    workbook2.NewWindow();
    }

    foreach (Excel.Window window in workbook1.Windows)
    {
    MessageBox.Show(String.Format(
    “Workbook1 Window: {0}”, window.Caption));
    }

    foreach (Excel.Window window in this.Application.Windows)
    {
    MessageBox.Show(String.Format(
    “Application Window: {0}”, window.Caption));
    }
    }
    VSTO:使用C#开发Excel、Word【15】 - 图9
    访问集合中的窗口
    要访问Windows集合中的窗口,可以使用一个名为get_Item的方法返回一个窗口。 get_Item方法使用类型为object的Index参数。 您可以传递一个表示Window标题的字符串,或者您可以将基于1的索引传递到Windows集合中。 您可以使用Count属性来检查给定集合中的多少项。 清单5-19显示了通过基于1的索引获取窗口并传递窗口的标题。
    清单5-19 使用get_Item从Windows集合获取窗口的VSTO自定义
    VSTO:使用C#开发Excel、Word【15】 - 图10
    private void ThisWorkbook_Startup(object sender, EventArgs e)
    {
    string caption = “”;
    Excel.Windows windows = this.Windows;

    if (windows.Count >= 1)
    {
    Excel.Window window = windows.get_Item(1);
    caption = window.Caption as string;
    MessageBox.Show(caption);
    }

    if (!String.IsNullOrEmpty(caption))
    {
    Excel.Window window2 = windows.get_Item(caption);
    string caption2 = window2.Caption as string;
    MessageBox.Show(caption2);
    }
    }
    VSTO:使用C#开发Excel、Word【15】 - 图11
    布局窗口
    Excel具有安排窗口和同步这些窗口的各种方法,以便当一个窗口滚动时,其他窗口也会滚动。 排列方法可以将窗口集合安排为平铺,水平,垂直或级联。 此方法还允许您同步显示相同工作簿的两个或多个窗口,以便在一个窗口滚动时,其他窗口滚动相同的数量。 表5-11显示了传递给排列方法的可选参数。
    表5-11 排列方法的可选参数
    VSTO:使用C#开发Excel、Word【15】 - 图12
    CompareSideBySideWith方法允许您同步两个窗口的滚动显示相同的工作簿或两个窗口显示不同的工作簿。此方法接受一个字符串,表示窗口的标题以与当前活动的窗口进行比较。您要与当前活动窗口进行比较的窗口必须是您正在使用的Windows集合的成员才能安全,因此应该使用Application.Windows集合,因为它包含所有打开的窗口。
    如清单5-20所示,重要的是激活要安排其窗口的工作簿。如果不这样做,将安排活动工作簿的窗口,而不是与Windows集合关联的工作簿。清单5-20还说明了Activate方法和Activate事件与Workbook对象冲突的问题。为了使编译器不要抱怨和IntelliSense工作,我们将Workbook转换为Excel._Workbook界面,让编译器知道我们想要的方法而不是事件。
    清单5-20 安排和同步Windows的VSTO定制

    VSTO:使用C#开发Excel、Word【15】 - 图13
    private void ThisWorkbook_Startup(object sender, EventArgs e)
    {
    Excel.Workbooks workbooks = this.Application.Workbooks;

    Excel.Workbook workbook1 = workbooks.Add(missing);
    Excel.Workbook workbook2 = workbooks.Add(missing);

    Excel.Window workbook1Window = workbook1.NewWindow();
    workbook2.NewWindow();

    ((Excel._Workbook)workbook1).Activate();

    workbook1.Windows.Arrange( Excel.XlArrangeStyle.xlArrangeStyleTiled, true, true, true);

    MessageBox.Show(String.Format( “Workbook {0} has its windows arranged tiled.”, workbook1.Name));

    ((Excel._Workbook)workbook2).Activate();

    this.Application.Windows.CompareSideBySideWith( workbook1Window.Caption);

    MessageBox.Show(String.Format( “The windows {0} and {1} are synchronized”, this.Application.ActiveWindow.Caption, workbook1Window.Caption));
    }
    VSTO:使用C#开发Excel、Word【15】 - 图14


    操作窗口对象
    Window对象表示一个Excel窗口。您可以使用Window对象来定位与工作簿关联的窗口。您还可以使用Window对象设置工作簿的显示设置,例如是否显示网格线和标题。
    定位窗口
    Window对象允许您定位和更改Excel在窗口中显示工作簿的方式。 Window具有XlWindowState类型的WindowState属性,可用于将窗口设置为xlMaximized,xlMinimized或xlNormal。
    当WindowState设置为xlNormal时,可以使用Left,Top,Width和Height属性来定位窗口。这些属性是表示点的双重值,而不是屏幕像素。您可以使用Window的PointsToScreenPixelsX和PointsToScreenPixelsY方法将点转换为像素。
    显示与窗口关联的设置
    许多其他属性允许您控制窗口的显示。表5-12列出了一些最常用的。
    表5-12 控制窗口显示的窗口属性
    VSTO:使用C#开发Excel、Word【15】 - 图15
    清单5-21显示了使用许多这些属性的示例。 请注意,我们添加对System.Drawing.dll的引用,以便我们可以使用ColorTranslator对象来设置GridlineColor属性。 ColorTranslator对象提供了一个名为ToOle的方法,该方法采用System.Drawing颜色,并将其转换为Ole颜色格式,即Office方法和属性所需的颜色格式。
    清单5-21 控制窗口显示选项的VSTO自定义
    VSTO:使用C#开发Excel、Word【15】 - 图16
    private void ThisWorkbook_Startup(object sender, EventArgs e)
    {
    Excel.Window win = this.NewWindow();

    win.WindowState = Excel.XlWindowState.xlNormal;
    win.Width = 200;
    win.Height = 200;
    win.Top = 8;
    win.Left = 8;
    win.DisplayGridlines = true;
    win.DisplayHeadings = false;
    win.DisplayHorizontalScrollBar = false;
    win.DisplayVerticalScrollBar = false;
    win.DisplayWorkbookTabs = false;
    win.EnableResize = false;

    win.GridlineColor = System.Drawing.ColorTranslator.
    ToOle(System.Drawing.Color.Blue);

    win.ScrollColumn = 10;
    win.ScrollRow = 20;
    win.Visible = true;
    win.Zoom = 150;
    }
    VSTO:使用C#开发Excel、Word【15】 - 图17


    使用名称集合和名称对象
    “名称”集合表示工作簿中已经给出名称的一组范围,以便可以通过公式中的名称或访问“名称”集合的代码访问该范围。 用户可以使用名称框创建和编辑名称,如图5-2所示,或者使用“插入”菜单中的“名称”菜单。 此外,名称有时由Excel的功能自动创建。 例如,当用户定义自定义打印区域时,Excel会创建名为Print_Area的命名范围。
    迭代名称集合
    Names集合有一个GetEnumerator方法,可以使用C#中的foreach关键字进行迭代。 例如,以下代码片段迭代与工作簿相关联的“Names”集合,并显示每个Name对象的名称以及以标准格式引用的范围的地址(例如“= Sheet1!$ A $ 5”)。
    foreach (Excel.Name name in workbook.Names)
    {
    Console.WriteLine(String.Format(
    “{0} refers to {1}”, name.Name, name.RefersTo));
    }
    访问名称集合中的名称
    要访问Names集合中的Name,您可以使用一个名为Item的方法,该方法具有三个可选参数,如表5-13所示。
    表5-13 Item方法的可选参数
    VSTO:使用C#开发Excel、Word【15】 - 图18
    清单5-22显示了一些创建名称的代码,然后以多种方式访问它。 它使用Add方法创建名称,该方法使用名称对象的名称和新创建的名称引用的标准格式地址字符串(例如“= Sheet1!$ A $ 5”)。
    清单5-22 创建名称对象并访问它的VSTO自定义

    VSTO:使用C#开发Excel、Word【15】 - 图19
    private void ThisWorkbook_Startup(object sender, EventArgs e)
    {
    Excel.Names names = this.Names;

    names.Add(“MyName”, “=Sheet1!$A$5”, missing, missing,
    missing, missing, missing, missing, missing,
    missing, missing);

    Excel.Name name1 = names.Item(missing, missing,
    “=Sheet1!$A$5”);

    MessageBox.Show(String.Format(
    “Name: {0} RefersTo: {1} RefersToR1C1: {2} Count: {3}”,
    name1.Name, name1.RefersTo, name1.RefersToR1C1,
    name1.RefersToRange.Cells.Count));

    Excel.Name name2 = names.Item(“MyName”, missing, missing);

    MessageBox.Show(String.Format(
    “Name: {0} RefersTo: {1} RefersToR1C1: {2} Count: {3}”,
    name2.Name, name2.RefersTo, name2.RefersToR1C1,
    name2.RefersToRange.Cells.Count));
    }
    VSTO:使用C#开发Excel、Word【15】 - 图20
    名称对象
    给定一个Name对象,你通常会使用几个属性。 名称返回名称作为字符串。 RefersTo属性返回标准格式地址作为名称引用的字符串。 RefersToR1C1返回“行和列”格式地址作为名称引用的字符串(如“= Sheet1!R26C9”)。 最重要的是,RefersToRange属性返回一个表示名称分配给的单元格范围的Excel范围对象。
    要从“定义名称”对话框和“名称框”下拉列表中隐藏名称,可以将Visible属性设置为false。 要删除名称,请使用删除方法。