可以使用 Excel VSTO 外接程序将控件添加到任何打开的工作表。 本演练演示了如何使用功能区,使用户能够向工作表添加Button、NamedRange和ListObject。 有关信息,请参阅 在运行时向 Office 文档添加控件。
适用于: 本主题中的信息适用于 Excel 的 VSTO 外接程序项目。 有关详细信息,请参阅 Office 应用程序和项目类型提供的功能。
本演练阐释了以下任务:
- 提供用于向工作表添加控件的用户界面(UI)。 
- 向工作表添加控件。 
- 从工作表中删除控件。 - 注释 - 以下说明中的某些 Visual Studio 用户界面元素在计算机上出现的名称或位置可能会不同。 这些元素取决于你所使用的 Visual Studio 版本和你所使用的设置。 有关详细信息,请参阅 个性化设置 IDE。 
先决条件
你需要满足以下条件才能完成本演练:
- 包含 Microsoft Office 开发人员工具的 Visual Studio 版本。 有关详细信息,请参阅 配置计算机以开发 Office 解决方案。 
- Excel 
创建新的 Excel VSTO 外接程序项目
首先创建 Excel VSTO 外接程序项目。
创建新的 Excel VSTO 外接程序项目
- 在 Visual Studio 中,创建名为 ExcelDynamicControls 的 Excel VSTO 外接程序项目。 有关详细信息,请参阅 如何:在 Visual Studio 中创建 Office 项目。 
- 添加对 Microsoft.Office.Tools.Excel.v4.0.Utilities.dll 程序集的引用。 本演练中,稍后需要此引用以编程方式将 Windows 窗体控件添加到工作表中。 
提供用于向工作表添加控件的 UI
将自定义选项卡添加到 Excel 功能区。 用户可以在选项卡上选中复选框,将控件添加到工作表。
提供用于向工作表添加控件的 UI
- 在 “项目 ”菜单上,单击“ 添加新项”。 
- 在添加新项 对话框中,选择功能区(Visual Designer),然后单击添加。 - 名为 Ribbon1.cs 或 Ribbon1.vb 的文件将在功能区设计器中打开,并显示默认选项卡和组。 
- 从工具箱的 Office 功能区控件选项卡中,将 CheckBox 控件拖动到 group1 上。 
- 单击 CheckBox1 将其选中。 
- 在 “属性” 窗口中,更改以下属性。 - 资产 - 价值 - 名称 - 按钮 - 标签 - 按钮 
- 将第二个复选框添加到 group1,然后更改以下属性。 - 资产 - 价值 - 名称 - NamedRange - 标签 - NamedRange 
- 将第三个复选框添加到 group1,然后更改以下属性。 - 资产 - 价值 - 名称 - ListObject - 标签 - ListObject 
向工作表添加控件
只能将托管控件添加到充当容器的宿主项。 由于 VSTO 外接程序项目适用于任何打开的工作簿,因此 VSTO 外接程序在添加控件之前将工作表转换为宿主项,或获取现有宿主项。 将代码添加到每个控件的单击事件处理程序,以在打开的工作表基础上生成 Worksheet 主机项。 然后,在工作表中的当前选定内容中添加 a Button、a NamedRange和 a ListObject 。
向工作表添加控件
- 在功能区设计器中,双击 “按钮”。 - “ClickButton复选框的事件处理程序在代码编辑器中打开。” 
- 将 - Button_Click事件处理程序替换为以下代码。- 此代码使用 - GetVstoObject方法获取表示工作簿中第一个工作表的宿主对象,并将控件添加到当前选定的单元格 Button。- private void Button_Click(object sender, RibbonControlEventArgs e) { Worksheet worksheet = Globals.Factory.GetVstoObject( Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets[1]); string buttonName = "MyButton"; if (((RibbonCheckBox)sender).Checked) { Excel.Range selection = Globals.ThisAddIn.Application.Selection as Excel.Range; if (selection != null) { Microsoft.Office.Tools.Excel.Controls.Button button = new Microsoft.Office.Tools.Excel.Controls.Button(); worksheet.Controls.AddControl(button, selection, buttonName); } } else { worksheet.Controls.Remove(buttonName); } }
- 在 解决方案资源管理器中,选择 Ribbon1.cs 或 Ribbon1.vb。 
- 在 “视图 ”菜单上,单击“ 设计器”。 
- 在功能区设计器中,双击 NamedRange。 
- 将 - NamedRange_Click事件处理程序替换为以下代码。- 此代码使用 - GetVstoObject此方法获取表示工作簿中第一个工作表的宿主项,然后为当前选定的单元格或单元格定义控件 NamedRange 。- private void NamedRange_Click(object sender, RibbonControlEventArgs e) { Worksheet worksheet = Globals.Factory.GetVstoObject( Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets[1]); string Name = "MyNamedRange"; if (((RibbonCheckBox)sender).Checked) { Excel.Range selection = Globals.ThisAddIn.Application.Selection as Excel.Range; if (selection != null) { worksheet.Controls.AddNamedRange(selection, Name); } } else { worksheet.Controls.Remove(Name); } }
- 在功能区设计器中,双击 ListObject。 
- 将 - ListObject_Click事件处理程序替换为以下代码。- 此代码使用 - GetVstoObject方法来获取表示工作簿中第一个工作表的宿主项,然后为当前选定的单元格或单元格定义一个 ListObject。- private void ListObject_Click(object sender, RibbonControlEventArgs e) { Worksheet worksheet = Globals.Factory.GetVstoObject( Globals.ThisAddIn.Application.ActiveWorkbook.Worksheets[1]); string listObjectName = "MyListObject"; if (((RibbonCheckBox)sender).Checked) { Excel.Range selection = Globals.ThisAddIn.Application.Selection as Excel.Range; if (selection != null) { worksheet.Controls.AddListObject(selection, listObjectName); } } else { worksheet.Controls.Remove(listObjectName); } }
- 将以下语句添加到 Ribbon 代码文件的顶部。 
从工作表中删除控件
保存和关闭工作表时不会保留控件。 在保存工作表之前,应以编程方式删除所有生成的 Windows 窗体控件,或者在再次打开工作簿时仅显示控件的大纲。 将代码添加到WorkbookBeforeSave事件以移除生成的宿主项的控件集合中的Windows窗体控件。 有关详细信息,请参阅 在 Office 文档中持久保存动态控件。
从工作表中删除控件
- 在 解决方案资源管理器中,选择 ThisAddIn.cs 或 ThisAddIn.vb。 
- 在 “视图 ”菜单上,单击“ 代码”。 
- 将以下方法添加到 - ThisAddIn类。 此代码获取工作簿中的第一个工作表,然后使用- HasVstoObject该方法检查工作表是否具有生成的工作表对象。 如果生成的工作表对象具有控件,则代码将获取该工作表对象并循环访问控件集合,删除控件。- void Application_WorkbookBeforeSave(Microsoft.Office.Interop.Excel.Workbook workbook, bool SaveAsUI, ref bool Cancel) { Excel.Worksheet worksheet = workbook.Worksheets[1] as Excel.Worksheet; if (Globals.Factory.HasVstoObject(worksheet) && Globals.Factory.GetVstoObject(worksheet).Controls.Count > 0) { Worksheet vstoWorksheet = Globals.Factory.GetVstoObject(worksheet); while (vstoWorksheet.Controls.Count > 0) { object vstoControl = vstoWorksheet.Controls[0]; vstoWorksheet.Controls.Remove(vstoControl); } } }
- 在 C# 中,必须为该 WorkbookBeforeSave 事件创建事件处理程序。 可以将此代码置于方法中 - ThisAddIn_Startup。 有关创建事件处理程序的详细信息,请参阅 如何:在 Office 项目中创建事件处理程序。 将- ThisAddIn_Startup方法替换为以下代码。- private void ThisAddIn_Startup(object sender, System.EventArgs e) { this.Application.WorkbookBeforeSave += new Microsoft.Office.Interop.Excel.AppEvents_WorkbookBeforeSaveEventHandler (Application_WorkbookBeforeSave); }
测试解决方案
通过从功能区上的自定义选项卡中选择控件,将控件添加到工作表。 保存工作表时,将删除这些控件。
测试解决方案。
- 按 F5 运行项目。 
- 选择 Sheet1 中的任何单元格。 
- 单击“ 加载项 ”选项卡。 
- 在 group1 组中,单击 “按钮”。 - 按钮显示在所选单元格中。 
- 在 Sheet1 中选择其他单元格。 
- 在 group1 组中,单击 NamedRange。 - 为所选单元格定义命名区域。 
- 在 Sheet1 中选择一系列单元格。 
- 在 group1 组中,单击 ListObject。 - 为所选单元格添加列表对象。 
- 保存工作表。 - 添加到 Sheet1 的控件不再显示。 
后续步骤
可以从本主题详细了解 Excel VSTO 外接程序项目中的控件:
- 若要了解如何将控件保存到工作表,请参阅 Office 开发示例和演练中的 Excel VSTO 外接程序动态控件示例。