Export (0) Print
Expand All

Connecting to Online Data Using Visio 2003

Office 2003
 

Adam Lofstedt
Visimation, Inc.

August 2005

Applies to:
    Microsoft Office Visio Standard 2003
    Microsoft Office Visio Professional 2003

Summary: Learn to use Microsoft .NET and smart client technologies to extend Visio 2003 with smart, scalable, and more secure data connectivity solutions. Learn from an example about combining Visio SmartShape technology with Web services. (23 printed pages)

Contents

Introduction to Creating a Smart Client Application
Using Visio 2003 as a Smart Client
The COM Add-in Approach to Visio Development
Creating a Visio COM Add-In
Initializing the Application
Responding to User Actions by Using Marker Events
Creating Web Services with SQL Server 2005
Connecting to a Web Service From a COM Add-In
Embedding XML Data in SolutionXML
Conclusion
Additional Resources
About the Author

Introduction to Creating a Smart Client Application

When you combine up-to-date business information with diagrams in Microsoft Office Visio 2003, Information Workers are able to identify crucial information more quickly, uncover hidden patterns, and communicate with other team members and managers more effectively. Visio provides built-in features to connect to Open Database Connectivity (ODBC) data sources, and Microsoft .NET developers can also extend Visio 2003 with smart, scalable, and more secure data connectivity solutions. This article provides a technical overview and step-by-step example about how to combine Visio SmartShape technology with Web services.

When coupled with up-to-date business data, Visio fully evolves into a business-critical smart client application. Component Object Model (COM) add-ins written in Microsoft Visual Basic .NET, C#, or managed C++ enable you to link Visio to online data, pulling information into diagrams on demand. This article walks through the steps involved in creating a smart client application using Visio, by creating a COM add-in that connects to a Web service.

Prerequisites

To create the application in this article, you must have the following programs installed:

If you are new to developing with Visio, see Getting Started: Developing with Visio 2003.

Using Visio 2003 as a Smart Client

Smart client technology combines the best of two worlds: online thin-client Web applications and offline rich-client desktop applications. There are benefits and drawbacks to each application type. Thin-client applications are fast, easy to deploy, and easily connected to centralized databases, but they lack offline functionality and rich user interfaces. Rich-client applications enable you to create powerful user interfaces (UIs) and robust end-user functionality, but typically they lack advanced data integration with online data sources.

Microsoft .NET technologies bring these two application types together, by including access to databases and Web services through standard .NET Framework classes. Now, rich-client desktop applications can become "smart clients" and can easily connect to online sources of data on demand, while still retaining their offline functionality.

To demonstrate using Visio as a smart client, this article walks through the process of linking Visio to a database-driven Web service. We use the AdventureWorks database, which is installed with Microsoft SQL Server 2005 April CTP. AdventureWorks is a full-featured sample database for a fictitious bicycle company.

The scenario we model is that of a warehouse manager who wants to graphically view products that are low in stock, warehouses where those products are located, and vendors that supply the products. We create an application, InventoryWatcher, that enables the storage of this inventory data as XML, directly within a Visio diagram. You access data from a SQL Server 2005 database using a Web service and store data in SolutionXML. With InventoryWatcher, a user can also refresh data by right-clicking on a page. The data is used to draw a diagram of a product that is low in stock and to present information about the warehouses where it is located and any vendors that supply that product. At any time, the user can change products by selecting a custom right-click menu, which reads the offline XML data stored in the Visio file, displays the products in a selectable ListView control in an anchored window or Microsoft Windows Form, and then redraws the diagram around the newly selected product.

Visio smart client application (click to see larger image)

Figure 1. Visio smart client application (click picture to see larger image)

You can see the flow of this smart client application in Figure 2. When Visio starts, our COM add-in loads with it, and waits for a valid Visio drawing document to be opened before it performs any critical actions. We do not want our COM add-in running and performing actions on every Visio diagram, so we limit the scope of our add-in to only those diagrams that we preconfigure with a special property. This special property tells our add-in that this is a special inventory diagram, and that it should initialize the programming logic.

After an inventory diagram opens, our add-in waits for special "marker events" to occur, which are custom events that we tie to the Visio Application object. Using marker events, our COM add-in can respond to user actions (menu item clicked, shape right-click menu action clicked, shape deleted, and more).

Flow of data integration

Figure 2. Flow of data integration

The COM Add-in Approach to Visio Development

Visio 2003 has a robust COM-based object model, enabling you to automate almost every aspect of diagram creation (dragging and dropping, adding text, connecting shapes, and more). You can automate this object model through a number of different architectures, including .exe file add-ons, Visio library file (.vsl file) add-ins, Microsoft Visual Basic for Applications (VBA) code, and COM add-ins. To use the full power of the .NET Framework, however, using COM add-ins is the recommended approach.

Visio 2003 includes a primary interop assembly (PIA) that enables you to integrate managed code assemblies and applications directly with Visio and its object model, using Visual Basic .NET, C#, or any language that uses the .NET Framework. You can write COM add-ins in managed code, and you can use all the features of the .NET Framework to create smart client applications based on Visio.

Creating a Visio COM Add-In

The easiest way to create a managed code COM add-in for Visio is to install the Microsoft Office Visio 2003 SDK. As part of its installation, the SDK creates a new project template and wizard for Visual Studio .NET 2003.

The New Project dialog box, with the Visio add-in template selected

Figure 3. The New Project dialog box, with the Visio add-in template selected

To create a COM add-in, after installing the Visio 2003 SDK

  1. Open Visual Studio .NET 2003
  2. On the File menu, select New and then click Project.
  3. In the New Project dialog box, click the Visio add-in or add-on icon (available in the Visual Basic, C#, and C++ project folders).
  4. In the Name text box, type a name for your project.
  5. Click OK.
  6. The Microsoft Visio Add-in or Add-on Wizard opens, as shown in Figure 4.

    The Visio Add-in or Add-on Wizard

    Figure 4. The Visio Add-in or Add-on Wizard

To configure the Microsoft Visio Add-in or Add-on Wizard

  1. Click Next.
  2. Select Create a COM Add-in.
  3. Type InventoryWatcher for the name of the add-in and type a description.
  4. Select Load the add-in when the Visio application loads.
  5. Click Finish.

After you complete the wizard, your solution opens. In Solution Explorer, you see two projects:

  • Your COM add-in assembly project, called InventoryWatcher
  • A setup project to install your COM add-in, called InventoryWatcherSetup

    Files and projects created by the Visio Add-in or Add-on Wizard

    Figure 5. Files and projects created by the Visio Add-in or Add-on Wizard

Key Classes and Methods

When you ran the wizard, it created several files for your project, the most important of which is the Connect class file (Connect.cs). This Connect class is responsible for implementing the IDTExtensibility2 interface, enabling your add-in to be loaded and initialized by Visio.

There are two important methods in the Connect class: OnConnection and OnStartupComplete.

The OnConnection Method

The OnConnection method is triggered when Visio begins loading your COM add-in, and is the point at which you get a reference to the Visio Application object. In the default code created by the SDK add-in wizard, a reference to the Visio Application object is stored in the local variable vsoApplication.

public void   OnConnection(
   object application, 
   Extensibility.ext_ConnectMode connectMode, 
   object addInInst,
   ref System.Array custom) 
{
   vsoApplication = (Microsoft.Office.Interop.Visio.Application)
      application;
   addInInstance = addInInst;
   System.Windows.Forms.MessageBox.Show("InventoryWatcher connected.", "InventoryWatcher add-in");
}

Notice that the wizard added an additional line at the end of this method to show a simple MessageBox to the user. At this point, you can press F5 to run your add-in. You see the MessageBox appear, verifying that your add-in has successfully been loaded by Visio. After you verify that your add-in is loading, you can safely remove the MessageBox line from the code.

The OnStartupComplete Method

The OnStartupComplete method is fired when Visio is finished loading (but before a document, template, or stencil has been opened). This is the key point at which you initialize your own classes and logic.

public void   OnStartupComplete(ref System.Array custom) 
{
   // Initialize your COM add-in classes here
}

Registering Your COM Add-In

For your COM add-in to be loaded by Visio at startup, it must be registered for use with Visio in the registry. The SDK add-in wizard automatically performs this registration for you, creating a registry entry in one of the following locations (depending on whether you chose to make the add-in available to all users or only to the current user):

  • HKEY_LOCAL_MACHINE\Software\Microsoft\Visio\Addins
  • HKEY_CURRENT_USER\Software\Microsoft\Visio\Addins

Running and Debugging Your COM Add-In

To run or debug your COM add-in, press F5 in Visual Studio .NET. The SDK add-in wizard configures Visio to start when the application is run. When you press F5, Visio starts and your COM add-in loads with it. If you included breakpoints in your code, they are hit if you perform any actions in Visio that cause that code to run.

Initializing the Application

When working with a COM add-in, you should encapsulate your logic in your own application class and initialize it during the OnStartupComplete method in the Connect class.

Creating the Application Class

For this article, we add a new class file to our project.

To add a class file to the project

  1. Right-click the project icon, and then select Add and click Add Class
  2. For the name of the class, type Application.

This Application class holds all of our logic and behavior. We instantiate our class in the OnStartupComplete method of the Connect class, and pass it a reference to the Visio Application object.

Our OnStartupComplete method now looks like this:

public void   OnStartupComplete(ref System.Array custom) 
{
   Application app = new Application(vsoApplication);
}

In the Application class file, we work with Visio objects, so we need to add a using directive at the top of the file. We also need a reference to the System.Xml namespace.

using System;
using System.Xml;
using Visio = Microsoft.Office.Interop.Visio;

Because we want to pass in a reference to the Visio Application object, we need to change the Application class constructor, and we need to add a private member variable. Our Application class now looks like the following.

using System;
using System.Xml;
using Visio = Microsoft.Office.Interop.Visio;
namespace InventoryWatcher
{
   public class Application
   {
      private Visio.Application _visioApplication;
      
      public Application(Visio.Application visioApplication)
      {
         // Store the Visio Application object locally
         _visioApplication = visioApplication;
      }
   }
}

Listening to Visio Events

At this point, our COM add-in only knows that Visio is running; it does not know if any Visio documents are open, and it cannot respond to any Visio events. Therefore, we need to set up Visio event handlers early on, preferably in our Application class constructor. The key events we want to listen for are DocumentOpened and MarkerEvent. The following code creates the stubs for our Visio event handlers.

      public Application(Visio.Application visioApplication)
      {
         // Store the Visio Application object locally
         _visioApplication = visioApplication;

         // Setup Visio Application Events
         SetupVisioEvents();
      }

      private void SetupVisioEvents()
      {
         _visioApplication.DocumentOpened += new 
   Microsoft.Office.Interop.Visio.EApplication_DocumentOpenedEventHandler
    (_visioApplication_DocumentOpened);
         _visioApplication.MarkerEvent += new 
   Microsoft.Office.Interop.Visio.EApplication_MarkerEventEventHandler
    (_visioApplication_MarkerEvent);
      }
      private void 
   _visioApplication_DocumentOpened(Microsoft.Office.Interop.Visio.Document
   doc)
      {
      }

      private void 
   _visioApplication_MarkerEvent(Microsoft.Office.Interop.Visio.Application
   app, int SequenceNum, string ContextString)
      {
      }

Testing the Document

Because we create an event handler for the DocumentOpened event, our application can be notified when documents are opened, and can test the contents of the opened document. Because Visio stencils are considered Document objects in Visio, in the DocumentOpened event handler we first need to test to determine if the document is a stencil.

      private void 
   _visioApplication_DocumentOpened(Microsoft.Office.Interop.Visio.Document 
   doc)
      {
         // Get the document name
         string fullName = doc.FullName.ToLower(); 

         if (fullName.EndsWith(".vss") || fullName.EndsWith(".vsx"))
         {
            // Don't perform any actions
            return;
         }

Next, we test the document to see if it is an inventory document. To do this, we check for the existence of a user-defined cell in the DocumentSheet of the document. (An explanation about how to set this cell is given in the next section of this article.)

         // Test if this is our document
         if 
    (!Convert.ToBoolean(doc.DocumentSheet.get_CellExistsU("User.InventoryWatcher",
   (short)Visio.VisExistsFlags.visExistsAnywhere)))
         {
            // This isn't our document, don't do anything
            return;
         }

If this is our special inventory diagram, we can then perform whatever actions are necessary when the document is first opened, such as automatically attempting to connect to the Web service to refresh the inventory data. Our DocumentOpened event handler now looks like the following code.

      private void 
   _visioApplication_DocumentOpened(Microsoft.Office.Interop.Visio.Document 
   doc)
      {
         // Get the document name
         string fullName = doc.FullName.ToLower(); 

         if (fullName.EndsWith(".vss") || fullName.EndsWith(".vsx"))
         {
            // Don't perform any actions
            return;
         }

         // Test if this is our document
         if 
    (!Convert.ToBoolean(doc.DocumentSheet.get_CellExistsU
    ("User.InventoryWatcher", (short)Visio.VisExistsFlags.visExistsAnywhere)))
         {
            // This isn't our document, don't do anything
            return;
         }

         // This is our document, refresh the data
         RefreshData();
      }

Setting Up the Inventory Document

We want our COM add-in to be associated with a specific diagram so that it does not interfere with other Visio diagram types, such as Unified Modeling Language (UML) documents, floor plans, or flowcharts. Therefore, we need to configure a document specifically for use with our COM add-in. To do this, we open a new Visio diagram and then add a document-level, user-defined cell to it.

To add a user-defined cell to a document's ShapeSheet spreadsheet (sometimes referred to as a DocumentSheet)

  1. Open a Visio diagram
  2. On the View menu, click Drawing Explorer Window.
  3. Right-click the Drawing icon and then click Show ShapeSheet.

    Accessing the document's ShapeSheet

    Figure 6. Accessing the document's ShapeSheet

  4. With the ShapeSheet window open, on the Insert menu, click Section. Select the User-defined cells check box, and then click OK.
  5. On the User-defined cells section of the DocumentSheet, create a cell called InventoryWatcher; give it a value of TRUE. This cell serves as a flag to our COM add-in that this document is an inventory document.

    Inserting a document-level, user-defined cell

    Figure 7. Inserting a document-level, user-defined cell

Responding to User Actions by Using Marker Events

So, now our COM add-in is listening to Visio events and is loading along with our inventory document. But how do we get our add-in to respond to user events, such as clicking a custom menu or toolbar item, double-clicking a shape, or clicking an item in a ListView control in an anchored window? We use marker events.

Marker events are the easiest way to wire up your COM add-in to respond to user actions. Setting up marker events is a two-step process. First, you create an event handler for the Visio Application object's MarkerEvent event. Our event stub code (seen previously in this article) already created this event for us, so our add-in is ready to respond to MarkerEvent events. Second, we need to trigger marker events on the client in response to user actions. We can do this for ShapeSheet cells by using the QUEUEMARKEREVENT ShapeSheet function. We can also call the QueueMarkerEvent add-on from a custom toolbar button, menu item, or automation code.

Setting Up User Actions

For this article, we create a right-click action menu on the first page in our inventory document. This right-click menu triggers a MarkerEvent event that invokes a Web service to refresh drawing data.

To add a right-click action to a page

  1. On the View menu, click Drawing Explorer.
  2. In the Drawing Explorer window, expand the Foreground Pages node and right-click the page that you want to add a right-click action to, and then select Show ShapeSheet.
  3. If there is not already an Actions section in the ShapeSheet, on the Insert menu, click Section, select the Actions check box, and then click OK.
  4. Name your action row by clicking in the first cell and then typing RefreshData.
  5. In the Actions cell, type the following formula:
    QUEUEMARKEREVENT("RefreshData")
    
    

    This formula triggers a MarkerEvent event and passes it a ContextString (in this case, RefreshData). This ContextString is used by our COM add-in to determine which kind of MarkerEvent event was triggered.

  6. To finish the Action cell, in the Menu cell, type Refresh Data. Your Actions row should look like this:

    The Actions.RefreshData row

    Figure 8. The Actions.RefreshData row

Responding to MarkerEvent Events

In our event stub code, we created a handler for the Visio MarkerEvent event. Inside this handler we can place code that is executed in response to our RefreshData Action cell click. All we need to do is check the ContextString to see if it is equal to "RefreshData", and if it is, execute our code to invoke a Web service. The following code performs the check and calls our RefreshData function.

      private void 
    _visioApplication_MarkerEvent(Microsoft.Office.Interop.Visio.Application
    app, int SequenceNum, string ContextString)
      {
         // Is this our marker event?
         if (ContextString == "RefreshData")
         {
            RefreshData();
         }
      }

Creating Web Services with SQL Server 2005

SQL Server 2005 includes built-in Web services technology, making it extremely easy to directly expose the results of stored procedures or user-defined functions to a smart client. Instead of creating Web services projects by using Visual Studio .NET and configuring Internet Information Services (IIS) to expose them, you can now create Web services directly by using SQL Server 2005, with SQL Server Endpoints. IIS is not required for this, because SQL Server 2005 uses the HTTP.sys kernel-mode driver to listen to SOAP requests. This driver is installed with Microsoft Windows XP Service Pack (SP) 2 and Microsoft Windows Server 2003.

Creating SQL Server Endpoints

SQL Server Endpoints are created by the CREATE ENDPOINT statement, which you can execute in the SQL Server 2005 Management Studio. (For more information, see the article titled Overview of Native XML Web Services for Microsoft SQL Server 2005.)

Before creating your Endpoints, be sure to first create the stored procedures and user-defined functions that you want to expose. For our InventoryWatcher application, you need to run SQL Server Management Studio to set up the stored procedure that provides us with product and inventory data.

To run SQL Server Management Studio and set up a stored procedure

  1. Open SQL Server Management Studio.
  2. From the New Query toolbar button, click Database Engine Query.

    Creating a new query

    Figure 9. Creating a new query

  3. The New Query window opens. Copy and paste the following script into the New Query window, and then run the code by clicking Execute on the toolbar.

    The Execute button

    Figure 10. The Execute button

    USE AdventureWorks
    IF EXISTS (SELECT name FROM sysobjects 
             WHERE name = 'sp_ProductList' AND type = 'P')
       DROP PROCEDURE sp_ProductList
    GO
    CREATE PROCEDURE sp_ProductList
    
    AS
    
    SELECT 1 AS TAG, 0 AS PARENT,
    Production.Product.ProductID AS [Product!1!id],
    Production.Product.[Name] AS [Product!1!name],
    Production.Product.SafetyStockLevel AS [Product!1!safetystocklevel],
    Production.Product.ReorderPoint AS [Product!1!reorderpoint], 
    Production.Product.MakeFlag AS [Product!1!makeflag], 
    Production.Product.ProductSubcategoryID AS [Product!1!subcategoryid],
    Production.ProductSubcategory.[Name] AS [Product!1!subcategoryname],
    NULL AS [Vendor!2!id],
    NULL AS [Vendor!2!name],
    NULL AS [Location!3!id],
    NULL AS [Location!3!name],
    NULL AS [Location!3!quantity]   
    FROM Production.Product 
    LEFT JOIN Production.ProductSubcategory 
    ON Production.Product.ProductSubcategoryID = Production.ProductSubcategory.ProductSubcategoryID
    WHERE Production.Product.SellEndDate IS NULL 
    AND Production.Product.DiscontinuedDate IS NULL 
    AND Production.Product.SafetyStockLevel > 
    (SELECT SUM(Production.ProductInventory.Quantity) AS TotalStock 
     FROM Production.ProductInventory  
     WHERE Production.Product.ProductID = Production.ProductInventory.ProductID) 
    
    UNION ALL
    
    SELECT 2 AS TAG, 1 AS PARENT,
    Production.Product.ProductID,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    Purchasing.ProductVendor.VendorID, 
    Purchasing.Vendor.[Name],
    NULL,
    NULL,
    NULL
    FROM Production.Product 
    INNER JOIN Purchasing.ProductVendor 
    INNER JOIN Purchasing.Vendor 
    ON Purchasing.ProductVendor.VendorID = Purchasing.Vendor.VendorID 
    ON Production.Product.ProductID = Purchasing.ProductVendor.ProductID
    WHERE Production.Product.SellEndDate IS NULL 
    AND Production.Product.DiscontinuedDate IS NULL 
    AND Production.Product.SafetyStockLevel > 
    (SELECT SUM(Production.ProductInventory.Quantity) AS TotalStock 
     FROM Production.ProductInventory  
     WHERE Production.Product.ProductID = Production.ProductInventory.ProductID) 
    
    UNION ALL
    
    SELECT 3 AS TAG, 1 AS PARENT,
    Production.Product.ProductID,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    Production.Location.LocationID,
    Production.Location.[Name],
    Production.ProductInventory.Quantity 
    FROM Production.Product 
    INNER JOIN Production.ProductInventory  
    INNER JOIN Production.Location 
    ON Production.ProductInventory.LocationID = Production.Location.LocationID 
    ON Production.Product.ProductID = Production.ProductInventory.ProductID 
    WHERE Production.Product.SellEndDate IS NULL 
    AND Production.Product.DiscontinuedDate IS NULL 
    AND Production.Product.SafetyStockLevel > 
    (SELECT SUM(Production.ProductInventory.Quantity) AS TotalStock 
     FROM Production.ProductInventory  
     WHERE Production.Product.ProductID = Production.ProductInventory.ProductID) 
    
    ORDER BY 3, 1
    
    FOR XML EXPLICIT
    
    

This stored procedure provides us with structured XML data that is easily consumed by our COM add-in client. We use the SQL Server FOR XML EXPLICIT statement to assemble the XML elements into a well-structured hierarchy. (For more information, see Using EXPLICIT Mode.) The generated XML contains a list of products whose current total inventory is less than the product's predefined SafetyStockLevel. The XML is in a format similar to the following:

<Product id="1" ...>
   <Vendor id="83" ...>
   <Vendor id="50" ...>
   <Location id="1" ...>
</Product>

After creating your stored procedure, you can begin to configure a SQL Server Endpoint. You can use the script below to create your Endpoint, being sure to set the SITE attribute to the name of the computer that is running SQL Server. Create a script using the same procedure we just used, cut and paste the following code into the new script, and then click Execute on the toolbar.

CREATE ENDPOINT ep_ProductList
    STATE = STARTED
AS HTTP
(
    PATH = '/InventoryWatcher',
    AUTHENTICATION = (INTEGRATED),
    PORTS = (CLEAR),
    SITE = 'localhost' –- Change to name of the computer running SQL Server 
)
FOR SOAP
(
    WEBMETHOD 'ProductList'
        (NAME='AdventureWorks.dbo.sp_ProductList', SCHEMA=DEFAULT),
    BATCHES = DISABLED,
    WSDL = DEFAULT,
    DATABASE = 'AdventureWorks',
    NAMESPACE = 'http://Adventure-Works/Products'
)

Connecting to a Web Service From a COM Add-In

One benefit of using a COM add-in instead of a .Visio add-on (a vsl file) or VBA code is the ability to use the .NET Framework and its built-in Web services infrastructure. Consuming a Web service from a managed code COM add-in is simple. It consists of the following steps:

  1. Adding a Web Reference
  2. Writing the proxy code to retrieve the data

Adding a Web Reference

To configure your COM add-in to communicate with a Web service, you need to add a Web Reference to your Visual Studio project.

To add a Web Reference to your Visual Studio project

  • In Solution Explorer, right-click the References icon and then click Add Web Reference.

    Adding a Web Reference to the COM add-in

    Figure 11. Adding a Web Reference to the COM add-in

The Add Web Reference dialog box appears, enabling you to type in the URL of the Web service. For SQL Server Endpoints, you need a URL in the following format (replacing localhost with the name of the computer that is running SQL Server):

http://localhost/InventoryWatcher?wsdl

The ?wsdl portion of the URL points Visual Studio to the address of the Web Services Description Language (WSDL) file so that it can automatically generate a proxy class for you to use in your COM add-in project. Fill in the appropriate URL, and then click Go to connect to the Web service. After you verify that the Web service method you defined in your CREATE ENDPOINT script is there, click Add Reference.

The Add Web Reference dialog box (click to see larger image)

Figure 12. The Add Web Reference dialog box (click picture to see larger image)

After you add the Web Reference, you see an icon that represents the proxy class, which you can use in the References section of Solution Explorer.

The generated proxy class

Figure 13. The generated proxy class

Writing Proxy Code to Retrieve Web Services Data

The code to retrieve data from our Web service is simple. We place this code in the RefreshData() method, which we already called in our MarkerEvent event handler above.

The proxy code involves creating an instance of our Web service proxy object, calling a Web method, and then returning the results in a generic object array. SQL Server 2005 Endpoints return an array of data along with status messages; this is why we need to use a generic object array. Because we are using the FOR XML EXPLICIT SQL statement, SQL Server returns the query data in the form of a System.Xml.XmlElement object.

      private void RefreshData()
      {
         // Get new data from the Web service
         localhost.ep_ProductList proxy = new 
    InventoryWatcher.localhost.ep_ProductList();
         proxy.Credentials = 
    System.Net.CredentialCache.DefaultCredentials;
         object[] returnData = proxy.ProductList();
         if (returnData[0].ToString() != "System.Xml.XmlElement")
         {
            return; 
         }
         // The Web service returns an XmlElement
         XmlElement productsElement = (XmlElement)returnData[0];

         // Replace our current SolutionXML with this new xml
         ReplaceSolutionXml(productsElement);
      }

Embedding XML Data in SolutionXML

SolutionXML is the ideal place for storing smart client data in Visio. SolutionXML enables you to embed custom user-defined XML data directly within a Visio document or ShapeSheet cell and to retrieve that data programmatically at any time. Embedding SolutionXML allows your document to store data offline, enabling drawings to continue to access that data during disconnected periods. (For more information about SolutionXML and how to work with it in Visio, see Embedding Custom XML in a DatadiagramML File [Visio 2003 SDK Documentation].)

Because we pulled data from our Web service, we can store it for offline use by using the set_SolutionXMLElement method. Once the data is stored, we can query this data and perform analysis on it offline.

      private void ReplaceSolutionXml(XmlElement productsElement)
      {
       _visioDocument.set_SolutionXMLElement("InventoryWatcher","<SolutionXML 
    name=\"InventoryWatcher\">" + productsElement.InnerXml + 
    "</SolutionXML>");
      }

Conclusion

Using COM add-ins, you can create powerful smart client applications based on Visio 2003. COM add-ins use the Web services infrastructure of the .NET Framework to create intelligent and up-to-date diagrams of critical business data. Using SQL Server 2005, it is easier than ever to enable smart clients to access and consume corporate data, which you can embed in SolutionXML to enable offline data access.

Additional Resources

To find out more information about using SmartShapes and Web services in Visio, see the following resources.

About the Author

Adam Lofstedt is an application consultant for Visimation, a Microsoft Gold Certified Partner that specializes in developing custom software solutions with Visio and Microsoft technologies. Adam has over seven years experience teaching about and developing with Microsoft Office Visio.

Show:
© 2014 Microsoft