Wrox Home  
Search
Professional ASP.NET 2.0 Server Control and Component Development
by Shahram Khosravi
August 2006, Paperback


Excerpt from Professional ASP.NET 2.0 Server Control and Component Development

ASP.NET 2.0 WebPartChrome

by Dr. Shahram Khosravi

In ASP.NET 2.0, a WebPartZoneBase zone defines a region on a Web Parts page that contains WebPart controls. This is the base class for all Web Parts zones that contain WebPart controls. A WebPartZoneBase zone uses a WebPartChrome object to render the WebPart controls that the zone contains. This article discusses the WebPartChrome class and develops a custom WebPartChrome chrome to show you how to develop your own custom WebPartChromes to customize the rendering of WebPart controls contained in a zone.

The best way to understand the WebPartChrome class and its extensible methods is to take a look under the hood of the RenderBody method of the WebPartZoneBase class. The following code listing contains the code for the RenderBody method. As the name implies, this method renders the body of the zone. As this code listing shows, this method iterates through the WebPart controls that the zone contains and calls the RenderWebPart method of the WebPartChrome object to render each enumerated WebPart control:

protected override void RenderBody(HtmlTextWriter writer)
{
  writer.RenderBeginTag(HtmlTextWriterTag.Table);
  foreach (WebPart webPart in WebParts)
  {
    writer.RenderBeginTag(HtmlTextWriterTag.Tr);
    writer.RenderBeginTag(HtmlTextWriterTag.Td);
    WebPartChrome.RenderWebPart(writer, webPart);
    writer.RenderEndTag();
    writer.RenderEndTag();
  }
  writer.RenderEndTag();
}

In other words, WebPartZoneBase delegates the responsibility of rendering its WebPart controls to WebPartChrome. This section first takes you under the hood to help you gain a solid understanding of the methods and properties of the WebPartChrome class. Listing 1 shows these methods and properties. The following sections discuss some of these methods and properties in detail.

Listing 1: The WebPartChrome class
public class WebPartChrome
{
  public WebPartChrome(WebPartZoneBase zone, WebPartManager manager);
  public virtual void 
  	RenderWebPart(HtmlTextWriter writer, WebPart webPart);
  protected virtual Style CreateWebPartChromeStyle(
  	WebPart webPart, PartChromeType chromeType)
  private void RenderTitleBar(HtmlTextWriter writer, WebPart webPart);
  protected virtual WebPartVerbCollection GetWebPartVerbs(
  	WebPart webPart);
  protected virtual WebPartVerbCollection FilterWebPartVerbs(
  	WebPartVerbCollection verbs, WebPart webPart);
  private bool ShouldRenderVerb(WebPartVerb verb, WebPart webPart);
  protected string GetWebPartChromeClientID(WebPart webPart);
  protected string GetWebPartTitleClientID(WebPart webPart);
  protected virtual void RenderPartContents(HtmlTextWriter writer, 
                                            WebPart webPart);
  protected WebPartManager WebPartManager {get;}
  protected WebPartZoneBase Zone {get;}
}

RenderWebPart

Listing 2 contains the implementation of the main parts of the RenderWebPart method of the WebPartChrome class. The boldface portions of this code listing shows some of the extensible methods of WebPartChrome class that you can extend to implement your own custom WebPartChrome, as you'll see later in this article.

Listing 2: The RenderWebPart method
public virtual void RenderWebPart(
	HtmlTextWriter writer, WebPart webPart)
{
  PartChromeType chromeType = this.Zone.GetEffectiveChromeType(webPart);
  Style style = CreateWebPartChromeStyle(webPart, chromeType);
  style.AddAttributesToRender(writer, this.Zone);
  writer.AddAttribute(HtmlTextWriterAttribute.Id, 
                      GetWebPartChromeClientID(webPart));
  writer.RenderBeginTag(HtmlTextWriterTag.Table);
  if ((chromeType == PartChromeType.TitleOnly) || 
      (chromeType == PartChromeType.TitleAndBorder))
  {
    writer.RenderBeginTag(HtmlTextWriterTag.Tr);
    writer.RenderBeginTag(HtmlTextWriterTag.Td);
    RenderTitleBar(writer, webPart);
    writer.RenderEndTag();
    writer.RenderEndTag();
  }
  writer.RenderBeginTag(HtmlTextWriterTag.Tr);
  this.Zone.PartStyle.AddAttributesToRender(writer, this.Zone);
  writer.RenderBeginTag(HtmlTextWriterTag.Td);
  RenderPartContents(writer, webPart)
  writer.RenderEndTag();
  writer.RenderEndTag();
  writer.RenderEndTag();
}

As mentioned, the main responsibility of the RenderWebPart method is to render the WebPart control that WebPartZoneBase passes into it. A WebPart control consists of the following two parts:

  • Chrome: The chrome of a WebPart control is a graphical frame on the control that consists of two parts:
    • Title bar: The title bar includes a title text, a title icon, and a verbs menu
    • Border: The border is the portion of the chrome that frames the WebPart control
  • Content: The content of a WebPart control constitutes its body, that is, the part that the chrome frames

The Web Parts Framework uses the PartChromeType enumeration to specify the type of chrome that the RenderWebPart method must render for the specified WebPart control. The following are the possible values of this enumeration:

  • PartChromeType.Default: The WebPart control inherits the chrome type from the zone that contains the control. The WebZone base class exposes a property of type PartChromeType named PartChromeType that specifies the chrome type for all the WebPart controls that the zone contains.
  • PartChromeType.BorderOnly: RenderWebPart will not render the title bar of the specified WebPart control. It will only render the border.
  • PartChromeType.TitleOnly: RenderWebPart will not render the border that frames the WebPart control. It will only render the title bar.
  • PartChromeType.TitleAndBorder: RenderWebPart will render both the title bar and border of the specified WebPart control.
  • PartChromeType.None: RenderWebPart will render neither the border nor the title bar of the specified WebPart control.

As Listing 2 shows, the RenderWebPart method renders a table that contains two rows where each row contains a single cell. As you'll see shortly, the method renders the title bar within the first row and content or body of the WebPart control within the second row.

Therefore, the first order of business for the RenderWebPart method is to render the table that contains the title bar and body of the specified WebPart control. To render this table, RenderWebPart must render the HTML attributes of the associated <table> HTML element. These HTML attributes mainly consists of the "id" and CSS style attributes. RenderWebPart calls the GetWebPartChromeClientID method of the WebPartChrome to return the client ID value of the specified WebPart control and assigns this value to the id attribute of the <table> HTML element that contains the chrome and body of the WebPart control:

writer.AddAttribute(HtmlTextWriterAttribute.Id, 
	GetWebPartChromeClientID(webPart));

What does this mean to you as a control developer? You can call the GetWebPartChromeClientID method to access the value of the id attribute of the containing or main <table> HTML element and use this value in your client-side code to take advantage of the DHTML capabilities of the requesting browser.

RenderWebPart also calls the CreateWebPartChromeStyle method of the WebPartChrome to return the Style object that contains the CSS style attributes of the <table> HTML element that contains the chrome and body of the specified WebPart control.

The default implementation of CreateWebPartChromeStyle builds a Style object based on the chrome type of the specified WebPart control. RenderWebPart calls the GetEffectiveChromeType method of its associated zone to return the chrome type of the WebPart control and passes the chrome type to the CreateWebPartChromeStyle method to return the Style object:

PartChromeType chromeType = this.Zone.GetEffectiveChromeType(webPart);
Style style = CreateWebPartChromeStyle(webPart, chromeType);
style.AddAttributesToRender(writer, this.Zone);

This means two things to you as a developer. First, you can override the CreateWebPartChromeStyle method in your custom WebPartChrome to customize the CSS style attributes of the containing <table> HTML element. Second, you can override the GetEffectiveChromeType method of the WebZone zone to customize the chrome type that is passed into the CreateWebPartChromeType.

Finally, RenderWebPart must render the <table> HTML element itself:

writer.RenderBeginTag(HtmlTextWriterTag.Table);