Using the Business Data Catalog and Smart Tags with the 2007 Microsoft Office System

Summary: Learn how to build custom applications that use the business data catalog and smart tags.

Scot Hillier, Microsoft MVP

Bhushan Nene, Microsoft Corporation

July 2007

Applies to: 2007 Microsoft Office System, Microsoft Office SharePoint Server 2007, Microsoft Windows SharePoint Services 3.0.

Download the code sample that accompanies this article.

Using Business Data in Office Documents

All organizations maintain data inside distinct line-of-business (LOB) systems that are required to support business processes. This data may be contained within a customer relationship management (CRM) system, an accounting system, an employee information system, or other similar systems. Typically, this information is accessed solely through a user interface that is an integral part of the LOB system and is not integrated with other systems. Furthermore, these user interfaces are often complicated and require significant training. As a result, only a few users within the organization ever master the interface, which makes it difficult for others to use the organizational knowledge contained within the system. Over the past couple of decades, vendors and customers developed many solutions to integrate these systems with existing business processes to make information more generally available. For many organizations, however, the goal of integration remains elusive. It is often still difficult to gain access to the information necessary to support daily business processes.

This technical article presents a solution that integrates LOB data with the 2007 Microsoft Office system to support the preparation of documents within Microsoft Office Word 2007. The solution presented uses product information contained within a Microsoft SQL Server 2005 database to support the creation of a quote sheet. In this scenario, a manufacturing sales representative uses a solution based on Office Word 2007, Microsoft Visual Studio 2005 Tools for Office Second Edition, and the business data catalog feature of Microsoft Office SharePoint Server 2007 Enterprise Edition to access product information and create a new quote sheet. The solution allows the sales representative to easily browse product information from within Word 2007 and insert the information into a quote document template. Furthermore, the solution uses smart tags to identify product numbers within the quote and display detailed information contained in the business data catalog through Office SharePoint Server 2007. Figure 1 shows a typical quote sheet being prepared by selecting business data catalog product data from a custom task pane in Word 2007.

Figure 1. The Quote Sheet solution

The Quote Sheet solution

The Business Data Catalog

The heart of the quoting solution is the business data catalog feature found in the enterprise version of Office SharePoint Server 2007. The business data catalog exposes data in LOB systems and makes them available as data sources for use by Web Parts, user profiles, list columns, Search Center, and your own custom applications. The quoting solution is an example of a custom application making use of business data catalog data.

The business data catalog makes use of standard classes in the Microsoft .NET Framework to interface with LOB systems. The business data catalog can connect with OLEDB and ODBC data sources using an ADO.NET interface or to any other data source using a SOAP interface. In the quoting solution, the business data catalog is connecting to the AdventureWorks sample database through its ADO.NET interface.

Developers determine what data is returned from the targeted LOB systems by creating a specialized XML file known as an application definition file. An application definition contains all of the information necessary for the business data catalog to establish a connection with the target data source and retrieve the requested data.

The application definition specifies what data to return by modeling the business entities contained in the target data source. In the quoting solution, a single business entity named Product is defined. The application definition describes the entity and the data to return as properties and methods. You can think of the entity as a class that defines the structure of the data you want returned from a LOB system. Figure 2 shows a conceptual diagram reflecting the relationships between the business entity, business data catalog, and the SQL Server data source.

Figure 2. The Product Entity in an appication definition

The Product Entity in an appication definition

The Application Definition

Application definitions are XML files that define the required data connection and business entities to retrieve desired data. Application definitions can be challenging to create because of the many elements required. After you create more than one, however, you find that the process is largely the same each time. Application definitions follow a schema defined in the file, BDCMetaData.xsd, which you can use to help create the XML. This file is located in Program Files\Microsoft Office Servers\12.0\Bin, and referring to it from Visual Studio provides you with IntelliSense help while writing the application definition.

The quoting solution uses an application definition to connect to the AdventureWorks database and return product information. The complete application definition is available with the code that accompanies this article. The following sections highlight key parts of the application definition.

The LobSystem Element

The LobSystem element is the outermost element in the application definition. The business data catalog uses the information in this element to identify your application definition. In particular, the Name and Version attributes are important. You should use them to maintain version control. In our solution, the application definition is named ProductCatalog. The following code shows the LobSystem element from the application definition with the extraneous information removed.

<LobSystem xmlns:xsi…
SystemUtility=…
ConnectionManager=…
EntityInstance=…" Version="1.0.0.0" Name="ProductCatalog"
…>

The Property Element

The Property element occurs in many places throughout the application definition. In each case, it defines specific properties for the associated parent element. In the case of the LobSystem element, it defines the wildcard character for searching. Users may provide this character as part of a keyword search. The following code shows how the Property element defines the percent sign as the wildcard search.

<Properties>
  <Property Name="WildcardCharacter" Type="System.String">%</Property>
</Properties>

The LobSystemInstance Element

The LobSystemInstance element provides the connection information for the target data source. If you examine the information contained in this element, you see that it is essentially a database connection string defined in XML. The following code shows the LobSystemInstance element as it appears in the accompanying code. You should be careful to modify the data source name in the element before using the application definition in your own environment.

<LobSystemInstance Name="ProductSheet">
  <Properties>
    <Property Name="AuthenticationMode"
      Type="System.String">PassThrough</Property>
    <Property Name="DatabaseAccessProvider"
      Type="System.String">SqlServer</Property>
    <Property Name="RdbConnection Data Source"
      Type="System.String">LitwareServer</Property>
    <Property Name="RdbConnection Initial Catalog"
      Type="System.String">Adventureworks</Property>
    <Property Name="RdbConnection Integrated Security"
      Type="System.String">SSPI</Property>
    <Property Name="NumberOfConnections" Type="System.Int32">-1</Property>
  </Properties>
</LobSystemInstance>

The Entity Element

The Entity element defines the business entities with the application definition. The entities contain the definitions for methods that return information and the data types for each column. Application definitions may contain many entities, but our example defines only the Product entity. The following code shows how to define the Product entity.

<Entity EstimatedInstanceCount="1000" Name="Product">

The Method Element

The Method element defines the queries to execute when returning entity data. Typically, an application definition defines three kinds of methods. One method returns many results based on a wildcard search. A second method returns a specific entity based on a primary key. A third method returns all of the entity primary keys for use when indexing for search. These methods are called Finder, SpecificFinder, and IdEnumerator. The following code shows a portion of the Finder method for the Product entity.

<Method Name="FindProducts">

  <Properties>
    <Property Name="Title" Type="System.String">Name</Property>
    <Property Name="RdbCommandType" Type="System.Data.CommandType,
      System.Data, Version=2.0.0.0, Culture=neutral,
      PublicKeyToken=b77a5c561934e089">Text</Property>
    <Property Name="RdbCommandText" Type="System.String">
Select Name, ProductNumber, Color, SafetyStockLevel, ReorderPoint, StandardCost, ListPrice,
Size, Weight, DaysToManufacture, ProductLine, Class, Style, SellStartDate, SellEndDate,
DiscontinuedDate, ModifiedDate From Production.Product Where Name LIKE @Name
</Property>
  </Properties>

  <FilterDescriptors>
    <FilterDescriptor Type="Wildcard" Name="Name"/>
  </FilterDescriptors>

   <Parameters>
    <Parameter Direction="In" Name="@Name">
      <TypeDescriptor TypeName="System.String, mscorlib, Version=2.0.0.0,
        Culture=neutral, PublicKeyToken=b77a5c561934e089"
        Name="Name" AssociatedFilter="Name" />
    </Parameter>
    <Parameter Direction="Return"
      TypeReflectorTypeName=…>
     Name="Products">
      <TypeDescriptor TypeName=…>
        <TypeDescriptors>
          <TypeDescriptor …>
            <TypeDescriptors>
            <TypeDescriptor TypeName="System.String" Name="Name" />
           <TypeDescriptor TypeName="System.String" Name="ProductNumber"
               IdentifierName="ProductNumber"/>
              <TypeDescriptor TypeName="System.String" Name="Color" />
              <TypeDescriptor TypeName="System.Int16" Name="SafetyStockLevel" />
              <TypeDescriptor TypeName="System.Int16" Name="ReorderPoint" />
              <TypeDescriptor TypeName="System.Decimal" Name="StandardCost" />
              <TypeDescriptor TypeName="System.Decimal" Name="ListPrice" />
              <TypeDescriptor TypeName="System.String" Name="Size" />
              <TypeDescriptor TypeName="System.Decimal" Name="Weight" />
             </TypeDescriptors>
           </TypeDescriptor>
         </TypeDescriptors>
       </TypeDescriptor>
     </Parameter>
</Parameters>

<MethodInstances>
<MethodInstance Type="Finder" ReturnParameterName="Products"
  ReturnTypeDescriptorName="ProductDataReader"
  ReturnTypeDescriptorLevel="0" Name="FindProductsInstance" />
</MethodInstances>
</Method>

Uploading the Application Definition

After writing the application definition, you upload it to the business data catalog. You upload application definitions through the Shared Services administration site in Office SharePoint Server 2007. From the home page of the Shared Services administration site, click the Import Application Definition link in the Business Data Catalog section. From here, you can browse for the application definition file and upload it. If you modify the application definition file for the sample as described in the previous section, you can upload it now.

When the application definition is uploaded, the business data catalog validates the XML and notifies you of any errors. After you successfully upload the definition, you can view the entity definition. Figure 3 shows what the Product entity looks like when the application definition is loaded into the business data catalog.

Figure 3. The Product Entity definition

The Product entity definition

Summary of Key Sample Files

The application definition for the quoting sample, called ProductCatalog.xml, is contained in the BDCApplication folder. You should modify this file as specified in the previous section. After modifying it, you can upload this directly into the business data catalog. Remember that the application definition uses the AdventureWorks database. You must install the AdventureWorks database before working with the sample code.

Using Business Data Catalog Data in Office SharePoint Server 2007

After the application definition is loaded into the business data catalog, you may use it as a data source for Web Parts, user profiles, list columns, and search. This article focuses on using the business data catalog data for custom application solutions, so it does not address these uses in detail. However, you can use a simple Web Part to verify that your application definition is correct and that the business data catalog is functioning. If you want more information about the business data catalog and Web Parts, see the Business Data Catalog Overview. To test the application definition, drop a Business Data List Web Part onto any available page in Office SharePoint Server 2007. This Web Part displays a list of entities using the Finder method. You can then select an individual entity and view its details through the SpecificFinder method.

Open the configuration properties for the Web Part and use the Type property to select the Product entity for display. The Business Data List automatically detects the Finder method definition and sets up the Web Part to support wildcard queries. From here, you can execute queries and see results. Figure 4 shows the Business Data List Web Part with product information displayed using the application definition defined in this solution.

Figure 4. The Business Data List Web Part

The Business Data List Web Part

The Business Data Catalog Web Service

While the Business Data Web Parts offer immediate value for using business data catalog data, our solution needs to interface with the business data catalog externally through Word 2007. Unfortunately, the business data catalog does not expose a Web service by default. To retrieve entities from the business data catalog and use them in Word, you must create a custom Web service that wraps the Finder and SpecificFinder methods defined in the application definition.

Creating a business data catalog Web service is possible because the business data catalog supports an object model interface that you can use to access entity definitions. You can use the Microsoft.Office.Server.ApplicationRegistry namespace to connect to the business data catalog, access the metadata model, and consume business data catalog data. In our quoting solution, we created a Web service that can execute any Finder method or SpecificFinder method for any application definition in the business data catalog. This also means that you can use the Web service in this sample in your own solutions.

Access to the business data catalog is controlled by a permission list maintained through the Shared Services administration site. Therefore, you must plan for allowing the Web service to access the business data catalog. The simplest way to ensure that the Web service has access to the business data catalog is to create a new virtual directory directly underneath the Shared Services site in IIS. Placing the Web service beneath the Shared Services site places it in the same security context as the business data catalog. It also allows the code to function correctly. While you do not have to deploy the service in this way, you must ensure your application pool has sufficient privileges to access the business data catalog. Figure 5 shows a new virtual directory created underneath the Shared Services site during the development of the quoting solution. You can create a similar directory and deploy the Web service from this sample with no changes.

Figure 5. A virtual directory under the Shared Services site

A virtual directory under the Shared Services site

The ExecuteFinder Method

You can use the ExecuteFinder method to execute a Finder method from an application definition and return matching entities in XML. If you have deployed the Web service for the sample, you can browse the Entities.asmx page directly and test the ExecuteFinder method. The method takes the arguments listed in Table 1.

Table 1. Arguments of the ExecuteFinder method

Argument

Description

SSPName

This is the name of the Shared Service provider in your Office SharePoint Server 2007 installation. If you deploy the Web service beneath the Shared Services site, then this value should be null.

LobInstanceName

This is the LobInstance name as described in the application definition. For the quoting solution, this is ProductSheet.

EntityName

This is the name of the Entity as described in the application definition. For the quoting solution, this is Product.

MethodName

This is the name of the Finder method as described in the application definition. For the quoting solution, this is FindProductsInstance.

SearchTerm

This is the term to use for the search. If the application definition supports wildcards, then this argument can use them. For the quoting solution, the percent sign (%) is defined as the wildcard character.

ActionName

This is the name of the action that opens a detail page in Office SharePoint Server 2007. This action is defined in the business data catalog and connected to a detail page in Office SharePoint Server 2007 when the application definition is uploaded. The default name for the action is View Profile.

If you test the ExecuteFinder method using the values listed in Table 1, you can return results directly in a browser. The results are formatted as a collection of Entity elements. Each property described in the application definition is returned as an attribute of the Entity element. Figure 6 shows the results from a test using the search term "%Bike%".

Figure 6. XML entities returned from the Web service

XML entities returned from the Web service

The ExecuteSpecificFinder Method

You can use the ExecuteSpecificFinder method to execute the SpecificFinder method described in the application definition. Because the application definition supports only a single SpecificFinder method, you do not have to know the name of the method. However, you do have to know the exact key of the entity you want to return. In the quoting sample, the product number is used as the key. The method takes the arguments listed in Table 2.

Table 2. The ExecuteSpecificFinder method

Argument

Description

SSPName

This is the name of the Shared Service provider in your Office SharePoint Server 2007 installation. If you deploy the Web service beneath the Shared Services site, then this value should be null.

LobInstanceName

This is the LobInstance name as described in the application definition. For the quoting solution, this is ProductSheet.

EntityName

This is the name of the Entity as described in the application definition. For the quoting solution, this is Product.

Identifier

This is the key to be used for the search. In the sample solution, the identifier is the product number. As a test, you can use "CL-9009."

ActionName

This is the name of the action that opens a detail page in Office SharePoint Server 2007. This action is defined in the business data catalog and connected to a detail page in Office SharePoint Server 2007 when the application definition is uploaded. The default name for the action is "View Profile."

The GenerateMOSTL Method

You can use the GenerateMOSTL method to generate valid XML for use as a Microsoft Office smart tag List. MOSTL is an XML-based smart tag that is deployed onto the client computer. The smart tag created within a MOSTL file consists of a list of terms to recognize and an associated URL that is accessed as an action item. In the quoting solution, the MOSTL file associates product numbers with their detail view in SharePoint Server. The sample code does not include a MOSTL file, because you must generate it using the Web service.

To get the smart tags working in Word 2007, you must copy the XML file created by the GenerateMOSTL method to the directory path C:\Program Files\Common Files\Microsoft Shared\Smart Tag\Lists and enable smart tags in Word 2007. Smart tags are disabled by default in Word, but can be enabled from the options dialog. Select Proofing then Auto Correct then Options then Smart Tags then Label Text with smart tags. After the MOSTL file is properly installed and the smart tags enabled, the quoting solution recognizes product numbers and displays the associated product detail page from the business data catalog in SharePoint Server 2007. Later in this article, we show how to use the sample to automatically create and install the MOSTL file. Figure 7 shows a smart tag functioning in the solution. Figure 8 shows the product detail page open in Office SharePoint Server 2007.

Figure 7. MOSTL tags in the solution

MOSTL tags in the solution

Figure 8. The product detail page in Office SharePoint Server 2007

The product detail page

While the MOSTL file makes it easy to create a smart tag recognizer for the solution, it may not be appropriate for larger data sets. With very large data sets, the file may become too large to be practical. In these cases, you may have to create a custom recognizer using managed code. A custom recognizer would allow you to implement more scalable strategies, such as calling to the Web service on demand. If you are interested in smart tag development with Visual Studio Tools for Office, see Visual Studio Tools for Office Developer portal.

Summary of Key Sample Files

The business data catalog Web service is contained in the folder named BDCWebServices and is named Entities.asmx. To use the business data catalog Web service, you can copy the Web service project under a virtual directory created in accordance with the previous section. After deploying, you can browse the Entities.asmx page directly and view the available Web methods.

Note that the Web service does not consider individual security permissions. The Web service opens all business data catalog data to users who call the service. If you want to secure the data, then you should consider creating a secure Web service using Windows Communication Foundation. For more information about Windows Communication Foundation, see Windows Communication Foundation.

Customizing Word 2007

Task panes are a well-understood paradigm in Microsoft Office products like Word 2007. Users use task panes regularly to get help, perform searches, and interact with other systems. For this reason, the task pane is a natural way to consume the data exposed by the custom business data catalog Web service. Along with the custom task pane, the quoting solution also customizes the Office Fluent Ribbon in Word. The Office Fluent Ribbon customization adds a new tab for the Business Data Catalog along with a button to display the custom task pane.

Creating Custom Task Panes

Custom task panes in Word 2007 are built with Visual Studio 2005 Tools for Office Second Edition. Visual Studio 2005 Tools for Office SE brings a managed code development model to the 2007 Office system through Visual Studio. Using Visual Studio 2005 Tools for Office SE, you can easily create Office add-ins and custom task panes. For more information or to find out how to get Visual Studio 2005 Tools for Office SE, see Visual Studio 2005 Tools for Office Second Edition. After installing, you can start projects in Visual Studio based on products in the 2007 Office system. For this sample, you need to download and install Visual Studio 2005 Tools for Office SE before you can open the project.

Custom task panes are built in Visual Studio 2005 Tools for Office SE with user controls. To create a task pane, you start a new Word 2007 project in Visual Studio and add a user control. On the user control, you can add any user interface elements you need. For the quoting solution, a TreeView is used to hold product information returned from the custom business data catalog Web service. Each node in the tree shows a separate product returned from a wildcard search using the ExecuteFinder method. A TextBox and Button control are used to accept the keyword input from the user and initialize the search. The following code shows how clicking the search button launches the Web service and populates the tree with product information.

private void buttonSearch_Click(object sender, EventArgs e)
{
    //Get path to Web service
    string servicePath = ConfigurationManager.AppSettings["ServicePath"];

    //Call the Web service and return matching products.
    BDCWebServices.Entities entityService = new BDCWebServices.Entities();
    entityService.Url = servicePath;
    entityService.Credentials = CredentialCache.DefaultCredentials;
    XmlNode entities = entityService.ExecuteFinder(
      "Litware SSP",
      "ProductSheet",
      "Product",
      "FindProductsInstance",
      textSearch.Text,
      "View Profile");

    treeProducts.Nodes.Clear();
    foreach (XmlNode entity in entities.ChildNodes)
    {
        TreeNode productNode = new TreeNode(entity.Attributes["bdc:Name"].Value);
        productNode.Tag = entity;
        productNode.Collapse();

        productNode.Nodes.Add("Product Number: "
          + entity.Attributes["bdc:ProductNumber"].Value);
        productNode.Nodes.Add("List Price: " + String.Format("{0:c}",
          double.Parse(entity.Attributes["bdc:ListPrice"].Value)));
        productNode.Nodes.Add("Standard Cost: " + String.Format("{0:c}",
          double.Parse(entity.Attributes["bdc:StandardCost"].Value)));
        productNode.Nodes.Add("Lead Time: " +
          entity.Attributes["bdc:DaysToManufacture"].Value + " days");

        treeProducts.Nodes.Add(productNode);

    }

}

A Menu control lets the user insert the returned information into the body of the document. Product data is inserted into the quote document by selecting the product in the custom task pane and clicking the appropriate menu item. Although you can insert any of the returned data, the approach is always the same. The underlying method must get a reference to the current cursor location and insert the product data. The following code shows how the product name is inserted into the document.

private void mnuActionsInsertProductName_Click(object sender, EventArgs e)
{
    if (treeProducts.SelectedNode != null)
    {

        string productName;
        if (treeProducts.SelectedNode.Nodes.Count > 0)
            productName = ((BDCAWServices.Product)treeProducts.SelectedNode.Tag).Name;
        else
            productName = 
           ((BDCAWServices.Product)treeProducts.SelectedNode.Parent.Tag).Name;

        Word.Range currentRange = Globals.ThisAddIn.Application.Selection.Range;
        currentRange.Text = productName;
    }
}

Along with returning product data, the Web service also returns the ActionURL property. As stated earlier in the article, the entity action is created by the business data catalog when the application definition is uploaded. This link points to an entity detail page with all of the available information displayed for the selected entity. By returning this link to the custom task pane, the user may select to display a complete product detail sheet by selecting the Show Product Sheet menu item in the task pane. Figure 8 shows an example of the product detail page displayed in the browser.

Customizing the Office Fluent Ribbon

You can add buttons to the Office Fluent Ribbon as part of the same Visual Studio 2005 Tools for Office SE project that creates the custom task pane. To add a new button to the Office Fluent Ribbon, you must add a Ribbon Support component to the project. When you add a Ribbon Support component to the project, Visual Studio 2005 Tools for Office SE also adds an XML file that allows you to define buttons for the Office Fluent Ribbon. You can modify this XML to create various buttons, tabs, and groups on the Office Fluent Ribbon. The following code shows how the Business Data Catalog tab is defined.

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="OnLoad">
<ribbon>
<tabs>
<tab id="BDC" label="Business Data Catalog">
<group id="ProductGroup" label="Products">
<button id="Search" 
size="large"
label="Product Search"
screentip="Search Products"
supertip="Shows or the Product Search task pane" 
onAction="OnSearch" 
imageMso="SearchLibraries"/>
<dialogBoxLauncher>
<button id="MOSTLUpdate"
label="MOSTL Dialog Box"
screentip="Show MOSTL Dialog Box"
supertip="Show the dialog box for managing business data catalog Smart Tags"
onAction="OnDialogLaunch" />
</dialogBoxLauncher>
</group>
</tab>
</tabs>
</ribbon>
</customUI>

The various elements and attributes of the XML file determine the tab, group, and button appearance. The event handler for the button click is defined using the onAction attribute and contains the name of a method to call when the button is clicked. In the quoting solution, this method displays the custom task pane.

Along with displaying the custom task pane, the solution also provides a configuration dialog for specifying the path to the path to the business data catalog Web service and automating the MOSTL file creation. This dialog is created as a Windows Form and is displayed using the dialogBoxLauncher, which appears on the new tab. Figure 9 shows the configuration dialog from the sample.

Figure 9. Sample configuration dialog

Sample configuration dialog

Summary of Key Sample Files

The Word add-in is contained in the folder BDCWordAddin. You should have Visual Studio 2005 Tools for Office SE installed before opening this project. There are several places in the add-in code that include a reference to the Litware SSP shared service provider that was part of the original development environment. You should change these references to the name of your SSP.

The sample is intended to be run directly from Visual Studio with the BDCWordAddin project set as the start up project. Note that the smart tag action handler does not function until it is registered in accordance with the next section.

Smart Tags and Business Data Catalog Data

The last piece of the quoting solution uses a custom smart tag action handler to link recognized product names to the custom task pane. The custom smart tag action handler works in conjunction with the MOSTL file so that users can open detailed information in SharePoint Server 2007 or the custom task pane.

Interestingly, Visual Studio 2005 Tools for Office SE does not support creating smart tags for products in the 2007 Office system. Smart tag development is supported for Office 2003 products using Visual Studio Tools for Office, but was not brought forward to Visual Studio 2005 Tools for Office SE. For more information about developing smart tags with Visual Studio Tools for Office, see the Visual Studio Tools for Office Developer Portal. Additionally, this sample creates a smart tag action handler directly in a class with no isolation from other add-ins. Developers are strongly advised to isolate smart tags from other add-ins to improve stability. For more information about creating production-ready smart tags, see Overview of Smart Tag Development).

All Microsoft Office add-ins are represented as COMAddIn objects and are contained within the collection COMAddIns. The COMAddIn interface defines an Object property, which by default is null but can be set to any value to expose functionality to external callers. Visual Studio Tools for Office supports this mechanism through a new virtual method named RequestComAddInAutomationService on the AddIn base class. The quoting solution uses this mechanism to allow the smart tag action handler to communicate with the custom task pane. In this way, you can overcome the fact that Visual Studio 2005 Tools for Office SE does not directly support smart tag development.

For the solution, we exposed Listener class from the add-in, which the smart tag action handler can call to pass the recognized product name to the custom task pane. To expose the class, you need to make the Listener class COM visible and return its instance by overriding the RequestComAddInAutomationService virtual method. The following code shows how the interface is created in the quoting solution and then returned by overriding the RequestComAddInAutomationService virtual method.

[ComVisible(true)]
[Guid("BB349BDE-AC21-4a8f-8AD3-D98238CF78E6")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IListener
{
    void ReceiveData(string data);
}
}
protected override object RequestComAddInAutomationService()
{
    if (this.listener == null)
        this.listener = new Listener();
    return this.listener;
}

After you set up the interface, the smart tag action handler uses it to pass data to the custom task pane. The workhorse for smart tag action logic is the InvokeVerb2 method of the ISmartTagAction2 interface. The smart tag runtime calls this method passing it a target object, which in case of Word is a Range object. From the Range object, you can get to the Application object and the COMAddIns collection. From the COMAddIns collection, you can access our particular Word add-in using its name. Then you can access the add-in's Object property, which contains the Listener object. The following code shows how the smart tag action handler uses this technique to call the ReceiveData method.

Word.Range r = (Word.Range)Target;
Word.Window w = r.Application.ActiveWindow;
object addinName = "BDCWordAddin";
Microsoft.Office.Core.COMAddIn addin = r.Application.COMAddIns.Item(ref addinName);
BDCAddInInterfaces.IListener listener = DCAddInInterfaces.IListener)addin.Object;
listener.ReceiveData(r.Text);

To receive the data, the add-in must implement the IListener interface and take some action. In the quoting solution, the custom task pane receives the product number from the smart tag action handler. Subsequently, the add-in calls the business data catalog Web service SpecificFinder method with the product number. The Web service returns the product information, which is then displayed in the task pane. Like the search results shown earlier, users can insert the product information displayed in the task pane directly into the current Word document using the menu found on the custom task pane. The following code shows how the add-in receives the product number from the smart tag action handler.

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class Listener : IListener
{
    public void ReceiveData(string data)
    {
        //Get the Active document.
        Word.Document document =
         Globals.ThisAddIn.Application.ActiveDocument as Word.Document;

        if (document != null)
        {
            //Get the wrapper for this document.
            DocumentWrapper Wrapper = null;
            Globals.ThisAddIn.Wrappers.TryGetValue(document, out Wrapper);

            if (Wrapper != null)
            {
                if (Wrapper.CustomTaskPane != null && Wrapper.CustomTaskPane.Control != null)
                {
                    //Get the task pane for this document.
                    SearchPane pane = Wrapper.CustomTaskPane.Control as SearchPane;

                    if (pane != null)
                    {
                        //Pass data to the task pane
                        pane.ShowDetails(data);
                    }
                }

            }
        }
    }

}

Summary of Key Sample Files

The smart tag action handler is contained in the folder named BDCSmartTag. To run the sample, you must compile the smart tag action handler, register it, and set up a code access security policy. Within the project, there is a batch file named SETUPTRUST for registering the smart tag and creating the code-access security policy. Look through these batch files and adjust the directory locations to match your development environment.

Managing Documents and Task Panes

Even though the add-in functionality is complete, you must provide some additional capabilities to deal with multiple documents opened at the same time. This is necessary to synchronize the multiple documents and task panes that exist in such a situation. You want to make sure that the right data always appears in the correct task pane. To accomplish this task, define a DocumentWrapper class to create the custom task pane and attach it to the document. Additionally, it must remove the task pane when the document is closed. The following code shows the DocumentWrapper class.

public class DocumentWrapper
{
    //Specify member variables.
    Word.Document document;
    CustomTaskPane taskPane;

    //Specify the constructor.
    public DocumentWrapper(Word.Document document)
    {
        //Save a reference to the current document.
        this.document = document;

        //Wire up the close event for the document.
        ((Word.DocumentEvents_Event)this.document).Close += new 
          Microsoft.Office.Interop.Word.DocumentEvents_CloseEventHandler(
          DocumentWrapper_Close);
            
        //Add a new SearchPane to this document.
        this.taskPane = Globals.ThisAddIn.CustomTaskPanes.Add(
          new SearchPane(), "BDC Pane", this.document.ActiveWindow);
        this.taskPane.Visible = true;

    }
    
    //Get the CustomTaskPane property.
    public CustomTaskPane CustomTaskPane
    {
        get { return this.taskPane; }
    }

    //Close the document.
    void DocumentWrapper_Close()
    {
        //Remove the custom task pane from the collection when the document closes
        if (this.taskPane != null)
            Globals.ThisAddIn.CustomTaskPanes.Remove(this.taskPane);
        this.taskPane = null;

        //Remove the document from the Wrappers collection.
        Globals.ThisAddIn.Wrappers.Remove(this.document);
        ((Word.DocumentEvents_Event)this.document).Close -= new 
          Microsoft.Office.Interop.Word.DocumentEvents_CloseEventHandler(
          DocumentWrapper_Close);
        this.document = null;
    }

    }

For each open document, there is an instance of the DocumentWrapper class. This collection of instances is maintained by a dictionary Dictionary<Word.Document, DocumentWrapper>. As a new document opens, create an instance of the DocumentWrapper class and add it to the dictionary. When the document is closed, the respective entry is removed from the dictionary. Let's look at creating an instance of DocumentWrapper class when a document is open.

Working with Other Office Applications

So far, we showed you how to connect smart tag action with Word custom task panes. To support other Microsoft Office applications such as Microsoft Office Excel, Microsoft Office PowerPoint, and Microsoft Office Outlook, you must modify the code. The changes to the smart tag action code are minimal. You gain access to the underlying Excel or PowerPoint Application object by typecasting the Target object passed to the InvokeVerb2 method to either Excel.Range or PowerPoint.TextRange. The code for an Excel or PowerPoint add-in is very similar to the Word add-in, except you control the visibility of the appropriate task pane differently. In the other applications, the task pane is anchored to the frame window that hosts documents. This is because in Excel and PowerPoint there is only one document frame window per instance of the application. Therefore, task panes for all open documents are anchored to this single window. So depending on which document is active at any given time, you need to make corresponding task pane visible and hide all other task panes.

The smart tags behavior in Outlook is unique. If you are using Word as an e-mail editor, Word recognizes the smart tags in e-mail. Consequently, the Target object is of type Word.Range and the ApplicationName passed in is Word.Application.12. You must distinguish if the recognized smart tag is from a Word document or Outlook e-mail message. You can do this by checking the ActiveWindow property of the underlying Application object. If the smart tag is from Outlook e-mail, such a check throws an exception. The following code shows how to implement this technique using the custom task pane in Outlook.

public void InvokeVerb2(int VerbID, string ApplicationName,
  object Target,
  Microsoft.Office.Interop.SmartTag.ISmartTagProperties Properties,
  string Text, string Xml, int LocaleID)
{
    try
    {
        if (ApplicationName == "Word.Application.12")
        {
            Word.Range r = (Word.Range)Target;
            bool inOutlook = false;

            try
            {
                Word.Window w = r.Application.ActiveWindow;
            }
            catch (System.Runtime.InteropServices.COMException comEx)
            {
                inOutlook = true;
            }

            if (!inOutlook)
            {
                object addinName = "BDCWordAddin";
                Microsoft.Office.Core.COMAddIn addin = 
                  r.Application.COMAddIns.Item(ref addinName);
                BDCAddInInterfaces.IListener listener = 
                 (BDCAddInInterfaces.IListener)addin.Object;
                listener.ReceiveData(r.Text);
            }
            else
            {
                Outlook.ApplicationClass outlook = 
                  new Microsoft.Office.Interop.Outlook.ApplicationClass();
                object outlookAddinName = "BDCOutlookAddIn";
                Microsoft.Office.Core.COMAddIn outlookAddin = 
                  outlook.COMAddIns.Item(ref outlookAddinName);
                BDCAddInInterfaces.IListener listener = 
                  (BDCAddInInterfaces.IListener)outlookAddin.Object;
                listener.ReceiveData(r.Text);
            }
        }
    }
    catch (System.Exception x)
    {
        MessageBox.Show(x.Message, "BDC Smart Tags",
          MessageBoxButtons.OK, MessageBoxIcon.Error);
    }

    finally
    {
        // Release the TokenList object and perform garbage collection at the end
        // To ensure an application does not stay in memory.
        System.Runtime.InteropServices.Marshal.ReleaseComObject(Target);
        GC.Collect();
    }

    return;
}

Conclusion

This white paper examiness the business data catalog and how to use it in custom applications with Word 2007. Using business data catalog data in Microsoft Office client applications is possible because of the object model interface exposed through the Microsoft.Office.Server.ApplicationRegistry namespace. You can wrap this object model in a custom Web service to expose business data catalog functionality to Microsoft Office clients. Additionally, you can make use of custom task panes and smart tags to interact with the business data catalog data.

Additional Resources

Resources for Developers

How-To Resources

Resources for Microsoft Products