利用 Visio 2003 连接在线数据

发布日期: 11/30/2005 | 更新日期: 11/30/2005

Adam Lofstedt
Visimation,Inc.

适用于:
Microsoft Office Visio Standard 2003
Microsoft Office Visio Professional 2003

摘要:学习如何使用 Microsoft .NET 和智能客户端技术,通过智能、可缩放和更安全的数据连接解决方案来扩展 Visio 2003。通过示例学习 Visio SmartShape 技术与 Web 服务的组合使用方式。

*
本页内容
创建智能客户端应用程序简介创建智能客户端应用程序简介
使用 Visio 2003 作为智能客户端使用 Visio 2003 作为智能客户端
Visio 开发的 COM 外接程序方法Visio 开发的 COM 外接程序方法
创建 Visio COM 外接程序创建 Visio COM 外接程序
关键的类和方法关键的类和方法
初始化应用程序初始化应用程序
使用标记事件响应用户操作使用标记事件响应用户操作
通过 SQL Server 2005 创建 Web 服务通过 SQL Server 2005 创建 Web 服务
从 COM 外接程序连接到 Web 服务从 COM 外接程序连接到 Web 服务
在 SolutionXML 中嵌入 XML 数据在 SolutionXML 中嵌入 XML 数据
小结小结
其他资源其他资源
关于作者关于作者

创建智能客户端应用程序简介

在将最新的业务信息与 Microsoft Office Visio 2003 中的关系图组合在一起时,信息工作者能够更快速地识别至关重要的信息,揭示隐藏的模式,以及更有效地与其他团队成员和经理进行沟通。Visio 提供内置功能以连接到开放式数据库连接 (ODBC) 数据源,而且 Microsoft .NET 开发人员还可以通过智能、可缩放和更安全的数据连接解决方案来扩展 Visio 2003。本文提供有关如何将 Visio SmartShape 技术与 Web 服务组合使用的技术概述和分步示例。

与最新的业务数据结合之后,Visio 就完全演变为业务关键的智能客户端应用程序。通过以 Microsoft Visual Basic .NET、C# 或托管 C++ 编写的组件对象模型 (COM) 外接程序,可将 Visio 连接到在线数据,并根据需要将信息提取到关系图中。本文通过创建一个连接到 Web 服务的 COM 外接程序,演练使用 Visio 创建智能客户端应用程序涉及的步骤。

前提条件

要创建本文中的应用程序,必须安装下列程序:

Microsoft Office Visio 2003 Standard 或 Microsoft Office Visio 2003 Professional

Microsoft Visual Studio .NET 2003

Microsoft Office Visio 2003 软件开发工具包 (SDK)

Microsoft SQL Server 2005 April CTP

如果您对使用 Visio 进行开发感到陌生,请参阅 Getting Started:Developing with Visio 2003

使用 Visio 2003 作为智能客户端

智能客户端技术将以下两个领域中最好的东西结合在一起:联机瘦客户端 Web 应用程序和脱机胖客户端桌面应用程序。每个应用程序类型都有优点和缺点。瘦客户端应用程序快速、易于部署,并可轻松地连接到集中式数据库,但它们缺少脱机功能和丰富的用户界面。胖客户端应用程序使您能够创建功能强大的用户界面 (UI) 和健壮的最终用户功能,但它们通常缺少与在线数据源的高级数据集成。

Microsoft .NET 技术通过标准的 .NET Framework 类包含对数据库和 Web 服务的访问,从而将这两个应用程序类型结合到一起。现在,胖客户端桌面应用程序可以变成“智能客户端”,并且可以根据需要轻松地连接到在线数据源,同时仍然保留了它们的脱机功能。

为演示如何使用 Visio 作为智能客户端,本文演练将 Visio 链接到数据库驱动的 Web 服务的过程。我们将使用 AdventureWorks 数据库(随 Microsoft SQL Server 2005 April CTP 一起安装)。AdventureWorks 是一家虚构的自行车公司的功能完善的示例数据库。

我们要模仿的情况是关于一位仓库经理的:该经理希望以图形方式查看库存不足的产品、这些产品所在的仓库以及这些产品的供应商。我们将创建应用程序 InventoryWatcher,通过它可直接在 Visio 关系图中以 XML 格式存储上述库存数据。您可以使用 Web 服务访问 SQL Server 2005 数据库中的数据,并将数据存储在 SolutionXML 中。使用 InventoryWatcher,用户还可以通过右键单击页面刷新数据。数据用来绘制库存不足的产品关系图,显示有关产品所在的仓库以及产品供应商的信息。用户可以随时通过以下方法来更改产品:选择某个自定义右键单击菜单,以便读取 Visio 文件中存储的脱机 XML 数据,在锚定窗口或 Microsoft Windows 窗体的可选 ListView 控件中显示产品,然后根据刚选择的产品重新绘制关系图。


1. Visio 智能客户端应用程序

您可以在图 2 中查看该智能客户端应用程序的流程图。当 Visio 启动时,COM 外接程序会与它一同加载,并等待一个有效的 Visio 绘图文档打开,然后执行关键性操作。我们不希望 COM 外接程序针对每个 Visio 关系图运行并执行操作,因此,我们将外接程序的运行对象范围限制为那些我们预先配置了特殊属性的关系图。该特殊属性可以告诉外接程序:这是一个特殊的库存关系图,并且它应该初始化编程逻辑。

在库存关系图打开后,外接程序会等待特殊的“标记事件”发生(这是我们绑定到 Visio Application 对象的自定义事件)。使用标记事件,COM 外接程序可以响应用户操作(单击菜单项、单击形状右键单击菜单操作、删除形状等等)。


2. 数据集成流程图

Visio 开发的 COM 外接程序方法

Visio 2003 具有基于 COM 的健壮对象模型,使您能够自动完成关系图创建的几乎所有方面(拖放、添加文本、连接形状等等)。您可以通过许多不同的体系结构 — 包括 .exe 文件外挂程序、Visio 库文件(.vsl 文件)外接程序、Microsoft Visual Basic for Applications (VBA) 代码和 COM 外接程序 — 来实现该对象模型的自动化。但是,为了充分利用 .NET Framework 的强大功能,建议您使用 COM 外接程序这一方法。

Visio 2003 包含一个主 Interop 程序集 (PIA),它使您能够利用 Visual Basic .NET、C# 或任何使用 .NET Framework 的语言,将托管代码程序集和应用程序直接与 Visio 及其对象模型相集成。您可以用托管代码编写 COM 外接程序,并且可以使用 .NET Framework 的所有功能来创建基于 Visio 的智能客户端应用程序。

创建 Visio COM 外接程序

创建 Visio 的托管代码 COM 外接程序的最简单方法是安装 Microsoft Office Visio 2003 SDK。作为安装的一部分,SDK 会为 Visual Studio .NET 2003 创建新的项目模板和向导。


3.“New Project”对话框(选择 Visio 外接程序模板)

安装 Visio 2003 SDK 后创建 COM 外接程序

1.

打开 Visual Studio .NET 2003。

2.

File 菜单上,选择 New,然后单击 Project

3.

New Project 对话框中,单击 Visio add-in or add-on 图标(位于 Visual Basic、C# 和 C++ 项目文件夹中)。

4.

Name 文本框中,键入项目名称。

5.

单击 OK

6.

Microsoft Visio Add-in or Add-on Wizard 将打开,如图 4 所示。


4. Visio Add-in or Add-on Wizard

配置 Microsoft Visio Add-in or Add-on Wizard

1.

单击 Next

2.

选择 Create a COM Add-in

3.

键入 InventoryWatcher 作为外接程序的名称,然后键入说明。

4.

选择 Load the add-in when the Visio application loads

5.

单击 Finish

完成该向导以后,解决方案打开。在 Solution Explorer 中,将看到下列两个项目:

COM 外接程序程序集项目,名为 InventoryWatcher

用于安装 COM 外接程序的安装项目,名为 InventoryWatcherSetup


5. Visio Add-in or Add-on Wizard 创建的文件和项目

关键的类和方法

在运行该向导时,它会为项目创建多个文件,其中最重要的是 Connect 类文件 (Connect.cs)。该 Connect 类负责实现 IDTExtensibility 2 接口,从而使您的外接程序能够由 Visio 加载并初始化。

Connect 类中有两个重要方法:OnConnectionOnStartupComplete

OnConnection 方法

OnConnection 方法在 Visio 开始加载 COM 外接程序时触发,而且您可以在该方法中获得对 Visio Application 对象的引用。在 SDK 外接程序向导创建的默认代码中,对 Visio Application 对象的引用存储在局部变量 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");
}

请注意,向导在该方法的末尾添加了一行额外的代码,以便向用户显示一个简单的 MessageBox。这时,可按 F5 运行您的外接程序。您会看到 MessageBox 出现,这证明外接程序已经由 Visio 成功加载。在验证外接程序能够加载以后,就可以安全地从代码中移除 MessageBox 代码行。

OnStartupComplete 方法

当 Visio 完成加载后(但是在文档、模板或模具打开之前),将激发 OnStartupComplete 方法。这是初始化您自己的类和逻辑的关键时刻。

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

注册 COM 外接程序

为了使您的 COM 外接程序能够在启动时由 Visio 加载,必须在注册表中注册它,以便将它与 Visio 配合使用。SDK 外接程序向导会自动为您执行该注册工作,它会在下列位置之一(具体取决于选择使该外接程序对所有用户都可用,还是仅对当前用户可用)创建一个注册表项:

HKEY_LOCAL_MACHINE/Software/Microsoft/Visio/Addins

HKEY_CURRENT_USER/Software/Microsoft/Visio/Addins

运行和调试 COM 外接程序

要运行或调试 COM 外接程序,请在 Visual Studio .NET 中按 F5。SDK 外接程序向导会将 Visio 配置为在应用程序运行时启动。当按 F5 时,Visio 将启动,并且 COM 外接程序会与它一同加载。如果代码中包含断点,那么当在 Visio 中执行任何导致这些代码运行的操作时,就会到达这些断点。

初始化应用程序

在使用 COM 外接程序时,应该将您的逻辑封装到自己的应用程序类中,并在 Connect 类中的 OnStartupComplete 方法的执行过程中初始化它。

创建 Application

对于本文,我们将向项目中添加一个新的类文件。

向项目中添加类文件

1.

右键单击项目图标,然后选择 Add 并单击 Add Class

2.

键入 Application 作为类名称。

Application 类保留我们的所有逻辑和行为。我们在 Connect 类的 OnStartupComplete 方法中实例化我们的类,并向它传递对 Visio Application 对象的引用。

我们的 OnStartupComplete 方法如下所示:

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

Application 类文件中,我们将使用 Visio 对象,因此需要在文件顶部添加 using 指令。我们还需要对 System.Xml 命名空间的引用。

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

因为我们希望传入对 Visio Application 对象的引用,所以需要更改 Application 类构造函数,并需要添加一个私有成员变量。我们的 Application 类现在看起来如下所示。

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;
      }
   }
}

侦听 Visio 事件

此时,COM 外接程序只知道 Visio 在运行;它不知道是否有打开的 Visio 文档,并且无法响应任何 Visio 事件。因此,我们需要尽早(最好在 Application 类构造函数中)设置 Visio 事件处理程序。我们希望侦听的关键事件是 DocumentOpenedMarkerEvent。下面的代码创建 Visio 事件处理程序的存根。

      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)
      {
      }

测试文档

因为我们为 DocumentOpened 事件创建了事件处理程序,所以应用程序在文档打开时会得到通知,并且可以测试打开文档的内容。因为 Visio 模具在 Visio 中被视为 Document 对象,所以在 DocumentOpened 事件处理程序中,我们首先需要测试以确定该文档是否为模具。

      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;
         }

接下来,我们测试该文档以检查它是否为库存文档。为此,我们将检查在该文档的 DocumentSheet 中是否存在用户定义的单元格。(本文的下一部分将说明如何设置该单元格。)

         // 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;
         }

如果这是特殊库存关系图,那么我们就可以执行在文档最初打开时需要执行的任何操作,例如,自动尝试连接到 Web 服务以刷新库存数据。我们的 DocumentOpened 事件处理程序如下所示。

      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();
      }

设置库存文档

我们希望将 COM 外接程序与特定关系图相关联,以防止它干扰其他 Visio 关系图类型,例如,统一建模语言 (UML) 文档、楼层平面图或流程图。因此,我们需要对文档进行专门配置,以便将其与我们的 COM 外接程序配合使用。为此,我们打开一个新的 Visio 关系图,然后在其中添加一个文档级别的用户定义单元格。

向文档的 ShapeSheet 电子表格(有时称为 DocumentSheet)中添加用户定义的单元格

1.

打开 Visio 关系图。

2.

View 菜单上,单击 Drawing Explorer Window

3.

右键单击“Drawing”图标,然后单击 Show ShapeSheet


6. 访问文档的 ShapeSheet

4.

打开 ShapeSheet 窗口以后,单击 Insert 菜单上的 Section。选中 User-defined cells 复选框,然后单击 OK

5.

在 DocumentSheet 的 User-defined cells 区段中,创建一个名为 InventoryWatcher 的单元格;将值 TRUE 赋予它。该单元格充当标志,以便告诉 COM 外接程序该文档是一个库存文档。


7. 插入文档级别的用户定义单元格

使用标记事件响应用户操作

现在,我们的 COM 外接程序可以侦听 Visio 事件并与库存文档一同加载。但是,如何使我们的外接程序响应用户事件(例如,单击自定义菜单或工具栏项、双击某个形状,或者单击锚定窗口的 ListView 控件中的项)呢?我们可以使用标记事件。

标记事件是连接 COM 外接程序以响应用户操作的最简单方式。设置标记事件的过程分为两个步骤。首先,需要为 Visio Application 对象的 MarkerEvent 事件创建事件处理程序。我们的事件存根代码(参见上文)已经为我们创建了该事件,因此我们的外接程序已经做好响应 MarkerEvent 事件的准备了。其次,我们需要在客户端触发标记事件以响应用户操作。可以使用 QUEUEMARKEREVENT ShapeSheet 函数为 ShapeSheet 单元格执行此操作。还可以从自定义工具栏按钮、菜单项或自动化代码中调用 QueueMarkerEvent 外挂程序。

设置用户操作

对于本文,我们在库存文档的第一页中创建了一个右键单击操作菜单。该右键单击菜单可以触发 MarkerEvent 事件,该事件可以调用 Web 服务以刷新绘图数据。

向页面添加右键单击操作

1.

View 菜单上,单击 Drawing Explorer

2.

Drawing Explorer 窗口中,展开 Foreground Pages 节点,右键单击希望向其中添加右键单击操作的页面,然后选择 Show ShapeSheet

3.

如果 ShapeSheet 中尚不包含 Actions 区段,在 Insert 菜单上单击 Section,选中 Actions 复选框,然后单击 OK

4.

通过单击第一个单元格然后键入 RefreshData 来命名您的操作行。

5.

Actions 单元格中,键入以下公式:

QUEUEMARKEREVENT("RefreshData")

该公式触发一个 MarkerEvent 事件,并向其传递一个 ContextString(在本例中为 RefreshData)。我们的 COM 外接程序使用该 ContextString 来确定触发了哪种 MarkerEvent 事件。

6.

要完成 Actions 单元格,请在 Menu 单元格中键入 Refresh Data。您的 Actions 行如下所示:


8. Actions.RefreshData

响应 MarkerEvent 事件

在事件存根代码中,我们为 Visio MarkerEvent 事件创建了处理程序。在该处理程序中,我们可以放置为响应 RefreshData Actions 单元格的单击事件而执行的代码。我们需要做的所有工作就是检查 ContextString,以确定它是否等于“RefreshData”;如果“是”,则执行我们的代码来调用 Web 服务。以下代码负责执行该检查,并调用我们的 RefreshData 函数。

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

通过 SQL Server 2005 创建 Web 服务

SQL Server 2005 包含内置的 Web 服务技术,从而使向智能客户端直接公开存储过程或用户定义函数的结果变得极其容易。现在,通过使用 SQL Server 2005 和 SQL Server 终结点来直接创建 Web 服务,而无需使用 Visual Studio .NET 创建 Web 服务项目,然后配置 Internet 信息服务 (IIS) 来公开它们。在该过程中无需使用 IIS,因为 SQL Server 2005 使用 HTTP.sys 内核模式驱动程序来侦听 SOAP 请求。该驱动程序与 Microsoft Windows XP Service Pack2 (SP) 和 Microsoft Windows Server 2003 一起安装。

创建 SQL Server 终结点

SQL Server 终结点由 CREATE ENDPOINT 语句创建,可在 SQL Server 2005 Management Studio 中执行该语句。(有关详细信息,请参阅标题为“Overview of Native XML Web Services for Microsoft SQL Server 2005”的文章。)

在创建终结点之前,确保首先创建您希望公开的存储过程和用户定义函数。对于我们的 InventoryWatcher 应用程序,需要运行 SQL Server Management Studio 来设置能够提供产品和库存数据的存储过程。

运行 SQL Server Management Studio 和设置存储过程

打开 SQL Server Management Studio。

New Query 工具栏按钮中,单击 Database Engine Query


9. 创建新查询

New Query 窗口打开。将以下脚本复制并粘贴到 New Query 窗口中,然后单击工具栏上的 Execute 来运行代码。


10.“Execute”按钮

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

该存储过程可提供易于 COM 外接程序客户端使用的结构化 XML 数据。我们使用 SQL Server FOR XML EXPLICIT 语句将 XML 元素组合到结构良好的层次结构中。(有关详细信息,请参阅“Using EXPLICIT Mode”。)生成的 XML 包含当前库存总量低于预定义 SafetyStockLevel 的产品列表。XML 的格式如下所示:

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

在创建存储过程之后,即可开始配置 SQL Server 终结点。您可以使用下面的脚本来创建终结点,但应确保将 SITE 属性设置为运行 SQL Server 的计算机的名称。使用我们刚刚使用过的同一过程创建脚本,将以下代码剪切并粘贴到新脚本中,然后单击工具栏上的 Execute

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'
)

从 COM 外接程序连接到 Web 服务

使用 COM 外接程序(而不是 .Visio 外挂程序(vsl 文件)或 VBA 代码)的好处之一是,能够利用 .NET Framework 及其内置的 Web 服务基础结构。从托管代码 COM 外接程序中使用 Web 服务的过程很简单。这一过程包含下列步骤:

1.

添加 Web 引用

2.

编写代理代码以检索数据

添加 Web 引用

要配置 COM 外接程序以便与 Web 服务通信,需要向 Visual Studio 项目中添加 Web 引用。

Visual Studio 项目中添加 Web 引用

Solution Explorer 中,右键单击 References 图标,然后单击 Add Web Reference


11. COM 外接程序中添加 Web 引用

这时会显示 Add Web Reference 对话框,以便您键入 Web 服务的 URL。对于 SQL Server 终结点,需要以下格式的 URL(请将 localhost 替换为运行 SQL Server 的计算机的名称):

http://localhost/InventoryWatcher?wsdl

URL 的 ?wsdl 部分将 Visual Studio 引向 Web 服务描述语言 (WSDL) 文件的地址,以便它能够自动生成代理类,以供您在 COM 外接程序项目中使用。填写正确的 URL,然后单击 Go 以连接到 Web 服务。在验证确实存在 CREATE ENDPOINT 脚本中定义的 Web 服务方法以后,单击 Add Reference


12.“Add Web Reference”对话框

添加 Web 引用后,可看到一个表示代理类的图标,可在解决方案资源管理器的 References 区段中使用该代理类。


13. 生成的代理类

编写代理代码以检索 Web 服务数据

从 Web 服务检索数据的代码很简单。将该代码放在 RefreshData() 方法中,上述 MarkerEvent 事件处理程序中已经调用了该方法。

代理代码涉及到创建 Web 服务代理对象的实例,调用 Web 方法,然后在一般对象数组中返回结果。SQL Server 2005 终结点会同时返回大量数据和状态消息;这就是为什么需要使用一般对象数组的原因。因为我们使用 FOR XML EXPLICIT SQL 语句,所以 SQL Server 将以 System.Xml.XmlElement 对象的形式返回查询数据。

      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);
      }

在 SolutionXML 中嵌入 XML 数据

在 Visio 中,SolutionXML 是存储智能客户端数据的理想位置。SolutionXML 使您能够将自定义的用户定义 XML 数据直接嵌入 Visio 文档或 ShapeSheet 单元格中,并且能够以编程方式随时检索这些数据。嵌入 SolutionXML 使文档能脱机存储数据,从而使图形能够在断开连接期间继续访问这些数据。(有关 SolutionXML 以及如何在 Visio 中使用它的详细信息,请参阅 Visio 2003 SDK 文档中的“Embedding Custom XML in a DatadiagramML File”。)

因为我们从 Web 服务中提取了数据,所以可以使用 set_SolutionXMLElement 方法来存储它以供脱机使用。一旦存储了数据,我们就可以脱机查询这些数据并对其执行分析。

      private void ReplaceSolutionXml(XmlElement productsElement)
      {
       _visioDocument.set_SolutionXMLElement("InventoryWatcher","" + productsElement.InnerXml + 
    "");
      }

小结

使用 COM 外接程序,可以基于 Visio 2003 创建功能强大的智能客户端应用程序。COM 外接程序使用 .NET Framework 的 Web 服务基础结构来创建关键业务数据的最新智能关系图。使用 SQL Server 2005 可使智能客户端更轻松地访问和使用公司数据 — 您可将这些数据嵌入 SolutionXML 以支持脱机数据访问。

其他资源

有关在 Visio 中使用 SmartShape 和 Web 服务的更多信息,请参阅以下资源。

Getting Started: Developing with Visio 2003

Embedding Custom XML in a DatadiagramML File

Using the QueueMarkerEvent Add-on in Visio Solutions

OfficeDeveloperCenter: Visio

OfficeDeveloperCenter

关于作者

Adam Lofstedt 是 Visimation 的应用程序顾问,该公司是 Microsoft 的金牌认证合作伙伴,专门从事使用 Visio 和 Microsoft 技术进行自定义软件解决方案的开发。Adam 具有七年以上的 Microsoft Office Visio 教学和开发经验。

转到原英文页面


阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页