Building Connected Web Parts


One of the most powerful things that can be done by Web Parts is to share data among parts within the same zone or even between different zones. A really common scenario among portal-style pages is to provide information based on the user's ZIP code. For example, when you log on to a portal for the first time, you typically add content to your page like local movie listings, weather reports, and local news. All of these could easily be written as ASP.NET 2.0 Web Parts. The issue is how to feed all of the Web Parts the same information: your ZIP code.

Data is shared among Web Parts in ASP.NET 2.0 using a publish/consume model. A Web Part can publish a piece of information that can then be consumed by any other Web Part that knows how to consume that information. This means that you could create a Web Part that prompts the user for her ZIP code and then publishes that information to all interested Web Parts. Without prior knowledge of other existing Web Parts, a developer could create a Web Part that consumes ZIP codes and an end user or administrator could utilize a ConnectionsZone to hook up publishers and consumers on the same page.

This is all made possible through a contract by which publishers and consumers both must abide. As you know, in programming terms, a contract is an interface. When a Web Part publishes data, it publishes that data in the form of an instance of an object that implements a specific interface. All a consumer has to do is implement a method that receives an instance of that same interface. The Web Part plumbing in the underlying connection takes care of calling the publishing method on the publisher and the consuming method on the consumer.

To illustrate connected Web Parts, this section walks you through adding a shared interface and two new user controls to the solution developed in the previous section, FirstWebPartPage.

Before creating any controls, add an App_Code folder to your web application and place the IZipCode interface in it. The code for the IZipCode interface is quite simple:

using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public interface IZipCode {     string ZipCode { get; set; } } 


This simple interface indicates to any consumers that the data being published is a string representing a ZIP code.

The first control is a simple control that prompts the user for his ZIP code. The beautiful thing about it is that the user's ZIP code can then be automatically stored in the personalization provider and remembered every time that same user loads the page. Create a new application subfolder called Controls and add a new web user control to it called ZipCodeSelector. The ascx code for this control is extremely simple:

<%@ Control Language="C#" AutoEventWireup="true"   CodeFile="ZipCodeSelector.ascx.cs" Inherits="Controls_ZipCodeSelector" %> Zip Code:&nbsp;<asp:TextBox  runat="server" />&nbsp; <asp:Button  runat="server" Text="Set" OnClick="btnSetZip_Click" /> 


The C# code that drives the control looks like this:

using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public partial class Controls_ZipCodeSelector : System.Web.UI.UserControl, IZipCode { private string zip = string.Empty; [Personalizable(PersonalizationScope.User)] [WebDisplayName("Zip Code")] [WebDescription("Zip Code Made Available to Connected Controls for localized data")] public string ZipCode {     get { return zip; }     set { zip = value; } } protected void Page_Load(object sender, EventArgs e) { } protected override void OnPreRender(EventArgs e) {     base.OnPreRender(e);     if (zip != null)         txtZip.Text = zip; } [ConnectionProvider("Zip Code Data Provider", "ZipCodeProvider")] public IZipCode ProvideIZipCode() {     return this; } protected void btnSetZip_Click(object sender, EventArgs e) {     zip = txtZip.Text;     txtZip.Text = string.Empty; } } 


The PersonalizableAttribute attribute class marks the ZipCode property as one that is not only managed by the personalization provider, but in this case it also indicates that the ZipCode property is managed at the User scope.

Under the hood, when you place a Web Part on a page that has a ConnectionProvider attribute on it, that tells the Web Part framework that the Web Part is publishing data.

To create a Web Part that consumes the data published by the ZipCodeSelector control, add a new Web User Control to the Controls folder and call it WeatherPart. We're not actually going to create a real weather control, so all you need to do is add the following code to your ascx file:

Currently Displaying the Weather for <asp:Label  runat="server" /> 


Then you can modify WeatherPart.ascx.cs so that it contains the following code to consume a ZIP code:

using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public partial class Controls_WeatherPart : System.Web.UI.UserControl { private IZipCode zipProvider = null; [ConnectionConsumer("Zip Code Consumer", "ZipCodeConsumer")] public void GetIZipCode(IZipCode Provider) {     zipProvider = Provider; } protected override void OnPreRender(EventArgs e) {     base.OnPreRender(e);     // take advantage of short-circuiting here     if ((zipProvider != null) && (zipProvider.ZipCode != string.Empty))         lblZip.Text = zipProvider.ZipCode;     else         lblZip.Text = "(No Data)"; } protected void Page_Load(object sender, EventArgs e) { } } 


The reason the preceding code uses the PreRender event is because, as the developer, you can't be absolutely sure when during the control's life cycle the connection data will be transferred. So the safest bet is to use the last event in the control life cycle before rendering to process the data being shared over the connection to guarantee that the data has been delivered. You will find that if you use the standard Page_Load method, the zipProvider instance will be null.

Build the solution to make sure everything compiles properly. Next, open up default.aspx again and select the CatalogZone control you placed in the designer earlier. Select the control's context menu and then click Edit Templates. This will open up the inside of the DeclarativeCatalogPart and allow you to drop additional controls into the catalog. Drag both of the controls created in this section into the area and then switch to design view to set the Title property. The new DeclarativeCatalogPart region should look something like this:

<asp:DeclarativeCatalogPart  runat="server"> <WebPartsTemplate>     <asp:Calendar  runat="server" Title="Misc Calendar" />     <asp:TextBox  runat="Server" Title="Test Text Box" />     <asp:Label  runat="server" Title="Sample Label" />     <uc2:WeatherPart  runat="server" Title="Weather Consumer" />     <uc3:ZipCodeSelector  runat="server" Title="Zip Provider" /> </WebPartsTemplate> </asp:DeclarativeCatalogPart> 


To allow users to modify the connection properties of connected Web Parts, you need a ConnectionsZone, so drag one of those from the Toolbox into the third column of the table right below the EditorZone and CatalogZone.

Now you're ready to run the application. When you run it, you will see that a new display mode, Connect, has been added to the display mode selector created earlier. Before using that mode, open the Catalog mode and add the two new Web Parts to the main zone. The ZIP code selector should contain an empty text box and the weather Web Part should display the "(no data)" phrase because it hasn't been connected and isn't receiving data.

Switch the page into Connect mode and click the drop-down menu for the ZIP code provider Web Part. Click the new Connect menu option. You will then be able to choose the destination control from a drop-down list of compatible controls. If there were 10 controls on the page that consumed ZIP codes using the IZipCode interface, all 10 of them would appear in the drop-down list. A portion of the page containing the connection editor for the ZIP code provider Web Part is shown in Figure 26.5.

Figure 26.5. Connecting a provider to a consumer using a connections zone.


When you connect the Web Parts and switch back to the Browse mode of the page, you won't notice any immediate difference because you still haven't given the ZIP code provider part a ZIP code. Enter a ZIP code and click the Set button. As soon as you click that button, you should not only see that the ZIP code remained in the text box, but that the weather consumer part has received the ZIP code, as shown in Figure 26.6.

Figure 26.6. Web part data provider and consumer in action.


Finally, close the page and then reopen it. You will see that the ZIP code provider has remembered your ZIP code because of the attributes used on the ZipCode property. As a result, that Web Part has also provided the ZIP code to the weather consumer partall without you having to do any additional work.



Microsoft Visual C# 2005 Unleashed
Microsoft Visual C# 2005 Unleashed
ISBN: 0672327767
EAN: 2147483647
Year: 2004
Pages: 298

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net