Rahul Soni's blog

Never assume the obvious is true!

Dynamically adding webparts to the dynamically added Catalog zone

Dynamically adding webparts to the dynamically added Catalog zone

  • Comments 12

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

Attachment: HomePage.GIF
  • Trackback from dotnetkicks.com
  • News

    Great list of Portable Apps for your USB drive on Wikipedia
    Microsoft Visual Studio 2005 - Update...

  • I had an issue where I was changing a WebPartManger's displaymode using the following code...
    WebPartManager1.DisplayMode...
  • Anton
  • Well, my personal favorite has always been winamp!
  • I had an issue where I was changing a WebPartManger's displaymode using the following code... WebPartManager1.DisplayMode

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

  • 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,

    Rahul

  • 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,

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

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

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

Page 1 of 1 (12 items)
Leave a Comment
  • Please add 3 and 2 and type the answer here:
  • Post