Dynamically adding webparts to the dynamically added Catalog zone
Today we are going to discuss how to add webparts to a Catalog Zone dynamically in your webpage.
Sometimes, you may have quite a lot of different webparts which you don't want to add by default to any page. Instead, you want to design an interface where you have added everything into your catalog zone dynamically. This way, users have the option to simply populate those webparts which they like. It seems like there is no *easy* way to achieve this, so you have to plan accordingly to fulfill this requirement. Before I say anything else, let me point you to a link which will explain you quite a lot about webparts and no wonder I have derived some code directly from that link to make things easier.
Introducing the ASP.NET 2.0 Web Parts Framework.
A piece of advice, if time permits (and if you are not already comfortable with the webparts stuff), go through the above link and then proceed to the remaining part of this...
OK, cool... Let's begin...
Create a New Website in VS 2005. You will have a page called default.aspx. Lets delete it! We will add another page called Default.aspx, but ensure that there is no codebehind. You can do this by ensuring that when you are adding a new Web Form, the checkbox Place code in seperate file is UNCHECKED. Now, in the source view of the Default.aspx, delete everything and paste the following...
<%@ Page Language="vb" %>
<script runat="server">
Sub CustomizePage(ByVal s As Object, ByVal e As EventArgs)
WebPartManager1.DisplayMode = WebPartManager.CatalogDisplayMode
End Sub
Sub EditWebParts(ByVal s As Object, ByVal e As EventArgs)
WebPartManager1.DisplayMode = WebPartManager.EditDisplayMode
End Sub
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs)
Dim dynamicCatalog As New CatalogZone
dynamicCatalog.ZoneTemplate = New CustomZoneTemplate()
dynamicCatalog.ID = "DynamicCatalog"
Ph1.Controls.Add(dynamicCatalog)
End Sub
</script>
<html>
<head id="Head1" runat="server">
<title>Home Page</title>
</head>
<body bgcolor="gray">
<form id="form1" runat="server">
<asp:WebPartManager
ID="WebPartManager1"
Runat="Server" />
<table width="100%" Height="100%" cellpadding="5" cellspacing="10">
<tr height="50">
<td colspan="3" align="right" bgcolor="white" style="height: 50px">
<asp:LinkButton ID="LinkButton1"
Text="Customize Page"
OnClick="CustomizePage"
Runat="Server" />
|
<asp:LinkButton ID="LinkButton2"
Text="Edit Web Parts"
OnClick="EditWebParts"
Runat="Server" />
</td>
</tr>
<tr>
<td valign="top" bgcolor="white" width="40%">
<asp:WebPartZone
ID="WebPartZone1"
Width="100%"
HeaderStyle-BackColor="lightblue"
PartTitleStyle-BackColor="silver"
Runat="Server" >
<HeaderStyle BackColor="LightBlue" />
<PartTitleStyle BackColor="Silver" />
</asp:WebPartZone>
</td>
<td valign="top" bgcolor="white" width="40%">
<asp:WebPartZone
ID="WebPartZone2"
Width="100%"
HeaderStyle-BackColor="lightblue"
PartTitleStyle-BackColor="silver"
Runat="Server" >
<HeaderStyle BackColor="LightBlue" />
<PartTitleStyle BackColor="Silver" />
</asp:WebPartZone>
</td>
<td valign="top" width="20%" bgcolor="white">
<asp:PlaceHolder runat=server ID="Ph1"></asp:PlaceHolder>
</td>
</tr>
</table>
</form>
</body>
</html>
Add three new classes (in your App_code folder) called CustomProduct.vb, CustomWebPartTemplate.vb and CustomZoneTemplate.vb. Now, paste the following code accordingly.
CustomProduct.vb
Imports System.Collections
Imports System.Data
Imports System.Data.SqlClient
Imports System.Web.UI
Imports System.Web.UI.WebControls.WebParts
Public Class CustomProduct
Inherits WebPart
Const connectionString As String = _
"Server=localhost;Trusted_Connection=True;Database=Northwind"
Const selectString As String = "SELECT * FROM Products " & _
"JOIN Categories ON Products.CategoryID=Categories.CategoryID"
Private _categoryName As String = "Beverages"
Public Sub New()
MyBase.Title = "Custom Product"
End Sub
Public Overrides ReadOnly Property Verbs() As WebPartVerbCollection
Get
' Create Beverages verb
Dim verb1 As New WebPartVerb("verb1", New _
WebPartEventHandler(AddressOf ChangeCategory))
verb1.Text = "Beverages"
verb1.Description = "Displays Beverages Products"
' Create Seafood verb
Dim verb2 As New WebPartVerb("verb2", New _
WebPartEventHandler(AddressOf ChangeCategory))
verb2.Text = "Seafood"
verb2.Description = "Displays Seafood Products"
' Create collection of verbs
Dim newVerbs() As WebPartVerb = {verb1, verb2}
' Return WebPartVerbCollection including base verbs
Return New WebPartVerbCollection(newVerbs)
End Get
End Property
Public Sub ChangeCategory(ByVal s As Object, ByVal e As WebPartEventArgs)
Dim newCategory As String = s.Text
Me.CategoryName = newCategory
Me.Title = String.Format("Featured Product - {0}", newCategory)
End Sub
<Personalizable(), WebBrowsable()> _
Public Property CategoryName() As String
Get
Return _categoryName
End Get
Set(ByVal value As String)
_categoryName = value
End Set
End Property
Protected Overrides Sub RenderContents(ByVal writer _
As HtmlTextWriter)
' Load Products into DataTable
Dim productTable As New DataTable()
Dim dad As New SqlDataAdapter(selectString, _
connectionString)
dad.Fill(productTable)
' Filter the DataTable with a Category
Dim productView As DataView = productTable.DefaultView
productView.RowFilter = "CategoryName='" & _categoryName & "'"
If productView.Count = 0 Then
Return
End If
' Randomly select a row
Dim rnd As New Random()
Dim row As DataRowView = _
productView(rnd.Next(productView.Count))
' Render the row
writer.Write(row("ProductName").ToString())
writer.Write(String.Format("- {0:c}", row("UnitPrice")))
End Sub
End Class
CustomWebPartTemplate.vb
Public Class CustomWebPartTemplate
Implements ITemplate
Dim Product1 As CustomProduct
Dim Product2 As CustomProduct
Public Sub InstantiateIn(ByVal container As System.Web.UI.Control) _
Implements System.Web.UI.ITemplate.InstantiateIn
'
Product1 = New CustomProduct
Product1.ID = "CustomProduct1"
Product1.Title = "Custom Product 1"
container.Controls.Add(Product1)
Product2 = New CustomProduct
Product2.ID = "CustomProduct2"
Product2.Title = "Custom Product 2"
container.Controls.Add(Product2)
End Sub
End Class
CustomZoneTemplate.vb
Public Class CustomZoneTemplate
Inherits WebPart
Implements ITemplate
Public Sub InstantiateIn(ByVal container As System.Web.UI.Control) _
Implements System.Web.UI.ITemplate.InstantiateIn
'
Dim DeclCatalogPart As New DeclarativeCatalogPart
Dim PgCatalogPart As New PageCatalogPart
PgCatalogPart.ID = "MyPageCatalog"
PgCatalogPart.Title = "My Page Catalog Title"
DeclCatalogPart.WebPartsTemplate = New CustomWebPartTemplate()
DeclCatalogPart.ID = "MyDeclarativeCatalog"
DeclCatalogPart.Title = "My Declarative Catalog Title"
container.Controls.Add(PgCatalogPart)
container.Controls.Add(DeclCatalogPart)
End Sub
End Class
If you switch to the design view of default.aspx you will see that there are two Zones created at design time and in the third column you will see a simple Placeholder. This is where our Catalogzone will get created and loaded at runtime. Once you run the project you will see something like this...
Now, click on "Customize Page" link and you should be able to see the dynamically added webparts with appropriate titles like the following...
Happy Programming :o)
-Rahul Soni
Comments
Anonymous
March 20, 2006
Trackback from dotnetkicks.comAnonymous
March 21, 2006
News
Great list of Portable Apps for your USB drive on Wikipedia
Microsoft Visual Studio 2005 - Update...Anonymous
March 28, 2006
I had an issue where I was changing a WebPartManger's displaymode using the following code...
WebPartManager1.DisplayMode...Anonymous
April 05, 2006
AntonAnonymous
April 06, 2006
Well, my personal favorite has always been winamp!Anonymous
October 04, 2006
I had an issue where I was changing a WebPartManger's displaymode using the following code... WebPartManager1.DisplayModeAnonymous
February 14, 2007
Its so nice. and i need one more help from you. i have the same type of requirement. in my requirement i have some web user controls. and i want to load those controls dynamically to the DeclCatalogPart. so can you please help me to solve this issue.Anonymous
February 14, 2007
Hi Ram, Thanks! Regarding your query, if you create an ASCX page and use it to dynamically load the controls, and then load that ascx control in the DeclCatalogPart, things should work fine. HTH, RahulAnonymous
May 09, 2007
hi, when i load ASCX page work fine. but i want to pass a value to ASCX page and that is not working for me or i don't know how to do it. Thanks,Anonymous
December 17, 2008
hi , I develop the web parts for user to personalize But i want to Administrator set the Web part for per role web parts And user login it's only see whichever web parts set by administrator.. Is it possible.... ? Plz Reply if u know : hirensagar007@yahoo.comAnonymous
January 28, 2009
Hi, I am trying to add dynamic Panels into the WebPartZone. The Panels also has hyperlinks added as a control into it. But when I try to add Panels as Generic Web Part into the webpartzone, The panel gets displayed but the hyperlink inside the panel doesn't get displayed. Please help..Anonymous
September 22, 2009
Best and rare artical found on ,net. It help me lot.. I am developing dashboard with webpart. I wanted to add controls dynamically.. I have one small question. Right now, I am using user controls to add as a web parts. Is there any major disadvantage if I used user controls instead of custom webpart class for rendering? Waiting 4 reply..