Showing posts with label Web Part Connections. Show all posts
Showing posts with label Web Part Connections. Show all posts

Friday, 10 October 2008

Ajax Web Parts Part 4 - Dynamic 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

Currently the dynamically created Web Parts (described in part 3) cannot be moved between zones. In addition, doing a postback results in more dynamically generated Web Parts appearing. This occurs because the Web Part Manager assigns each dynamically created Web Part a random ID when its AddWebPart() function is called. To fix this problem we need a Web Part Manager that doesn’t assign random IDs and, luckily for us, Lee Dale has created just what we’re after.

Modifying Lee’s code slightly, so that it derives from the Preview DLL’s WebPartManager, rather than the standard WebPartManager (to ensure cross browser drag and drop), gives the following:


namespace AjaxWebParts.Controls
{
public class DynamicWebPartManager
: Microsoft.Web.Preview.UI.Controls.WebParts.WebPartManager
{
public void AddDynamicWebPart(WebPart webPart,
Microsoft.Web.Preview.UI.Controls.WebParts.WebPartZone zone)
{
Internals.AddWebPart(webPart);
Internals.SetZoneID(webPart, zone.ID);
}
}
}


To use this new Web Part Manager we need to make the following changes:

In our DynamicWebParts class, make the following changes:

1. change the WebPartManager alias at the top of the line to become the following:


using WebPartManager = AjaxWebParts.Controls.DynamicWebPartManager;


2. change the addition of the dynamically created Web Part to the Web Part Zone to use the DynamicWebPartManger’s function. So the current


return itsManager.AddWebPart(genericWebPart, zone, 0);


is replaced by:


itsManager.AddDynamicWebPart(genericWebPart, zone);
return genericWebPart;


In the default.aspx page the following changes are required:

1. Add the following to the set of namespace registrations:


<%@ Register Namespace="AjaxWebParts.Controls" TagPrefix="awp" %>


2. Change the reference to the Web Part Manager from “cc1:WebPartManager” to “awp:DynamicWebPartManager”

After these changes have been made everything should now work as it should: the dynamically created Web Parts should now be able to be dragged between zones and multiple Web Parts should not appear when postbacks occur. All that is required now is to implement the connection between the dynamic Web Parts.



Creating Dynamic Web Part Connections

Once dynamic Web Parts exist, with non-random ID values, creating the connections between them is relatively straightforward. We simply need to get the connection point from each Web Part and then, if a connection can be made between the Web Parts, simply create a connection that joins the two connection points.


We therefore need to add a new function to our DynamicWebParts class to create the Web Part connection, as follows:








Finally we need to call this function from our default.aspx.cs code-behind file. The Page_Init() function now becomes:






Now, when the Web Page is run, the dynamically generated Web Parts will be connected. Typing a value into the dynamic provider's text box and clicking the button will result in the value being displayed in the dynamically created consumer Web Part.




Creating Dynamic Web Part Zones

Now that we can dynamically create Web Parts, lets move on to create the rest of the page dynamically, starting with the Web Part Zones.
This is very straightforward – it’s simply a case of creating an instance of a WebPartZone and adding it to the page (note that the WebPartZone that gets created is from the Preview DLL, due to the alias that was declared).

The DynamicWebParts class member function therefore appears as follows:




Similarly, we can create the WebPartManager:




and the UpdatePanel:



Since all the page components can now be created dynamically, the static components in the page markup are no longer required. This page therefore simplifies down to:



Note that a PlaceHolder component has been added to give us somewhere to add our dynamic components.

In the Default.aspx.cs code behind file the Page_Init function now becomes:



And, since the page markup no longer defines a WebPartManager, this needs to obtained dynamically when needed. So the Page_load function now changes to become:




Click here to see this in action.


Putting this all together results in an ASP.NET AJAX page, featuring 2 Web Part Zones and 2 dragable, connected, Web Parts. Everything has now been created dynamically and is therefore just what’s required for populating tab pages.

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