演练:在运行时更新功能区上的控件

本演练演示如何在功能区加载到 办公室 应用程序中后,使用功能区对象模型更新功能区上的控件。

适用于: 本主题中的信息适用于以下应用程序的文档级项目和 VSTO 外接程序项目: Excel;InfoPath 2013 和 InfoPath 2010;前景;幻灯片;项目;Visio;词。 有关详细信息,请参阅办公室应用程序和项目类型提供的功能。

此示例提取来自 Northwind 示例数据库的数据,以填充 Microsoft Office Outlook 中的组合框和菜单。 在这些控件中选择的项目会自动填充电子邮件中的“收件人”和“主题”字段。

本演练阐释了以下任务:

  • 创建新的 Outlook VSTO 外接程序项目。

  • 设计自定义功能区组。

  • 将自定义组添加到内置选项卡。

  • 在运行时更新功能区上的控件。

注意

以下说明中的某些 Visual Studio 用户界面元素在计算机上出现的名称或位置可能会不同。 这些元素取决于你所使用的 Visual Studio 版本和你所使用的设置。 有关详细信息,请参阅个性化设置 Visual Studio IDE

先决条件

你需要满足以下条件才能完成本演练:

创建新的 Outlook VSTO 外接程序项目

首先,创建 Outlook VSTO 外接程序项目。

创建新的 Outlook VSTO 外接程序项目

  1. 在 Visual Studio 中,使用名称 Ribbon_Update_At_Runtime创建 Outlook VSTO 外接程序项目。

  2. “新建项目” 对话框中,选择 “创建解决方案的目录”

  3. 将项目保存到默认项目目录中。

    有关详细信息,请参阅“如何:在 Visual Studio 中创建办公室项目。

设计自定义功能区组

当用户撰写新邮件时,将显示此示例的功能区。 若要为功能区创建自定义组,请先向项目添加功能区项,然后在功能区设计器中设计该组。 此自定义组通过从数据库拉取名称和订单历史记录,帮助你生成客户的后续电子邮件。

设计自定义组

  1. “项目” 菜单上,单击 “添加新项”

  2. “添加新项” 对话框中,选择 “功能区(可视化设计器)”

  3. 将新功能区的名称更改为 CustomerRibbon,然后单击“ 添加”。

    CustomerRibbon.csCustomerRibbon.vb 文件将在功能区设计器中打开,并显示默认选项卡和组。

  4. 单击功能区设计器以将其选定。

  5. “属性”窗口中,单击 RibbonType 属性旁边的下拉箭头,然后单击 Microsoft.Outlook.Mail.Compose

    这允许用户在 Outlook 中撰写新邮件时显示功能区。

  6. 在功能区设计器中,单击“Group1将其选中。

  7. “属性”窗口中,将“标签”设置为“客户购买”。

  8. 从工具箱“办公室功能区控件”选项卡中,将 ComboBox“客户购买”组中。

  9. 单击 ComboBox1 将其选中。

  10. “属性”窗口中,将“标签”设置为“客户”。

  11. 在工具箱“办公室功能区控件”选项卡中,将菜单拖到“客户购买”组中。

  12. “属性”窗口中,将“标签”设置为“购买的产品”。

  13. 将“动态”设置为 true

    这使你可以在功能区加载到办公室应用程序后,在运行时在菜单上添加和删除控件。

将自定义组添加到内置选项卡

内置选项卡是已在 Outlook 资源管理器或检查器功能区上的选项卡。 在此过程中,将自定义组添加到内置选项卡,然后指定自定义组在选项卡上的位置。

将自定义组添加到内置选项卡

  1. 单击 TabAddins (内置) 选项卡以将其选中。

  2. “属性”窗口中,展开 ControlId 属性,然后将 办公室Id 设置为 TabNewMailMessage

    这会将 “客户购买 ”组添加到 新邮件中显示的功能区“邮件 ”选项卡。

  3. 单击“客户购买”组以将其选中。

  4. “属性”窗口中,展开“位置”属性,单击 PositionType 属性旁边的下拉箭头,然后单击“Before办公室Id”。

  5. 办公室Id 属性设置为 GroupClipboard

    这会将“客户购买”组置于“消息”选项卡的剪贴板组之前

创建数据源

使用 “数据源” 窗口将类型化数据集添加到项目中。

创建数据源

  1. “数据” 菜单上,单击 “添加新数据源”

    这会启动 数据源配置向导

  2. 选择“ 数据库”,然后单击“ 下一步”。

  3. 选择“数据集”,然后单击“下一步”。

  4. 选择与 Northwind 示例 Microsoft SQL Server Compact 4.0 数据库的数据连接,或使用“新建连接”按钮添加新连接

  5. 选择或创建连接后,单击“ 下一步”。

  6. 单击“下一步保存连接字符串。

  7. 在“ 选择数据库对象 ”页上,展开 “表”。

  8. 选中以下每个表格旁的复选框:

    1. 客户

    2. 订单详细信息

    3. 订单

    4. 产品

  9. 单击“完成” 。

在运行时更新自定义组中的控件

使用功能区对象模型执行以下任务:

  • 将客户名称添加到 “客户 ”组合框。

  • 将菜单和按钮控件添加到 表示销售订单和销售产品的产品的“已购买 ”菜单。

  • 使用“客户”组合框和“产品购买”菜单中的数据填充新邮件的“发件人”、“主题”和“正文”字段。

使用功能区对象模型更新自定义组中的控件

  1. 在“项目”菜单上,单击“添加引用” 。

  2. “添加引用 ”对话框中,单击 “.NET ”选项卡,选择 System.Data.Linq 程序集,然后单击“ 确定”。

    此程序集包含有关使用语言集成查询 (LINQ) 的类。 你将通过 LINQ 使用 Northwind 数据库中的数据填充自定义组中的控件。

  3. 解决方案资源管理器中,单击 CustomerRibbon.csCustomerRibbon.vb 将其选中。

  4. “视图” 菜单上,单击 “代码”

    功能区代码文件将在代码编辑器中打开。

  5. 将下面的语句添加到功能区代码文件的顶部。 通过执行这些语句,可轻松访问 LINQ 命名空间和 Outlook 主互操作程序集 (PIA) 的命名空间。

    using System.Data.Linq;
    using System.Data.Linq.Mapping;
    using System.Linq.Expressions;
    using Outlook = Microsoft.Office.Interop.Outlook;
    using System.Data;
    using System.IO;
    using Ribbon_Update_At_Runtime.Northwind40DataSetTableAdapters;
    
  6. 在类中添加 CustomerRibbon 以下代码。 此代码声明了将用于存储 Northwind 数据库的“客户”、“订单”、“订单明细”和“产品”表中信息的数据表和表适配器。

    //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();
    
  7. 将以下代码块添加到 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;
    }
    
  8. 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();
      }
      

  9. 将以下代码添加到 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);
              }
          }
      }
      

  10. 解决方案资源管理器中,双击功能区代码文件。

    功能区设计器随即打开。

  11. 在功能区设计器中,双击 “客户 ”组合框。

    功能区代码文件将在代码编辑器中打开,并且将显示 ComboBox1_TextChanged 事件处理程序。

  12. ComboBox1_TextChanged 事件处理程序替换为以下代码。 此代码执行以下任务:

    • 调用 PopulateSalesOrderInfo 帮助程序方法。 此方法使用 与所选客户相关的销售订单更新“购买 的产品”菜单。

    • 调用 PopulateMailItem 帮助程序方法并传入当前文本,该文本是所选客户名称。 此方法填充新邮件的“To”、“主题”和“正文”字段。

      private void comboBox1_TextChanged(object sender,
          RibbonControlEventArgs e)
      {
          PopulateSalesOrderInfo();
          PopulateMailItem(comboBox1.Text);
      }
      

  13. 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;
    }
    
  14. 将以下代码添加到 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 数据库中的数据进行更新。

测试自定义组中的控件

  1. F5 运行项目。

    Outlook 启动。

  2. 在 Outlook 的“文件”菜单上,指向“新建”,然后单击“邮件”。

    将出现以下操作:

    • 出现新的邮件消息检查器窗口。

    • 功能区的“消息”选项卡上,“客户购买”组显示在剪贴板组之前

    • 组中的 “客户 ”组合框使用 Northwind 数据库中的客户名称进行更新。

  3. 功能区的“消息 ”选项卡上的 “客户购买 ”组中,从 “客户”组合框中选择一个客户

    将出现以下操作:

    • 购买 的产品”菜单已更新,以显示所选客户的每个销售订单。

    • 每笔销售订单子菜单进行更新,以显示该笔订单中购买的产品。

    • 所选客户的电子邮件地址将添加到邮件的“收件人行,邮件的主题和正文填充有文本。

  4. 单击“产品购买”菜单,指向任何销售订单,然后单击销售订单中的产品。

    该产品名称将添加到邮件消息的正文中。

后续步骤

可从以下主题了解有关如何自定义 Office 用户界面的更多信息: