首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

13.7  将WebPart连接在一起

本章中多次使用了一个天气WebPart的例子,在前面的例子中,使用了ZipCode属性来指出显示哪个位置的天气。更好的解决方案是向WebPart提供邮政编码,它可能由另一个WebPart提供。这是通过WebPart连接实现的,其中数据可以从一个WebPart直接提供给另一个WebPart。

WebPart连接围绕着两方面,一方面是提供数据的提供者,另一方面是使用数据的消费者。提供者和消费者都使用一个公共接口来定义在它们之间传递的数据,并由WebPartManager管理连接。图13-15显示了提供者和消费者之间的数据流,并显示了WebPartManager对此如何控制。

WebPartManager

 

消费者

 

提供者

 

图13-15  WebPart连接数据流

步骤如下:

(1)WebPartManager调用提供者上的一个方法。

(2)WebPartManager接收提供者接口。

(3)WebPartManager将接口传递给消费者。

(4)消费者使用所提供的接口调用提供者。

13.7.1  实现WebPart连接

实现连接时,需要一个接口来定义数据,而且要求提供者实现这个接口。消费者不需要实现这个接口,但是需要接口的一个引用(因为要用这个接口来传递数据)。

1. 创建接口

实现WebPart连接时,首先是创建一个定义数据的接口。例如,天气WebPart需要一个邮政编码,其接口定义见代码清单13-15。

代码清单13-15  邮政编码接口

public interface IZipCode

{

  string ZipCode { get; }

}

这只是定义了一个只读属性ZipCode,这是唯一需要的数据。接口还可以更复杂,包含其他属性和方法,从而在连接时提供更大的灵活性。

2. 提供者中实现这个接口

提供者要实现这个接口向消费者提供数据。在这个例子中,Contacts WebPart是一个提供者,这也是一个用户控件。这个用户控件的后台代码如代码清单13-16所示,这里实现了IZipCode接口。

代码清单13-16  创建提供者

public partial class ch13_Contacts :

  System.Web.UI.UserControl, IWebPart, IZipCode

{

  #region IWebPart Members

  ...

  #endregion

  #region IZipCode Members

  public string ZipCode

  {

    get { return DetailsView1.Rows[10].Cells[1].Text; }

  }

  [ConnectionProvider("Zip Code", "ZipCodeProvider")]

  public IZipCode ProvideIZipCode()

  {

    return this;

  }

  #endregion

}

关于这段代码有几个要点需要注意:

q 这个接口实现只是返回DetailsView 控件中一个单元格的详细信息。如果接口需要更多的信息,只需实现这些属性,或者甚至可以返回更复杂的类型。

q ProvideIZipCode方法返回实现此接口的对象的当前实例。WebPartManager使用这个实例来获取接口,从而将其传递给消费者。

q ProvideIZipCode方法带有ConnectionProvider性质,指示这是连接信息的提供者。建立连接时,会使用这个性质中定义的值。第一个值是描述,第二个是连接点的名(连接点是提供连接接口的提供者中的一个特定点,通过指定显式的名允许有多个连接点)。

3. 在消费者中使用接口

消费者并不实现接口。相反,它会定义一个连接端点来接受接口的一个实例,如代码清单13-17所示。

代码清单13-17  使用连接接口

private IZipCode _provider;

[ConnectionConsumer("Zip Code", "ZipCodeConsumer",

   AllowsMultipleConnections=true)]

public void GetIZipCode(IZipCode provider)

{

    _provider = provider;

}

这里有一个方法GetIZipCode,它取一个IZipCod类型(接口)的参数。WebPartManager从提供者接收接口,并使用这个方法将接口传递给消费者。在示例代码中,这个接口只是存储在一个变量中以便以后使用(稍后将介绍)。消费者方法也带了一个属性,不过这里是一个ConnectionConsumer属性。其参数也包括描述和连接点名,另外还有一个可选的参数指示是否能对这个端点建立多个连接。

代码清单13-18显示了消费者如何使用提供者传递的这个接口。首先它检查这个接口是否为null值,如果是null,说明当前没有连接。如果已经有连接,则访问接口定义的属性,从提供者获取数据。在这个例子中,会使用这个数据建立对Yahoo天气RSS提要的一个查询,这会提供数天的天气预报。

代码清单13-18  使用从提供者获取的数据

if (_provider != null)

{

  string qry = string.Format(

    "http://xml.weather.yahoo.com/forecastrss?p={0}",

    _provider.ZipCode);

一旦定义了接口和端点,下面需要将WebPart连接在一起。

13.7.2  连接WebPart

WebPart之间的连接可以是静态或动态连接。静态连接由设计页面的人定义,而动态连接由用户在运行时创建。静态连接在WebPartManager的StaticConnections元素中建立,如代码清单13-19所示。

代码清单13-19  创建静态连接

<asp:WebPartManager ID="WebPartManager1" runat="server"

  Personalization-Enabled="true"

  OnAuthorizeWebPart="WebPartManager1_AuthorizeWebPart">

  <StaticConnections>

    <asp:WebPartConnection ID="connection1"

        ConsumerConnectionPointID="ZipCodeConsumer"

        ConsumerID="yWeatherWebPart"

        ProviderConnectionPointID="ZipCodeProvider"

        ProviderID="Contacts1"

        />

  </StaticConnections>

</asp:WebPartManager>

连接的详细信息在WebPartConnection的4个属性中定义:

q ConsumerConnectionPointID, 消费者上的连接点名。这是ConnectionConsumer属性中定义的名。

q ConsumerID, 作为消费者的WebPart的ID。在这个例子中,消费者就是ID为yWeatherWebPart的定制服务器控件。

q ProviderConnectionPointID, 提供者上的连接点名。这是ConnectionProvider属性中定义的名。

q ProviderID, 作为提供者的WebPart的ID。在这个例子中,提供者就是ID为Contacts1的用户控件。

由于这个连接是永久的,数据会从提供者提供到消费者(只要提供者和消费者都在页面上)。例如,考虑图13-16,这里显示了Contacts和Weather WebPart,尽管看上去并非如此,它们实际上已经连接。原因在于所提供的数据来自DetailsView,而当前没有选择签约方。

图13-16  已连接的WebPart(没有选择数据)

如果选择了一个签约方,数据就可以提供给消费者,从而自动显示天气的详细信息。

13.7.3  用户发起的连接

可以让用户将两个WebPart连接起来,或者断开WebPart的连接(甚至断开静态创建的WebPart连接),为此要使用一个ConnectionsZone,如代码清单13-20所示。

代码清单13-20  声明一个ConnectionsZone

<asp:ConnectionsZone

  ID="ConnectionsZone1" runat="server" />

页面的DisplayMode设置为ConnectDisplayMode时,Connect verb会增加到WebPart的verbs菜单。选择这个模式会显示ConnectionsZone,其内容取决于WebPart的当前连接状态(参见图13-17)。对于一个没有当前连接的WebPart,会看到一个消息指示当前没有连接,并有一个链接可以创建连接。例如,如果一个提供者没有活动连接,其连接区域如图13-18所示。

图13-17  已连接的WebPart(选择了数据)

图13-18  无活动连接的提供者的连接区域

对于有连接的WebPart,可以看到当前连接(提供了选项可以将连接删除),还可以看到创建连接的链接,如图13-19中所示。这里显示了将发送邮政编码的Contacts WebPart(所发送数据的描述取自ConnectionProvider属性),它与My Weather WebPart有一个连接。对于提供者,界面布局相同,但是名字会适当调整(参见图13-20)。

图13-19  有活动连接的提供者的连接区域

图13-20  有活动连接的消费者的连接区域

不论在提供者上还是消费者上,点击Disconnect都会删除WebPart之间的连接。点击Connect链接则建立与一个WebPart的连接。例如,图13-21显示了消费者的连接,它从Contacts WebPart获得数据,图13-22则相反,显示了提供者的连接,向Weather WebPart发送数据。

图13-21  连接一个提供者

图13-22  连接一个消费者

WebPart既可以作为提供者也可以作为消费者,可以使用来自多个WebPart的数据,也可以向多个WebPart提供数据。

13.7.4  连接到母版页中的WebPart

使用母版页时,通常在母版页上会有WebPartManager。如果希望在母版页和内容页上的WebPart之间定义连接,则需要在内容页上使用一个ProxyWebPartManager,如代码清单13-21所示。

代码清单13-21  声明一个ProxyWebPartManager

<asp:ProxyWebPartManager ID="ProxyWebPartManager1" runat="server">

  <StaticConnections>

    <asp:WebPartConnection ID="MyFirstConnection"

      ConsumerID="yWeatherWebPart"

      ProviderID="Contacts1">

    </asp:WebPartConnection>

  </StaticConnections>

</asp:ProxyWebPartManager>

顾名思义,ProxyWebPartManager就是母版页上WebPartManager的一个代理。

13.7.5  转换器

连接WebPart,显然希望更为灵活,你可能希望一个WebPart能提供多种不同的数据类型,或者能使用多种不同的数据类型。如果编写自己的WebPart,这很容易实现,因为可以向接口增加类型,但是如果使用第三方WebPart,则可能必须处理你不曾预见到的其他格式的数据。对此的解决方案是提供转换器,将数据从一种类型转换为另一种类型。

转换器是一个在接口(消费者和提供者使用的接口)提供的类型之间完成数据转换的类。例如,考虑两个通过接口提供数据的WebPart,其中一个提供整数数据,另一个提供串数据。默认,二者无法连接,因为数据类型不兼容。不过,通过创建一个转换器,数据在WebPart之间流动时就可以转换数据。为了便于理解,请考虑两个WebPart,其中一个提供串数据,另一个使用整数数据。尽管在这二者之间转换很容易,不过要知道这种技术适用于任何类型,利用简单类型更易于理解转换器的原则。例如,考虑代码清单13-22,它实现了一个WebPartTrasnformer,将一个串提供者的数据转换到一个整数消费者。

代码清单13-22  一个简单的转换器

[WebPartTransformer(typeof(IStringData), typeof(IIntegerData))]

public class IntegerToStringTransformer :

  WebPartTransformer, IIntegerData

{

  IStringData _stringData;

  /// <summary>

  /// Transforms from IFoo to IBar

  /// </summary>

  public override object Transform(object providerData)

  {

    _stringData = (IStringData)providerData;

    return this;

  }

  #region IIntegerData Members

  public int IntegerData

  {

    get

    {

      if (_stringData.StringData != null)

      {

        try

        {

          return int.Parse(_stringData.StringData);

        }

        catch { }

      }

      return -1;

    }

  }

  #endregion

}

转换器由WebPartTransformer属性标识,它定义了从哪个类型转换以及转换为哪个类型。这个类继承自WebPartTransformer,实现了IIntegerData接口(消费者使用的接口)。可以通过Transform方法访问串数据,IIntegerData接口的实现只是转换这个接口的数据。

使用转换器之前,必须在web.config的webParts transformers元素中先定义。类型必须设置为转换器的完全类型名,如代码清单13-23所示。

代码清单13-23  配置转换器

<webParts enableExport="true">

  <transformers>

    <add name="String to Integer Transformer"

      type="Sample.Web.UI.IntegerToStringTransformer"/>

  </transformers>

</webParts>

运行时,转换器介入到WebPart之间的连接中,首先允许连接(因为转换器会转换不兼容的类型),然后完成具体的转换过程。其好处在于,这种技术可以用于从第三方WebPart转换数据,而不必要求第三方以其不需要的形式提供(或使用)数据。你也可以自行编写转换器,来集成以前不兼容的WebPart。

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论