My last piece on a collapsible EditorZone got me really going. This time I’ll show how to create a
CatalogZone which displays a dropdown combobox instead of a list of checkboxes.
There are two main components which need to interact to make this possible. A class derived from
CatalogZone takes care of rendering the header and footer. This class is called
DropDownCatalogZone. The header shows an informative title. The footer is used to display a dropdown combobox which can be used to select a
WebPartZone to add the WebPart to. The footer also shows the ‘Add’ and ‘Close’ buttons used to add a WebPart from the catalog to the page and to close the zone again. For each
CatalogPart which is displayed in the
CatalogZone, a dropdown combobox is rendered by a class derived from
First let’s examine the
DropDownCatalogPartChrome class. It contains one method used to render a
CatalogPart. This method is displayed in figure 1. The implementation takes the following steps:
- Get the WebPart descriptions stored in the
- Create a
- Attach the ID of the list to a preformatted ID in the
CatalogZone. (I’ll explain the why later.)
- Add each WebPart description to the
- Render the list.
public override void RenderCatalogPart(HtmlTextWriter writer,
WebPartDescriptionCollection partDescriptions =
DropDownList list = new DropDownList();
list.Width = new Unit(150, UnitType.Pixel);
list.ID = ((DropDownCatalogZone)Zone).ModuleSelectorControlID;
foreach (WebPartDescription description in partDescriptions)
list.Items.Add(new ListItem(description.Title, description.ID));
writer.Write("Select a module:");
The interesting bit about this code is the use of the
CatalogZone to provide the ID for the
DropDownList. This is necessary because the
Chrome class doesn’t load postback data itself, the
DropDownCatalogZone loads this data based on the ID. By using it on the
DropDownCatalogZone is able to load the
WebPartDescription of the selected item in the list.
DropDownCatalogZone contains the bulk of the code. It will need to perform the following tasks:
- Create an instance of
- Render the header and footer.
- Handle postback data sent by the
- Handle postback data sent by the buttons shown in the footer.
The first step is easy enough. A simple override of the
CreateCatalogPartChrome is sufficient. The rendering of the header is trivial as well, it only writes a title to the output stream.
The third and fourth steps are more of a challenge. The
DropDownCatalogZone will need to override the
RaisePostBackEvent methods. The
LoadPostData method is used to load the selected WebPart and the selected WebPartZone from the posted values.
protected override bool LoadPostData(string postDataKey,
_selectedPart = postCollection[ModuleSelectorControlID];
_selectedZone = postCollection[ZoneSelectorControlID];
The selected WebPart is loaded using the same key as used by the
DropDownCatalogPartChrome class to render the
DropDownList which is rendered in the footer uses the same mechanism as used by the
DropDownCatalogPartChrome class, but it uses a different ID, the
RaisePostBackEvent method only needs to verify whether the postback is performed by the ‘Add’ button, and take the necessary actions to actually add the WebPart to the WebPartZone.
protected override void RaisePostBackEvent(string eventArgument)
if (eventArgument == ((DropDownCatalogVerb)AddVerb).EventArgument &&
AddVerb.Visible && AddVerb.Enabled)
WebPartZoneBase zone = base.WebPartManager.Zones[_selectedZone];
WebPartDescriptionCollection descriptions =
WebPart webPart = SelectedCatalogPart.GetWebPart(
WebPartManager.AddWebPart(webPart, zone, 0);
The rest of the code found in the
DropDownCatalogZone class is plumbing to wire up the ‘Add’ and ‘Remove’ buttons and handle their state management.
Just a few little steps were required to change the default behavior of the
CatalogZone, happy coding!