Click here to Skip to main content
Click here to Skip to main content

Create an ASP.NET Rounded Panel WebControl

By , 25 Sep 2007
 
Screenshot - RoundedPanel.jpg

Introduction

There are perhaps hundreds of ideas on the internet regarding how to make those sleek rounded "Web 2.0" panels (as depicted above) that can be seen on millions of websites these days. Undoubtedly, there are many server controls that do the same thing. I've seen some good, and most bad. This was my attempt at creating a sleek solution to what certainly should be a simple problem.

Background

Because there is no one "right" answer to making rounded corners, I opted for what I deemed to be the simplest and highest performance solution. From a scalability standpoint, it didn't make sense to have to do it with images. While I'm a fan of JavaScript, I wanted to plan for the times when the client has JavaScript turned off. Sure, it's rare, but it happens. Finally, I wanted to encapsulate all of this functionality into a drag-n-drop server control that would require minimal configuration in Visual Studio and, of course, be cross-browser compliant.

Because I'm no CSS genius, I looked around on the web to find a few solutions that did what I wanted to do. I really just wanted pure CSS, and, as I said above, no images or JavaScript. I found exactly what I wanted on Stu Nicholls' website, CSSPlay. He had an elegant CSS solution that seemed like it would work well inside of a web control. And, since he didn't mind anyone using his code, I thought this would be the best approach. Thanks, Stu!

Inside the Code

The control itself contains only five properties and one overridden method. I allow the user to configure the Panel Border Color, Panel Text Color, Panel Inner Background Color, Panel Outer Background Color and the text inside of the panel. Sure, you can nest controls in the panel (it inherits from the ASP Panel control), but sometimes you don't want to have to configure a label control. Setting the text makes it simpler.

The method simply overrides the RenderContents method to output the CSS I needed nested in style tags, and the divs and nested tags that comprise the panel. I changed the CSS to reference elements by its unique Client ID, so it becomes feasible to have several panels on a page that have varying styles (as in the screenshot above). All the rest of the design functionality is inherited from the Panel control, including visibility.

On a final note, I made sure to render any child controls between paragraph tags. It makes the final panel rendering nice and neat. Yes, you can also use output.WriteBeginTag("p"); if you so choose. I like output.Write();

if (HasControls())
{
     output.Write("<p>");
     this.RenderChildren(output);
     output.Write("</p>");
}

Using the Code

I included the output DLL (Web2Controls.dll) in the downloadable source as well as the code file. You can simply add it to your toolbox, drag the control on your page, and start adding nested controls. All of the properties are located under the "Rounded Panel" category, and have defaults set. The panel also accounts for differing height and width units. You can use percentages or pixels with either. Because it inherits its designer attributes from the Panel control, you won't get a graphic representation of the panel (color and style wise) until you run it. It will simply display as any Panel would, and you can drag or drop controls on it.

I tested this in IE6, IE7 and Firefox, and didn't have any problems. I don't have Opera or Safari installed locally, so if any of you test with those platforms, I'd be interested to hear your results.

Happy UI'ing!

History

  • 9/25/07 - Removed a stray paragraph tag that was in for testing
  • 9/22/07 - Added closing div tag to output rendering

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)

About the Author

UsualDosage
Web Developer
United States United States
Member
I have been an ASP.NET/C# Programmer for about 7 years, specializing in business applications for financial institutions. I formerly wrote business applications for mortgage banking front-ends in C++ before switching to the .NET Framework, which I program in almost exclusively, now, except for my occasional contract dalliances in PHP and MySQL, which I really like. I especially enjoy graphic design, and web work.

In my spare time I run the local internet radio portal Jaxrockradio.com.

I have long moonlighted as an ANSI C programmer for several online MUDs (still a hobby of mine), and probably will continue to as long as they let me.

You can view my blog by visiting http://www.usualdosage.com.

My site design portfolio is located at http://design.usualdosage.com

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralWhy the label cannot show inside the rounded panelmemberYee Cheing Seah24 Jun '09 - 18:12 
Hi, this lib is cool, but i meet the problem. since i put the label inside the rounded panel. The label cannot been show. Can i know how to solve it. thank ya
 
<embed src="http://www.blingyblob.com/glittermatic/holder.swf?message=Elaine%20Seah&font=fonts/font15.swf&glitter=glitters/glitter7.swf&swfHeight=85&bevel=1&shadow=1&glow=1&blur=0&fade=1&blink=0&fontsize=53&num=7" quality="high" wmode="transparent" bgcolor="ffffff" width="500" height="85" name="glitters" align="middle" allowScriptAccess="samedomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" >


GeneralRe: Why the label cannot show inside the rounded panelmemberYee Cheing Seah25 Jun '09 - 18:15 
i have to found the solution for this. Thank ya. And i meet up other problem is when i print the page. The top and bottom border will disappear. i have no idea to make it ? can any one help?
 
<embed src="http://www.blingyblob.com/glittermatic/holder.swf?message=Elaine%20Seah&font=fonts/font15.swf&glitter=glitters/glitter7.swf&swfHeight=85&bevel=1&shadow=1&glow=1&blur=0&fade=1&blink=0&fontsize=53&num=7" quality="high" wmode="transparent" bgcolor="ffffff" width="500" height="85" name="glitters" align="middle" allowScriptAccess="samedomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" >


GeneralRe: Why the label cannot show inside the rounded panelmemberwasanaeng4 Aug '09 - 8:15 
Hi,
 
I had the same problem as you mentioned in labels
 
So I change the span properties in the rounded panel
.....
sbOut.Append("* html .xrounded em {width:24px; height:12px; width:0; height:0;}");
            sbOut.Append("#" + id + " .xrounded span {display:inline; width:auto; height:auto; color:" + borderColor +
                "; overflow:hidden; border-top:10px solid " + panelColor + "; border-left:10px dotted transparent; border-right:10px dotted transparent; margin-left:0px; margin-top:0px;}");
            sbOut.Append("* html .xrounded span {width:20px; height:10px; width:0; height:0;}");
.....
Thanks
 
Regards
 
Wasana
Sri LankaThumbs Up | :thumbsup:
GeneralRe: Why the label cannot show inside the rounded panelmemberMember 415218429 Jun '11 - 0:18 
even i have a same problem..
i want to display a lable in rounded panel plz help me...
thans in advance
GeneralFix Rendering Child controls bugmemberdreammaker_tr27 Nov '07 - 3:42 
Why we have that bug; cause when adding child control (like label control) our roundedpanel control style "span attribute" hide or break our child controls. If look the source of the page we see all controls there but not show on page.
 

Now, i fix this error 3 steps.
1.Remove RenderContents
2.Add override Render Children
3.Add override Render
 
and In sytle remove span keyword.
 
override RenderChildren
 
<code>
protected override void RenderChildren(HtmlTextWriter output)
            {
                  if (HasControls())
                  {
 
                        for (int i = 0; i <= Controls.Count - 1; i++)
                        {
                              Controls[i].RenderControl(output);
                        }
                  }
            }
</code>
 
override Render
 
<code>
protected override void Render(HtmlTextWriter output)
            {
                  string borderColor = ColorTranslator.ToHtml(PanelBorderColor);
                  string backColor = ColorTranslator.ToHtml(PanelOuterBackColor);
                  string panelColor = ColorTranslator.ToHtml(PanelInnerBackColor);
                  string foreColor = ColorTranslator.ToHtml(PanelTextColor);
                  string id = ClientID + "_inner";
 
                  StringBuilder sbOut = new StringBuilder();
 
                  // Build the CSS
                  sbOut.Append("<style type=\"text/css\">#" + id + " {background:" + backColor + "; width:" + Width + "; height:" + Height + "; margin:0px; padding:0px;}");
                  sbOut.Append("#" + id + " .xrounded p {marginBlush | :O 10px; letter-spacing:1px;}");
                  sbOut.Append("#" + id + " .xrounded p {padding-bottomBlush | :O .5em; color:" + foreColor + ";}");
                  sbOut.Append("#" + id + " .xrounded {background: transparent; margin:0em;}");
                  sbOut.Append("#" + id + " .xrounded em {display:block; width:10; height:10; color:" + foreColor +
                        "; overflow:hidden; border-top:12px solid " + borderColor + "; border-left:12px dotted transparent; border-right:12px dotted transparent; margin-left:50px;}");
                  sbOut.Append("* html .xrounded em {width:24px; height:12px; widthBlush | :O ; heightBlush | :O ;}");
                  sbOut.Append("* html .xrounded span {width:20px; height:10px;}");
                  sbOut.Append(".xb1, .xb2, .xb3, .xb4, .xb5, .xb6, .xb7 {display:block; overflow:hidden; font-sizeBlush | :O ;}");
                  sbOut.Append(".xb1, .xb2, .xb3, .xb4, .xb5, .xb6 {height:1px;}");
                  sbOut.Append("#" + id + " .xb4, #" + id + " .xb5, #" + id + " .xb6, #" + id +
                        " .xb7 {background:#ccc; border-left:1px solid " + borderColor +
                        "; border-right:1px solid " + borderColor + ";}");
                  sbOut.Append("#" + id + " .xb1 {marginBlush | :O 8px; background:" + borderColor + ";}");
                  sbOut.Append("#" + id + " .xb2 {marginBlush | :O 6px; background:" + borderColor + ";}");
                  sbOut.Append("#" + id + " .xb3 {marginBlush | :O 4px; background:" + borderColor + ";}");
                  sbOut.Append("#" + id + " .xb4 {marginBlush | :O 3px; background:" + panelColor + "; border-widthBlush | :O 5px;}");
                  sbOut.Append("#" + id + " .xb5 {marginBlush | :O 2px; background:" + panelColor + "; border-widthBlush | :O 4px;}");
                  sbOut.Append("#" + id + " .xb6 {marginBlush | :O 2px; background:" + panelColor + "; border-widthBlush | :O 3px;}");
                  sbOut.Append("#" + id + " .xb7 {marginBlush | :O 1px; background:" + panelColor + "; border-widthBlush | :O 3px; height:2px;}");
                  sbOut.Append("#" + id + " .xboxcontent {display:block; background:" + panelColor +
                        "; border:3px solid " + borderColor + "; border-widthBlush | :O 3px;}</style>");
 
                  // Start Build the panel structure
                  sbOut.Append("<div id=\"" + id + "\">");
                  sbOut.Append("<div class=\"xrounded\" style=\"height: 100%\">");
                  sbOut.Append("<b class=\"xb1\"></b><b class=\"xb2\"></b><b class=\"xb3\"></b><b class=\"xb4\"></b><b class=\"xb5\"></b><b class=\"xb6\"></b><b class=\"xb7\"></b>");
                  sbOut.Append("<div class=\"xboxcontent\" style=\"height: 100%\">");
                  output.Write(sbOut.ToString());
 
                  //Render Children controls
                  this.RenderChildren(output);
 
                  // End Build the panel structure
                  output.Write("</div>");
                  output.Write("<b class=\"xb7\"></b><b class=\"xb6\"></b><b class=\"xb5\"></b><b class=\"xb4\"></b><b class=\"xb3\"></b><b class=\"xb2\"></b><b class=\"xb1\"></b>");
                  output.Write("</div>");
                  output.Write("</div>");
            }
</code>
 
Happy programming.
GeneralNested Controls not working for mememberrlax3115 Nov '07 - 2:04 
I can create the panel, but when I try to put a control in it and set a property of the control from the code behind, the changes to the control do not render.
 
Example:   If I put a Label in my rounded panel, then try to set it's Text property, the label will not show my text.   Sometimes it even shows some weird triangle where the label should be.   If I comment out your CSS, the panel works fine.
 
Code example:
aspx:
.
.
.
<body>
     <form id="form1" runat="server">
          <ucl:RoundedPanel ID="pnlRoundedPanel" runat="server" Width="300px">
               This text will show
         
               <br />
         
               <asp:Label ID="lblLabel" runat="server" />
          </ucl:RoundedPanel>
     </form>
</body>
.
.
.
 
cs:
protected void Page_Load(object sender, EventArgs e)
{
     lblLabel.Text = "This text will not";
}
 
From what your article says this should work.   And what's the deal with the weird triangle?   There is nothing special about the page, no master page or other styles.   Just a blank page.
GeneralRe: Nested Controls not working for mememberSteven Szelei11 May '10 - 20:07 
Label does not work unles you do something such as
 
foreach (Control ctrl in this.Controls)
     {
         if (ctrl.GetType().Equals(typeof(Label)))
             output.Write(((Label)ctrl).Text);
         else
             ctrl.RenderControl(output);                    
     }
 
But by doing so you miss the standard html tags embeded between the controls.
 
I have found if you use ASP:Literal everything works fine with the code provided by the author.
 
If someone has a way of determining and parsing all elements within the parent and then rendering appropreatly I would like to see that. I have not attempted to over ride the render function to determine if it could be used to detect Labels and render them in line appropreatly.
 
Regs,
 
Steven
QuestionBorder WidthmemberBen Millspaugh23 Oct '07 - 7:03 
Is there any way to change the rounded corder border width? I would like a thin (1px) border if possible.
AnswerRe: Border WidthmemberUsualDosage23 Oct '07 - 8:08 
Please read comments below by "intooitive".
 
Quae narravi nullo modo negabo.

QuestionData Binding ProblemmemberBen Millspaugh23 Oct '07 - 6:49 
I am trying to use the rounded panel in a DataList template but the id does not change when it is rendered so the class names don't work.   For example, in the code below the id for "Label1" will be changed to "DataList1_ctl00_Label1" for the 1st item in the list and "DataList1_ctl01_Label1" for the 2nd item, and so on.   But the RoundedPanel remains "RoundedPanel1" thoughout causing formatting issues in the page (i.e. nothing displays).
 
      <asp:DataList ID="DataList1" runat="server" DataSourceID="SqlDataSource1">
            <ItemTemplate>
                  <cc2:RoundedPanel id="RoundedPanel1" runat="server">
                        <asp:Label ID="Label1" runat="server" Text='<%# Eval("FieldName") %>'></asp:Label>
                  </cc2:RoundedPanel>
            </ItemTemplate>
      </asp:DataList>
 
Thanks in advance for any help!

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130523.1 | Last Updated 25 Sep 2007
Article Copyright 2007 by UsualDosage
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid