Web Part 教程--Web Part 连接

整个教程连接

Web Part 教程--简介
Web Part 教程--自定义 Web Part
Web Part 教程--Web Part 连接
Web Part 教程--深入理解 Web Part Manager & Zone

 

 三、Web Part 连接
      连接允许 Web Part 之间交换数据,是门户框架的强大特性之一。所有连接都包括两个 web parts,一个提供数据,可以为任何类型,此 part 称为生产者(provider),另一个接收数据并消费,称为消费者( consumer)。两者之间有个可选的控件转换器(transformer),当生产者和消费者的数据接口不一致时进行数据转换。
   常用于显示主从和明细数据。
   
     InterfaceA                                InterfaceB
    +----------+        +-------------+        +----------+
    | provider |=======>| transformer |=======>| consumer |
    +----------+        +-------------+        +----------+
                     InterfaceA==>InterfaceB
    
    创建可连接的 Web Part 时先要确定双方交换数据的方式,一般是定义一个接口。在生产者中实现此接口,并定义一个用 ConnectionProvider 特性修饰的方法返回此接口。再在消费者中定义一个用 ConnectionConsumer 特性修饰的方法用此接口作为参数,然后就可以在消费者的渲染时使用此接口中的数据。
    连接分为动态和静态两种,静态就是在页面上配置好了连接属性,动态是通过 ConnectionsZone 或者是代码进行连接控制。
    
    下面写一个程序来演示如何进行 Web Parts 间的连接。该程序主要功能是有一些网站数据,生产者有两个,一个使用 ISiteInfo 接口(有个 List 属性)来传递数据,一个使用 ISiteXml 接口(有个 XML 字符串属性),消费者只有一个,把 ISiteInfo 中的数据显示在页面上。当生产者为 ISiteXml 就需要使用转换器。先看接口一致的简单场景:
准备工作
1、创建一个新的 Web Application,修改配置文件

2、添加一个类文件 Site.cs,定义一个简单的实体类 Site,包含三个属性 Title、Url、Rank。

3、添加一个数据源模拟类文件 Data.cs,添加一个返回 Site 列表的方法:
public class Data { public static List<Site> GenSiteList() { List<Site> us = new List<Site> { new Site{Title = "衣心衣意女装店", Url = "http://shop36641266.taobao.com/", Rank= 5}, new Site{Title = "我的图库", Url = "http://coldljy.poco.cn", Rank = 4}, new Site{Title = "我的博客", Url = "http://blog.csdn.net/coldljy", Rank = 3} }; return us; } }

连接相关工作    
1、添加一个接口文件 ISiteInfo.cs,声明一个接口:
public interface ISiteInfo { List<Site> Sites { get; } }
    
    将站点列表以 List 格式返回。
    
2、添加一个类文件 SitesProvider.cs,定义一个生产者类 SitesProvider,继承自 WebControl (或 WebPart),实现 ISiteInfo 接口。
public class SitesProvider : WebControl, ISiteInfo { public List<Site> Sites { get { return Data.GenSiteList(); } } }
    
    注意添加引用,下面步骤中有关引用的问题将不再赘述:
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    
3、添加一个返回 ISiteInfo 接口的方法:
[ConnectionProvider("Sites Provider", "sitesProvider")] public ISiteInfo ISiteInfoProvider() { return this; }
        
4、添加一个类文件 SitesConsumer.cs,继承自 WebControl,声明一个私有变量以保存接口数据:
public class SitesConsumer : WebControl { private ISiteInfo isi; }


5、添加一个方法传入接口数据
[ConnectionConsumer("Sites Consumer", "sitesConsumer")] public void ISiteInfoConsumer(ISiteInfo iSiteInfo) { this.isi = iSiteInfo; }
    
6、现在可以在渲染时消费数据了
    重载 Render 方法:
    
protected override void Render(HtmlTextWriter writer) { if (isi == null) { writer.Write("<b>No site information available.</b>"); } else { writer.Write("<table>"); foreach (Site site in isi.Sites) { writer.Write("<tr>"); writer.Write("<td>"); writer.Write(string.Format("<a href="/" mce_href="/""{0}/" target=/"_blank/">{1}</a>", site.Url, site.Title)); writer.Write("</td>"); writer.Write("<td>"); writer.Write(string.Empty.PadLeft(site.Rank, '*')); writer.Write("</td>"); writer.Write("</tr>"); } writer.Write("</table>"); } base.Render(writer); }
    
7、先编译一下。

8、创建一个页面以测试测试静态连接
    i.添加一个 WebPartManager 到页面。
    ii.再添加一个 WebPartZone,把 SitesProvider 和 SitesConsumer 拖到里面。
<asp:WebPartZone ID="wpzStaticConnDemo" runat="server"> <ZoneTemplate> <cc1:SitesProvider ID="SitesProvider1" runat="server" Title="Data"/> <cc1:SitesConsumer ID="SitesConsumer1" runat="server" Title="List"/> </ZoneTemplate> </asp:WebPartZone>
    
    iii.在页面代码中添加一个标签 StaticConnections 到 WebPartManager 标签里,添加一个 WebPartConnection 标签进去,定义好生产者和消费者,注意标识要和上面文件中定义的一致,如果没有给予则系统会默认标识名为 default。
<asp:WebPartManager ID="WebPartManager1" runat="server"> <StaticConnections> <asp:WebPartConnection ID="conn" ProviderID="SitesProvider1" ProviderConnectionPointID="sitesProvider" ConsumerID="SitesConsumer1" ConsumerConnectionPointID="sitesConsumer"/> </StaticConnections> </asp:WebPartManager>
    
9、运行
    可以看到内容直接显示出来了。
    
10、创建一个页面以测试通过 ConnectionsZone 进行动态连接
    前面两步同 8 的i、ii 。
    拖一个 ConnectionsZone 到页面。
    拖一个按钮到页面,在其点击事件中切换显示模式。
protected void Button1_Click(object sender, EventArgs e) { this.WebPartManager1.DisplayMode = WebPartManager.ConnectDisplayMode; }
    
11、设置 10 中创建的页面为启动页面,运行
    看到都是空白
    i.点击按钮
    ii.展开 List 控件的下拉,可以看到新增了一项 Connect,点击它
    iii.页面上会新出现一个 Connections Zone
    iv. 点击 Create a connection to a Consumer
    v. 在下面新出现的下拉框中选择 Data
    vi.点击 Connect 按钮,数据将显示在 Data 控件中;点击 Disconnect 将断开连接,Data 控件中的数据消失。
    
12、创建一个页面以测试通过代码进行动态连接    
    前面两步同 8 的i、ii 。
    拖一个按钮到页面,一个进行连接操作,一个进行断开连接操作。
    页面的后台代码中添加连接代码:
protected void btnConn_Click(object sender, EventArgs e) { WebPart wpp = this.wpzCodeDemo.WebParts["SitesProvider1"]; WebPart wpc = this.wpzCodeDemo.WebParts["SitesConsumer1"]; ProviderConnectionPointCollection pcpc = this.WebPartManager1.GetProviderConnectionPoints(wpp); ConsumerConnectionPointCollection ccpc = this.WebPartManager1.GetConsumerConnectionPoints(wpc); if (this.WebPartManager1.CanConnectWebParts(wpp, pcpc[0], wpc, ccpc[0])) { this.WebPartManager1.ConnectWebParts(wpp, pcpc[0], wpc, ccpc[0]); } }

    页面的后台代码中添加断开连接代码:
    protected void btnDisconn_Click(object sender, EventArgs e)
    {
        this.WebPartManager1.DisconnectWebParts(this.WebPartManager1.Connections[0]);           
    }
    
13、运行
    点击连接和断开连接按钮测试。
    
通过前面的试验,应该对 Web Part 的连接有比较全面的理解了。再来看看与连接相关的另一知识点--转换,当生产者和消费者接口不一致时就需要进行转换,把生产者的数据转换为消费者需要的类型。下面通过实例来学习,继续使用连接测试项目:
1、添加一个接口文件 ISiteXml.cs,声明一个接口 ISiteXml:
public interface ISiteXml { string Xml { get; } }
    
    将站点以 XML 格式返回。
    
2、添加一个类文件 SitesXmlProvider.cs,定义一个类似于 SitesProvider 类的新类 SitesXmlProvider:
public class SitesXmlProvider : WebControl, ISiteXml { public string Xml { get { return Data.GenSiteXml(); } } [ConnectionProvider("Sites Xml Provider", "sitesXmlProvider")] public ISiteXml ISiteXmlProvider() { return this; } }
    
    实现了接口 ISiteXml,作为新的生产者。
    
3、新建一个类文件 SiteTranformer.cs,定义一个转换类 SiteTranformer:
[WebPartTransformer(typeof(ISiteXml), typeof(ISiteInfo))] public class SiteTranformer : WebPartTransformer, ISiteInfo { private List<Site> sites; public override object Transform(object providerData) { string xml = ((ISiteXml)providerData).Xml; TextReader tr = new StringReader(xml); XElement root = XElement.Load(tr); var query = from s in root.Descendants("Site") select new Site { Title = s.Element("Title").Value, Url = s.Element("Url").Value, Rank = int.Parse(s.Element("Rank").Value) }; sites = query.ToList<Site>(); return this; } public List<Site> Sites { get { return sites; } } }
    
    继承自 WebPartTransformer,重写其中的 Transform 方法,把接口 ISiteXml 中的数据进行转换,在实现的 ISiteInfo 接口中返回转换后的数据。转换类需要用 WebPartTransformer 特性进行修饰,指明原始接口和目标接口。
    
4、添加一个测试页面,具体请参考前面的例子,只是把生产者由 SitesProvider 改为 SitesXmlProvider。

你可能感兴趣的:(Web,xml,object,server,测试,Class)