Custom rendering of WebParts in ASP.NET

Damir Dobric Posts

Next talks:

 

    

Follow me on Twitter: #ddobric



 

 

Archives

By using of ASP.NET WebParts, sometimes it might be useful to implement custom look and feel of the web part.  The existing web part framework enables you to customize the design (chrome) of the web part by simply changing of html style.

By using of this technique, it is unfortunately not possible to take the full control of rendering of the web part.

 

Because of that I extended the web part functionality by implementing of the custom WebPartZone and WebPartChrome classes. In this post I will show how to do that.

 

First, the new custom WebPartZone has to be implemented. The new zone class DZone derives from WebPartZone is responsible to define which WebPartChrome class has to be utilized by WebPartManager. Following code shows the full implementation of the custom zone class:

 

namespace SpsGadget{

public class DZone : WebPartZone {

private Unit m_BorderWidth = new Unit(1, UnitType.Pixel);

      protected override WebPartChrome CreateWebPartChrome() {

      return new DChrome(this, base.WebPartManager);

      } 

   }

 }

Now the WebPartChrome class has to be extended. For this reason I implemented the new class DChrome, which derives from WebPartChrome.

The method RenderWebPart is invoked when the certain web part has to be rendered. In this method all magic is done:

 

public class DChrome : WebPartChrome

    {

        public DChrome(DZone zone, WebPartManager mgr) : base (zone, mgr)

        {

           

        }

 

        /// <summary>

        /// Called when the WebPart-chrome and webpart content have to be rendered.

        /// </summary>

        /// <param name="writer"></param>

        /// <param name="webPart"></param>

        public override void RenderWebPart(HtmlTextWriter writer, WebPart webPart)

        {

            PartChromeType chromeType = this.Zone.GetEffectiveChromeType(webPart);

            Style style0 = CreateWebPartChromeStyle(webPart, chromeType);

            style0.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();

 

            return;

 

        }

 

 

        /// <summary>

        /// Here we implement our custom webpart renderer.

        /// </summary>

        /// <param name="writer"></param>

        /// <param name="webPart"></param>

        private void renderTitleBar(HtmlTextWriter writer, WebPart webPart)

        {

            writer.AddAttribute(HtmlTextWriterAttribute.Cellspacing, "0");

            writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding, "0");

            writer.AddAttribute(HtmlTextWriterAttribute.Border, "0");

            writer.AddStyleAttribute(HtmlTextWriterStyle.Width, "100%");

            writer.RenderBeginTag(HtmlTextWriterTag.Table);

            writer.RenderBeginTag(HtmlTextWriterTag.Tr);

          

            int num1 = 1;

            bool flag1 = this.Zone.ShowTitleIcons;

            string text1 = null;

            if (flag1)

            {

                text1 = webPart.TitleIconImageUrl;

                if (!string.IsNullOrEmpty(text1))

                {

                    num1++;

                    writer.RenderBeginTag(HtmlTextWriterTag.Td);

                    this.renderTitleIcon(writer, webPart);

                    writer.RenderEndTag();

                }

            }

            writer.AddStyleAttribute(HtmlTextWriterStyle.Width, "100%");

            TableItemStyle style1 = this.Zone.PartTitleStyle;

            if (!style1.Wrap)

            {

                writer.AddStyleAttribute(HtmlTextWriterStyle.WhiteSpace, "nowrap");

            }

            HorizontalAlign align1 = style1.HorizontalAlign;

            if (align1 != HorizontalAlign.NotSet)

            {

                TypeConverter converter1 = TypeDescriptor.GetConverter(typeof(HorizontalAlign));

                writer.AddAttribute(HtmlTextWriterAttribute.Align, converter1.ConvertToString(align1).ToLower(CultureInfo.InvariantCulture));

            }

            VerticalAlign align2 = style1.VerticalAlign;

            if (align2 != VerticalAlign.NotSet)

            {

                TypeConverter converter2 = TypeDescriptor.GetConverter(typeof(VerticalAlign));

                writer.AddAttribute(HtmlTextWriterAttribute.Valign, converter2.ConvertToString(align2).ToLower(CultureInfo.InvariantCulture));

            }

            //if (this.Zone.RenderClientScript)

            {

                writer.AddAttribute(HtmlTextWriterAttribute.Id, this.GetWebPartTitleClientID(webPart));

            }

            writer.RenderBeginTag(HtmlTextWriterTag.Td);

            if (flag1 && !string.IsNullOrEmpty(text1))

            {

                writer.Write("&nbsp;");

            }

            this.renderTitleText(writer, webPart);

            writer.RenderEndTag();

            this.renderVerbsInTitleBar(writer, webPart, num1);

            writer.RenderEndTag();

            writer.RenderEndTag();

        }

 

        private void renderTitleIcon(HtmlTextWriter writer, WebPart webPart)

        {

            //throw new Exception("The method or operation is not implemented.");

        }

 

        private void renderVerbsInTitleBar(HtmlTextWriter writer, WebPart webPart, int num1)

        {

            //throw new Exception("The method or operation is not implemented.");

        }

 

        private void renderTitleText(HtmlTextWriter writer, WebPart webPart)

        {

            writer.Write(DateTime.Now.ToString());

        }

 

        /// <summary>

        /// Use this method to append additiona javascripts.

        /// </summary>

        public override void PerformPreRender()

        {

            base.PerformPreRender();

        }

    }

 

The web part is always rendered as HTML table, with the title and content of the template zone. The table containing web part content has a title, which plays important role during drag and drop process in design mode. The title is rendered in the method renderTitleBar(). The method can be fully customized. However the title TD-tag has to always have the id, which is used during drag and drop process.

The id is set by following line of code:

 

writer.AddAttribute(HtmlTextWriterAttribute.Id, this.GetWebPartTitleClientID(webPart));

 

If the id is not set, the user will not be able move the web part. Because of that, be sure that he custom implementation sets the id on the proper value as shown in previous code-snippet.

 

The last code-snippet shows how to declare custom controls in the ASPX page:

 

<cc1:DZone ID="DZone3" runat="server" BorderColor="#CCCCCC" Font-Names="Verdana"

                        Padding="6" Height="87px" Width="305px">

                        <PartChromeStyle BackColor="#00F300" BorderColor="#D1DDF1" Font-Names="Verdana" ForeColor="#003300" />

                        <MenuLabelHoverStyle ForeColor="#D1DDF1" />

                        <EmptyZoneTextStyle Font-Size="0.8em" />

                        <MenuLabelStyle ForeColor="White" />

                        <MenuVerbHoverStyle BackColor="#EFF3FB" BorderColor="#CCCCCC" BorderStyle="Solid"

                            BorderWidth="1px" ForeColor="#333333" />

                        <HeaderStyle Font-Size="0.7em" ForeColor="#CCCCCC" HorizontalAlign="Center" />

                        <MenuVerbStyle BorderColor="#507CD1" BorderStyle="Solid" BorderWidth="1px" ForeColor="White" />

                        <PartStyle Font-Size="0.8em" ForeColor="#333333" />

                        <TitleBarVerbStyle Font-Size="0.6em" Font-Underline="False" ForeColor="White" />

                        <MenuPopupStyle BackColor="#507CD1" BorderColor="#CCCCCC" BorderWidth="1px" Font-Names="Verdana"

                            Font-Size="0.6em" />

                        <PartTitleStyle BackColor="#507CD1" Font-Bold="True" Font-Size="0.8em" ForeColor="White" />

                        <ZoneTemplate>

                            <asp:Button ID="Button1" runat="server" Height="46px" Width="183px" />

                        </ZoneTemplate>

                    </cc1:DZone>

 

 


Posted Sep 04 2006, 03:37 PM by Damir Dobric
Filed under:

Comments

Darth Dog wrote Rendere draggabile una WebPartChrome custom
on 10-04-2007 22:10

Rendere draggabile una WebPartChrome custom

Márcio Martins wrote re: Custom rendering of WebParts in ASP.NET
on 06-04-2008 17:01

Thanks it help me to clean the table the webpart generates, but the verbs bar disapeared, I guess it it because the renderVerbsInTitleBar is not implemented. But how can i implement it?

Thanks in advance.

marciocmartins (at) hotmail

r4 nds wrote re: Custom rendering of WebParts in ASP.NET
on 10-13-2009 8:33

what are the WebPartZone and WebPartChrome classes? I dint get anything at all.........Please provide information over it. Provide links to related topics if possible.

developers.de is a .Net Community Blog powered by daenet GmbH.