Teun.ToString()

by Teun Duynstee [Macaw]

<October 2008>
SuMoTuWeThFrSa
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678


Navigation

Subscriptions

News

I discontinued this blog. I now post at: www.TeunToString.net



Download Finch PocketBlogger

Post Categories

Article Categories



Creating a web part catalog that reads web parts from a central repository (file)

Remark up front: an updated version for the code presented below is here. The screenshot and explanation below are still valid.

One of the features that seems lacking from the web part framework in ASP.NET 2.0 seems to be a catalog part that uses a central repository for defining the available web parts. With the current catalog parts (DeclarativeCatalogPart, ImportCatalogPart and PageCatalogPart) you're left to coding your web parts into the DeclarativeCatalog for each and every page.

When I set out to fix this problem I thought that I might be able to make a subclass from DeclarativeCatalog and by making a small change be able to specify a file location. It turned out to be slightly more complex, because DeclarativeCatalog is a sealed class. It also escapes me why the constructors of GenericWebPart would be protected. Am I missing a static factory method somewhere?

Anyway, here is the code for the catalog part:

#region Using directives

namespace SampleWebParts
{
 public class FileCatalogPart : CatalogPart
 {
  public FileCatalogPart()
  {

  }
  private string _templateLocation;
  public string TemplateLocation
  {
   get
   {
    return _templateLocation;
   }

   set
   {
    _templateLocation = value;
   }
  }


  Hashtable webparts = new Hashtable();
  public override WebPartDescriptionCollection GetAvailableWebPartDescriptions()
  {
   webparts.Clear();
   Collection<WebPartDescription> coll = new Collection<WebPartDescription>();
   
   if (TemplateLocation != null)
   {
    Control container = Page.LoadControl(TemplateLocation);
    if (container != null)
    {
     // You cannot directy iterate over the Controls collection, an excption
     // is thrown that the collection was changed while iterating
     ArrayList iterate = new ArrayList(container.Controls);
     foreach (Control child in iterate)
     {
      WebPart wp = null;
      if (child is WebPart)
      {
       wp = (WebPart)child;
      }
      else
      {
       if (!( child is LiteralControl))
       {
        wp = new PublicCreatableGenericWebPart(child);
       }
      }
      if (wp != null)
      {
       WebPartDescription desc = new WebPartDescription(wp);
       coll.Add(desc);
       webparts[desc] = wp;
      }
     }
    }
   }
   return new WebPartDescriptionCollection(coll);
  }

  public override WebPart GetWebPart(WebPartDescription description)
  {
   return (WebPart)webparts[description];
  }


 }
 public class PublicCreatableGenericWebPart : GenericWebPart
 {
  public PublicCreatableGenericWebPart(Control c): base(c)
  {
  }
 }
}

To use this catalog, you can specify it in your page like this:

<asp:DeclarativeCatalogPart ID="DeclarativeCatalogPart1" Runat="server" Title="Extra parts" >
  <WebPartsTemplate>
    <asp:Calendar ID=cal Runat=server />
  </WebPartsTemplate>
</asp:DeclarativeCatalogPart>
<asp:ImportCatalogPart ID=imp Runat=server />
<asp:PageCatalogPart ID=pagecat Runat=server />
<my:FileCatalogPart id=filecat Runat=Server TemplateLocation="~/catalogtemplate.ascx" Title="Company parts"/>

and finally, you'd have to set up a central file to contain the available web parts for your organization (it actually is an ASCX file, but you shouldn't try to include it in your page):

<%@ Control %>
<asp:Calendar ID=cal Runat=server Title="Calendar"/>
<asp:Login Runat=server ID=lgnBox Title="Login control" >
</asp:Login>

Result:

posted on Friday, October 29, 2004 4:17 PM by TeunD





Powered by Dot Net Junkies, by Telligent Systems