Sharing Data with Connection Points


Connection points are intended for the single-sided exchange of data between two Web Parts that don't even have to know about each other. Each connection has a provider that delivers the data and a consumer that uses it. The communication is based on an interface, which has to be defined first and is controlled by the WebPartManager.

Tip

At present, the essential implementation for connection points is quite time-consuming, as the example shows. Presumably the system will be modified again in the Beta version to simplify the exchange of data for developers in the future. Probably the new way won't be completely compatible with the approach shown here.

I've chosen the WeatherWebPart control presented earlier as the starting point for the example. This Web Part is a typical example in that it requires user-specific information, a zip code, to output weather data. To serve as a provider, I like to have another Web Part control that allows users to enter their zip code.

As mentioned previously, the basis for the communication relies on an interface that has to be known by the provider as well as by the consumer. IZipProvider implements the Zip property and the ZipHasChanged event that the provider can use to inform the consumer about a change.

 using System; public interface IZipProvider {     event EventHandler ZipHasChanged;     string Zip     {get; } } 

The provider shown here implements the IZipProvider interface to inform users about changes and give them the desired data. I'm talking about a composite control that is implemented as a Web Part with a TextBox control and a button. A click of the button activates the event that is defined in the interface. Overriding the ConnectionPoints property is important. In Listing 8-5, you can see that the Web Part control registers itself as provider for the mentioned interface. This is the only way to ensure a typed communication between the two Web Parts.

Listing 8-5: Allowing Users to Enter Their Zip Codes Through a Custom Provider

start example
 using System; using System.ComponentModel; using System.Web.Personalization; using System.Web.UI; using System.Web.UI.WebControls; namespace PGK.Web.UI.WebControls.WebParts {     public class ZipProviderWebPart: WebPart, IZipProvider, INamingContainer     {         private string zip = string.Empty;         private ConnectionPointCollection connectionPoints;         private EventHandler zipHasChanged;         private Button button;         private TextBox textBox;         public ZipProviderWebPart() { }         string IZipProvider.Zip         {             get { return this.zip; }         }         event EventHandler IZipProvider.ZipHasChanged         {             add { this.zipHasChanged += value; }             remove { this.zipHasChanged -= value; }         }         protected override void CreateChildControls()         {             this.textBox = new TextBox();             this.textBox.AutoPostBack = true;             this.textBox.Text = "90211";             this.textBox.TextChanged += new EventHandler(this.OnZipChanged);             this.Controls.Add(this.textBox);             this.button = new Button();             this.button.Text = "Submit";             this.Controls.Add(this.button);         }         protected void OnZipChanged(object sender, EventArgs e)         {             this.zip = this.textBox.Text;             if (this.zipHasChanged != null)             {                 this.zipHasChanged(this, e);             }         }         public override ConnectionPointCollection ConnectionPoints         {            get            {                 if (this.connectionPoints == null)                 {                     this.connectionPoints = new ConnectionPointCollection(this,                         base.ConnectionPoints);                     ConnectionProviderCallback provCallBack =                         new ConnectionProviderCallback(GetIZipProvider);                     ConnectionPoint connPoint =                         new ConnectionPoint(typeof(IZipProvider), provCallBack);                     connPoint.Name = "ZipProviderPoint";                     this.connectionPoints.Add(connPoint);                 }                 return this.connectionPoints;            }         }         private object GetIZipProvider()         {             return (IZipProvider)this;         }     } } 
end example

This works in a similar way on the consumer side. The property must be overridden here as well so that the Web Part control can register as a consumer for the interface. A callback is also set here that will be called if the connection can be established. The WeatherWebPart control gets access to the provider through the interface and can register for the ZipHasChanged event. You can see all of this demonstrated in Listing 8-6.

Listing 8-6: TheWeb Part Consuming the Provider and Acquiring the Entered Zip Code

start example
 using System; using System.ComponentModel; using System.Web.Personalization; using System.Web.UI; using System.Web.UI.WebControls; namespace PGK.Web.UI.WebControls.WebParts {     public sealed class WeatherWebPart: WebPart     {         private ConnectionPointCollection connectionPoints;         private IZipProvider zipProvider;         public override ConnectionPointCollection ConnectionPoints         {             get             {                 if (this.connectionPoints == null)                 {                     this.connectionPoints =                         new ConnectionPointCollection(this, base.ConnectionPoints);                     ConnectionConsumerCallback consCallBack =                         new ConnectionConsumerCallback(ConnectToProvider);                     ConnectionPoint connPoint =                         new ConnectionPoint(typeof(IZipProvider),                         consCallBack);                     connPoint.Name = "ZipConsumerPoint";                     this.connectionPoints.Add(connPoint);                 }                 return this.connectionPoints;             }         }         public void ConnectToProvider(object obj)         {             if (obj == null && this.zipProvider == null)                 throw new Exception("Null interface");             this.zipProvider = (IZipProvider) obj;             if (this.zipProvider != null)             {                 this.ZipCode = this.zipProvider.Zip;                 this.zipProvider.ZipHasChanged +=                     new EventHandler(OnProviderZipChanged);             }         }         public void OnProviderZipChanged(object sender, EventArgs e)         {             this.ZipCode = this.zipProvider.Zip;         }         ...     } } 
end example

Now the two web controls are in the position to communicate with each other, in principle. You only have to put them on a page and establish the connection between the two through the WebPartManager, as in Listing 8-7.

Listing 8-7: Establishing the Connection That Brings Provider and Consumer Together

start example
 <asp:content      contentplaceholder runat="server">     <asp:webpartmanager runat="server" >         <connections>                <asp:connection consumer                    provider   enabled="true"                    providername="ZipProviderPoint"                    consumername="ZipConsumerPoint">                </asp:connection>         </connections>     </asp:webpartmanager>     <table cellspacing="1" cellpadding="1" width="100%" border="1">         <tr>             <td valign="top">                 <asp:webpartzone  runat="server" width="100%"                     draghighlightcolor="244, 198, 96" title="Left Zone">                     <parttitlestyle forecolor="White" backcolor="#2254B1">                     </parttitlestyle>                     <partstyle borderwidth="1px"                         borderstyle="Solid"                         bordercolor="#81AAF2">                     </partstyle>                     <partverbstyle forecolor="White">                     </partverbstyle>                     <zonetemplate>                             <webparts:ZipProviderWebPart                                    runat="server" />                             <WebParts:weatherwebpart    runat="server" />                         <asp:calendar  runat="server">                         </asp:calendar>                     </zonetemplate>                 </asp:webpartzone>             </td>         </tr>     </table> </asp:content> 
end example

After all of this source code, you'll probably agree with my initial assessment. The implementation of connection points is still a little bit complex at present, although it looks quite easy in Figure 8-12. I certainly wouldn't have succeeded in implementing this example without the functioning template from AndreS of the ASP.NET team. Thank you very much for your help!

click to expand
Figure 8-12: The user can easily change the weather location.




ASP. NET 2.0 Revealed
ASP.NET 2.0 Revealed
ISBN: 1590593375
EAN: 2147483647
Year: 2005
Pages: 133

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