Monday 15 September 2008

Ajax Web Parts Part 2 - Web Part Connections

Posts In This Series:

Introduction - ASP.NET AJAX and Web Parts
Ajax Web Parts Part 1 - Drag and Drop
Ajax Web Parts Part 2 - Web Part Connections
Ajax Web Parts Part 3 - Dynamic Web Parts
Ajax Web Parts Part 4 - Dynamic Web Part Connections


Download the source - Part 1
Download the source - Part 2
Download the source - Part 3
Download the source - Part 4



Introduction

The first part of this series introduced the components required to perform basic Web Part drag and drop.

In that post a simple Web Part was created from the Calendar component. This was then used to illustrate how a Web Part could be moved between Web Part Zones that had been created at design time.

Although the Calendar component was useful for illustrating how a Web Part can be moved between zones, it doesn’t really give a realistic view of how Web Parts would be used in a real-world situation. For this we need something slightly more complex – a pair of Web Parts that communicate via a connection.



Click here to see what will be created.



Web Part Connections

Two Web Parts are required to form a Web Part Connection; a Provider Web Part to initiate the connection and a Consumer Web Part to receive the connection.

For our example, both of these Web Parts can be formed by creating a standard User Control and then adding it to a WebPartZone (by dragging it from the Solution Explorer window and dropping it into the WebPartZone in the Design view of the Web Form).

For simplicity the Provider part consists of only 2 items: a text box to enter a string and a button to send the string to the Consumer part. So, in the markup, the Provider is given by:






The Consumer only contains a label, to display the string that is received from the Provider. Its markup is therefore as follows:






To allow these Web Parts to communicate we must now define the connection between them. This is done by creating an interface that specifies the type and name of parameters that may be passed between the Web Parts.

In our case we are only sending a string (the text entered into the text box) from the Provider to the Consumer. The interface (in the sample download code this is defined in IWebPartInterface.cs within the App_Code directory) therefore defines that the Consumer can get a single string, called Message, from the Provider and appears as follows:


public interface IWebPartInterface
{
string Message { get;}
}



In the code-behind the User Controls must specify the part they play in the connection.

The Provider, as its name suggests, must provide the interface. It does this by having a function that returns the interface. This function is identified by using the ConnectionProvider attribute. Each end of the connection is referred to as a Connection Point. The ConnectionProvider attribute takes a parameter that assigns a name to the connection point (for our provider we’ve radically called it “ProviderConnectionPoint”).

Since, in our case, the Provider class inherits from the IWebPartInterface the member function can simply return an instance of its class (i.e. it returns this).

Finally, the Provider needs to actually return some data to give to the consumer. In our case this is simply the value that gets entered into the text box and, from the interface we’ve defined, we know that this value should be labelled as Message.

Therefore the complete code-behind of the Provider class is as follows:


public partial class User_Controls_Provider
: System.Web.UI.UserControl, IWebPartInterface
{
[ConnectionProvider("ProviderConnectionPoint")]
public IWebPartInterface GetProviderData()
{
return this;
}

public string Message
{
get { return TextBox1.Text; }
}
}



In the Consumer the ConnectionConsumer attribute is used to specify that the SetProviderData method is used to get the interface and store it into a local variable.

Once the connection has been established between the Provider and the Consumer, the Consumer can use it to set the text of its label and this is done at the pre-render stage of the page lifecycle.


public partial class User_Controls_Consumer
: System.Web.UI.UserControl
{
IWebPartInterface itsProvider = null;

[ConnectionConsumer("ConsumerConnectionPoint")]
public void SetProviderData(IWebPartInterface aProviderData)
{
itsProvider = aProviderData;
}

protected override void OnPreRender(EventArgs e)
{
if (itsProvider != null)
{
Label1.Text = itsProvider.Message;
}
base.OnPreRender(e);
}
}



Finally, the connection needs to be specified in the Web Part Manager. This needs to define which Web Part acts as the provider of the connection and which as the consumer. So, for the Web Parts we’ve defined, the markup appears as follows:




Putting this all together results in a Web Page consisting of 2 Web Parts that can be dragged between the Web Part Zones and that can communicate. Entering some text into the provider Web Part’s text box and clicking on the button results in the text appearing in the consumer Web Part, as shown below:






Click here to see this in action.



Conclusion

This post has expanded our Web Part example to show how 2 Web Parts can communicate using a Web Part Connection. Everything has still been created statically at design time. In the next post I’ll look at how these Web Parts and Web Part Zones can be created dynamically to form a tab framework.


Links


More information on Web Part Connections can be found at the following:

http://www.carlosag.net/Articles/WebParts/connectionsTutorial.aspx

http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.webparts.webpartconnection.aspx