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


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.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.


Mahendiran said...

Nice article, last one week I spend for dynamically added the web part. Now only I fixed it.
Thanks u very much.

Steve said...

Hi Mahendiran,
Glad you found the post useful. Hopefully I'll get around to adding the source for this post in the next couple of days, and the final post, on how to use Web Parts in a tab framework, shortly after that.

loki said...

HI, realy a nice job, but i was wondering if we need to align these dynamic webzones to specific table structure how we can do that or if any work around exist ?

loki said...

i found the solution for attaching dynamic parts to a table structure, we can do that by dynamicly creating the table it self, heres the code for C#..

#region table for Zones

Table tabl = new Table();
TableRow row = new TableRow();
TableCell cell = new TableCell();
cell.VerticalAlign = VerticalAlign.Top;
TableCell cell1 = new TableCell();
cell1.VerticalAlign = VerticalAlign.Top;
TableCell cell2 = new TableCell();
cell2.VerticalAlign = VerticalAlign.Top;



loki said...

When deploying the code over Internet on IIS
first it gives me:
The display mode specified is currently disabled in this page. Make sure that customization is enabled for the current user.

then, I created the site for adminstrator user only and uses the window authentication , but my site is not viewable on only IE for rest of the browsers it works well, i used ur ajaxwebpart4 code just for testing, it also dont open on IE, is there any tweak or setting i m missing which i required to make webparts work on the server?

Thx in advance

Steve said...

Hi Loki,

I'm not sure that I compeletly understand your problem - but if it is to do with the display mode of the web parts, then it may be caused by the fact that personalization of web parts isn't available to annoymous users, if you are using forms authentication.

One possible way to authenticate an anonymous user, thereby enabling personalization, is to create an authentication cookie. Details of how to do this can be found here:

I hope this helps with your problem.


Abu Mtn Dew said...

I am having an issue with regard to getting the custom webpartmanager recognized in the aspx page with the tag prefix etc. The code is as follows:

Register Namespace="CustomWebPartManager" Assembly="DynamicWebPartManager.DynamicWebPartManager" TagPrefix="ecwpm"

I actually moved the web part manager that was created to it's own assembly. I am sure this is pretty easy and the answer is right under my nose but it keeps telling me it's unable to load the assembly and unable to recognize the tag prefix ecwpm. I have the project referenced etc.

loki said...

Thx a lot that solved the problem, I just chnaged the session time to 30min from 5 secs, and its wooting :D

loki said...

Steve is there any way that i could extend or use the onwebpartmoved function ..?

Abhijit said...

I use Ajax Web Parts Part 2 - Web Part Connections , code
I run this site through IIS, but Web part is not Drag Drop.


Rajat said...

Thanks for such a wonderful articles.
I have tried the dynamic control its working only 2 problem which i found hope you will help in that.
1) When creating dynamic web parts its duplicate :( how to resolve it ?
2) when drag drop a grid from one zone to another the container zone lost its state