本演练演示如何在功能区加载到 Office 应用程序中后,使用功能区对象模型更新功能区上的控件。
适用于: 本主题中的信息适用于以下应用程序的文档级项目和 VSTO 外接程序项目:Excel、InfoPath 2013 和 InfoPath 2010、Outlook、PowerPoint、Project、Visio、Word。 有关详细信息,请参阅 Office 应用程序和项目类型提供的功能。
该示例从 Northwind 示例数据库拉取数据,以在 Microsoft Office Outlook 中填充组合框和菜单。 在这些控件中选择的项目会自动填充电子邮件中的 “收件人 ”和 “主题” 等字段。
本演练阐释了以下任务:
创建新的 Outlook VSTO 外接程序项目。
设计自定义功能区组。
将自定义组添加到内置选项卡。
在运行时更新功能区上的控件。
注释
以下说明中的某些 Visual Studio 用户界面元素在计算机上出现的名称或位置可能会不同。 这些元素取决于你所使用的 Visual Studio 版本和你所使用的设置。 有关详细信息,请参阅个性化设置 Visual Studio IDE。
先决条件
你需要满足以下条件才能完成本演练:
包含 Microsoft Office 开发人员工具的 Visual Studio 版本。 有关详细信息,请参阅 配置计算机以开发 Office 解决方案。
Microsoft Outlook
创建新的 Outlook VSTO 外接程序项目
首先,创建 Outlook VSTO 外接程序项目。
创建新的 Outlook VSTO 外接程序项目
在 Visual Studio 中,使用名称 Ribbon_Update_At_Runtime创建 Outlook VSTO 外接程序项目。
在“ 新建项目 ”对话框中, 选择“为解决方案创建目录”。
将项目保存到默认项目目录。
有关详细信息,请参阅 如何:在 Visual Studio 中创建 Office 项目。
设计自定义功能区组
当用户撰写新邮件时,将显示此示例的功能区。 若要为功能区创建自定义组,请先向项目添加功能区项,然后在功能区设计器中设计该组。 此自定义组通过从数据库拉取名称和订单历史记录,帮助你生成客户的后续电子邮件。
设计自定义组
在 “项目 ”菜单上,单击“ 添加新项”。
在添加新项对话框中,选择功能区(可视化设计器)。
将新功能区的名称更改为 CustomerRibbon,然后单击“ 添加”。
CustomerRibbon.cs或CustomerRibbon.vb文件将在功能区设计器中打开,并显示默认选项卡和组。
单击功能区设计器以选择它。
在 “属性 ”窗口中,单击 RibbonType 属性旁边的下拉箭头,然后单击 Microsoft.Outlook.Mail.Compose。
这允许用户在 Outlook 中撰写新邮件时显示功能区。
在功能区设计器中,单击 “Group1 ”将其选中。
在 “属性” 窗口中,将 “标签 ”设置为 “客户购买”。
从工具箱的“Office 功能区控件”选项卡中,将 ComboBox 拖到“客户购买”组中。
单击 ComboBox1 将其选中。
在 “属性” 窗口中,将 “标签 ”设置为 “客户”。
从工具箱的“Office 功能区控件”选项卡中,将菜单拖到“客户购买”组中。
在 “属性” 窗口中,将 “标签 ”设置为 “购买的产品”。
将 “动态 ”设置为 true。
这使你可以在功能区加载到 Office 应用程序后,在运行时动态地在菜单上添加和删除控件。
将自定义组添加到内置选项卡
内置选项卡是已在 Outlook 资源管理器或检查器功能区上的选项卡。 在此过程中,将自定义组添加到内置选项卡,然后指定自定义组在选项卡上的位置。
将自定义组添加到内置选项卡
单击 TabAddins (Built-In) 选项卡将其选中。
在 “属性” 窗口中,展开 ControlId 属性,然后将 OfficeId 设置为 TabNewMailMessage。
这会将客户购买组添加到新邮件中显示的功能区的消息选项卡。
单击“ 客户购买 ”组以将其选中。
在 “属性” 窗口中,展开 “位置 ”属性,单击 PositionType 属性旁边的下拉箭头,然后单击 BeforeOfficeId。
将 OfficeId 属性设置为 GroupClipboard。
这会将“客户购买”组置于“消息”选项卡的剪贴板组之前。
创建数据源
使用 “数据源 ”窗口向项目添加类型化数据集。
创建数据源
在 “数据 ”菜单上,单击“ 添加新数据源”。
这会启动 数据源配置向导。
选择 “数据库”,然后单击“ 下一步”。
选择 “数据集”,然后单击“ 下一步”。
选择与 Northwind 示例Microsoft SQL Server Compact 4.0 数据库的数据连接,或使用 “新建连接 ”按钮添加新连接。
选择或创建连接后,单击“ 下一步”。
单击“ 下一步 ”保存连接字符串。
在“ 选择数据库对象 ”页上,展开 “表”。
选中下表旁边的复选框:
客户
订单详细信息
订单
产品
单击“完成”。
在运行时更新自定义组中的控件
使用功能区对象模型执行以下任务:
将客户名称添加到 “客户 ”组合框。
将菜单控件和按钮控件添加到“已购买产品”菜单,以表示销售订单和所售产品。
使用 “客户 ”组合框和 “产品购买 ”菜单中的数据填充新邮件的“发件人”、“主题”和“正文”字段。
使用 Ribbon 对象模型更新自定义组中的控件
在 “项目 ”菜单上,单击“ 添加引用”。
在“ 添加引用 ”对话框中,单击 “.NET ”选项卡,选择 System.Data.Linq 程序集,然后单击“ 确定”。
此程序集包含用于使用 Language-Integrated Query (LINQ) 的类。 将使用 LINQ 使用 Northwind 数据库中的数据填充自定义组中的控件。
在 解决方案资源管理器中,单击 CustomerRibbon.cs 或 CustomerRibbon.vb 将其选中。
在 “视图 ”菜单上,单击“ 代码”。
功能区代码文件将会在代码编辑器中打开。
将以下语句添加到 Ribbon 代码文件的顶部。 这些语句可以轻松访问 LINQ 命名空间和 Outlook 主互作程序集(PIA)的命名空间。
在类中添加
CustomerRibbon以下代码。 此代码声明用于存储 Northwind 数据库的 Customer、Orders、Order Details 和 Product 表中的信息的数据表和表适配器。//Declare the Northwind dataset. Northwind40DataSet nwDataSet = new Northwind40DataSet(); //Declare the data tables. Northwind40DataSet.CustomersDataTable customerTable; Northwind40DataSet.OrdersDataTable orderTable; Northwind40DataSet.Order_DetailsDataTable orderDetailsTable; Northwind40DataSet.ProductsDataTable productsTable; //Declare the data table adapters for each table. CustomersTableAdapter customerTableAdapter = new CustomersTableAdapter(); OrdersTableAdapter ordersTableAdapter = new OrdersTableAdapter(); Order_DetailsTableAdapter detailsTableAdapter = new Order_DetailsTableAdapter(); ProductsTableAdapter productsTableAdapter = new ProductsTableAdapter();将以下代码块添加到
CustomerRibbon类。 此代码添加了三种帮助程序方法,用于在运行时为功能区创建控件。private RibbonDropDownItem CreateRibbonDropDownItem() { return this.Factory.CreateRibbonDropDownItem(); } private RibbonMenu CreateRibbonMenu() { return this.Factory.CreateRibbonMenu(); } private RibbonButton CreateRibbonButton() { RibbonButton button = this.Factory.CreateRibbonButton(); button.Click += new RibbonControlEventHandler(button_Click); return button; }将
CustomerRibbon_Load事件处理程序方法替换为以下代码。 此代码使用 LINQ 查询执行以下任务:使用 Northwind 数据库中 20 个客户的 ID 和名称填充 Customers 组合框。
调用
PopulateSalesOrderInfo辅助方法。 此方法使用与当前所选客户相关的销售订单号更新 ProductsPurchased 菜单。private void CustomerRibbon_Load(object sender, RibbonUIEventArgs e) { customerTable = nwDataSet.Customers; customerTableAdapter.Fill(customerTable); var customerQuery = from customers in customerTable.AsEnumerable().Take(20) select new { CustomerID = customers.Field<string>("Customer ID"), CustomerName = customers.Field<string>("Contact Name") }; // Execute the query. foreach (var item in customerQuery) { this.comboBox1.Items.Add(CreateRibbonDropDownItem()); this.comboBox1.Items.Last().Label = item.CustomerName + "|" + item.CustomerID.ToString(); } this.comboBox1.Text = this.comboBox1.Items.First().Label; PopulateSalesOrderInfo(); }
将以下代码添加到
CustomerRibbon类。 此代码使用 LINQ 查询执行以下任务:将子菜单添加到与所选客户相关的每个销售订单的 ProductsPurchased 菜单。
将按钮添加到与销售订单相关的产品的每个子菜单。
将事件处理程序添加到每个按钮。
private void PopulateSalesOrderInfo() { String[] tempArray = comboBox1.Text.Split(new Char[] { '|' }); menu1.Items.Clear(); orderTable = nwDataSet.Orders; orderDetailsTable = nwDataSet.Order_Details; productsTable = nwDataSet.Products; ordersTableAdapter.Fill(orderTable); detailsTableAdapter.Fill(orderDetailsTable); productsTableAdapter.Fill(productsTable); var orderQuery = from orders in orderTable.AsEnumerable() where orders.Field<string>("Customer ID") == tempArray[1] select new { OrderID = orders.Field<int>("Order ID") }; foreach (var orderItem in orderQuery) { menu1.Items.Add(CreateRibbonMenu()); RibbonMenu orderMenu = (RibbonMenu)menu1.Items.Last(); orderMenu.Dynamic = true; orderMenu.Label = orderItem.OrderID.ToString(); orderMenu.Tag = orderItem.OrderID; var productQuery = from orderDetail in orderDetailsTable.AsEnumerable() join product in productsTable.AsEnumerable() on orderDetail.Field<int>("Product ID") equals product.Field<int>("Product ID") where orderDetail.Field<int>("Order ID") == orderItem.OrderID select new { ProductName = product.Field<string>("Product Name") }; foreach (var productItem in productQuery) { RibbonButton button = CreateRibbonButton(); button.Label = productItem.ProductName; orderMenu.Items.Add(button); } } }
在 解决方案资源管理器中,双击功能区代码文件。
功能区设计器已打开。
在功能区设计器中,双击 “客户” 组合框。
功能区代码文件在代码编辑器中打开,随后事件处理程序
ComboBox1_TextChanged出现。将
ComboBox1_TextChanged事件处理程序替换为以下代码。 此代码执行以下任务:调用
PopulateSalesOrderInfo辅助方法。 使用此方法可将与所选客户相关的销售订单更新至 “购买的产品” 菜单。调用
PopulateMailItem帮助程序方法,并将当前文本(即所选客户名称)传入。 此方法填充新邮件的“To”、“主题”和“正文”字段。
将以下
Click事件处理程序添加到CustomerRibbon类。 此代码将所选产品的名称添加到新邮件的“正文”字段中。void button_Click(object sender, RibbonControlEventArgs e) { Outlook.Application application = Globals.ThisAddIn.Application; Outlook.Inspector inspector = application.ActiveInspector(); Outlook.MailItem myMailItem = (Outlook.MailItem)inspector.CurrentItem; RibbonButton myCheckBox = (RibbonButton)sender; myMailItem.Subject = "Following up on your order"; myMailItem.Body = myMailItem.Body + "\n" + "* " + myCheckBox.Label; }将以下代码添加到
CustomerRibbon类。 此代码执行以下任务:使用当前所选客户的电子邮件地址填充新邮件的“到”行。
将文本添加到新邮件的“主题”和“正文”字段。
private void PopulateMailItem(string addressToLine) { Outlook.Application application = Globals.ThisAddIn.Application; Outlook.Inspector inspector = application.ActiveInspector(); Outlook.MailItem myMailItem = (Outlook.MailItem)inspector.CurrentItem; myMailItem.To = ""; String[] tempArray = addressToLine.Split(new Char[] { '|' }); myMailItem.To = tempArray[0] + "@example.com"; myMailItem.Subject = "Following up on your order"; myMailItem.Body = "Hello " + tempArray[0] + "," + "\n" + "We would like to get your feedback on the " + "following products that you recently ordered: "; }
测试自定义组中的控件
在 Outlook 中打开新邮件窗体时,功能区“邮件”选项卡上会显示一个名为“客户购买”的自定义组。
若要创建客户跟进电子邮件,请选择客户,然后选择客户购买的产品。 客户购买组中的控件在运行时使用 Northwind 数据库中的数据进行更新。
测试自定义组中的控件
按 F5 运行项目。
Outlook 将启动。
在 Outlook 的“文件”菜单上,指向“新建”,然后单击“邮件”。
将出现以下操作:
此时会显示一个新的邮件检查器窗口。
在功能区的“ 消息 ”选项卡上, “客户购买 ”组显示在 剪贴板 组之前。
组中的 “客户 ”组合框使用 Northwind 数据库中的客户名称进行更新。
在功能区的“ 消息 ”选项卡上的“ 客户购买 ”组中,从 “客户 ”组合框中选择一个客户。
将出现以下操作:
“ 购买的产品 ”菜单已更新,以显示所选客户的每个销售订单。
将更新每个销售订单子菜单以显示按该订单购买的产品。
所选客户的电子邮件地址将添加到邮件的 “收件人 ”行,邮件的主题和正文填充有文本。
单击“ 产品购买 ”菜单,指向任何销售订单,然后单击销售订单中的产品。
产品名称将添加到邮件正文中。
后续步骤
可以详细了解如何从以下主题自定义 Office UI:
将基于上下文的用户界面添加到任何文档级别的自定义功能中。 有关详细信息,请参阅 “操作窗格概述”。
扩展标准或自定义Microsoft Office Outlook 窗体。 有关详细信息,请参阅 演练:设计 Outlook 窗体区域。
将自定义任务窗格添加到 Outlook。 有关详细信息,请参阅 “自定义任务”窗格。