Introduction
Controls introduced by Microsoft are simple ones and rarely used by live Web applications in the market. Panel is such a control. Because of its simplicity, the look-and-feel of the Panel control is not consistent in every browser.
Background
Panel control plays a crucial role in most Web applications. Microsoft introduced Panel control which groups related widgets together. Especially, it draws a curved-corner panel with the title appearing on the top-left, like below. Interesting, isn't it?
<asp:Panel ID="panel1" runat="server" GroupingText="Product Information">
…</asp:Panel>
Unfortunately, the look-and-feel is not the same in other browsers (FireFox, Safari, Opera and Chrome). The curve-corner panel turns into a rectangle. The top-right and left-bottom corners are broken. When I looked at some open source frameworks, I found that they did not have any solutions or workarounds for this.
I searched for some workarounds on the Internet but the look-and-feel is still not as good as it is shown on the Internet Explorer browser. I tried to look for a better panel on the Internet, but no one met my demands perfectly. Then I decided to write my own Panel Web Control.
Using the Extend Panel Web Control
By adding a reference to a separate library project that contains the panel control, you can use it in your code easily.
With Panel Web Control (named as "PDTPanel
") in mind, the code looks like:
<webcontrols:PDTPanel ID="pnlTest" runat="server"
GroupingTitle="Product Information" GroupingIconUrl="icon_edit.gif"
Shadow="true" Width="200px" AllowExpandCollapse="true" />
Now you can see the consistent look-and-feel in various browsers: Internet Explorer, FireFox, Safari, Opera and Google Chrome.
By adding up some customization, I come up with a stronger container control as below:
It looks nice, doesn't it?
Panel control supports "Expand/Collapse" capability. You can enable this feature by setting AllowExpandCollapse=true
.
Now you can look at the following attributes that panel control currently supports:
Attributes | Description |
Width | If you set its value as “Auto ”, control will automatically shrink to fit its content inside |
Shadow | Drop a shadow surrounding panel |
GroupingTitle | Title of panel |
GroupingIconUrl | Display an icon next to GroupingTitle |
AllowExpandCollapse | Allow/disallow the expand/collapse feature (appears on the top-right corner) |
ExpandIconUrl | Specify the URL of icon which will override the built-in Expand icon (embedded image) |
CollapseIconUrl | Specify the URL of icon which will override the built-in Collapse icon (embedded image) |
InitialState | Specify the initial state (expand|collapse). By default, it is in "expand" state. |
ExpandTooltip | Specify the tooltip of expand/collapse icon when user moves mouse over it. Default value is "Click to expand" |
CollapseTooltip | Specify the tooltip of expand/collapse icon when user moves mouse over it. Default value is "Click to collapse" |
BackgroundUrl | Fill the whole inner area with specified background |
AdjustedWidth | An additional attribute to defeat Internet Explorer bug (except Internet Explorer 8.0). Because of Internet Explorer bug, panel control cannot shrink to fit the content inside perfectly. To get around this problem, a fixed value for "AdjustedWidth " will override the current width of the panel control |
Notes: Google Chrome doesn't accept Image URL without specifying the slash "/". It requires that Image URL must always begin with slash, otherwise image cannot display correctly. Meanwhile, other browsers (Internet Explorer, FireFox, Safari, Opera) accept Image URL without slash "/".
Examples:
BackgroundUrl="/background.gif"
GroupingIconUrl="/icon_edit.gif"
ExpandIconUrl="/expand.gif
CollapseIconUrl="/collapse.gif"
Inside the C# Web Control Code
I put all stuff in an assembly, including a Web Control and embedded images/CSS.
The implementation for this control is very simple. First, place all the child/nested controls in an ArrayList
variable (used by some private
functionalites). Override functions AddParsedSubObject()
and CreateChildControls()
.
protected override void AddParsedSubObject(Object obj)
{
_items.Add(obj);
}
protected override void CreateChildControls()
{
System.Collections.IEnumerator myEnumerator = _items.GetEnumerator();
while (myEnumerator.MoveNext())
{
Control ctr = (Control)myEnumerator.Current;
this.Controls.Add(ctr);
}
}
Second, the look-and-feel of panel will be made through overriding function Render()
:
protected override void Render(HtmlTextWriter output)
{
...
}
As a result, HTML table and cells are rendered as below:
Embedded Resources
Because I put all the images/CSS files inside the same assembly with web control, these resources must be embedded. Please learn more about Web Resource on MSDN.
After all the resources have been embedded, the following code snippet will extract the URL of the resource:
string imageWebResourceUrl;
imageWebResourceUrl = Page.ClientScript.GetWebResourceUrl(this.GetType(),
"TruongPham.WebControls.Images" +
((Shadow == true) ? ".WithShadow" : "") +
".DetailLeftTop.gif");
Dynamic ClientID: ContentRegionID
This is a private
property assigned to content region inside the panel control. This is being used for JavaScript code snippet to fire expand/collapse event. Note that ContentRegionID
should NOT be a fixed value, otherwise a conflict occurs when using multiple panel controls in the same Web page. It’s better to associate this property with a GUID
.
private string _controlGUID = System.Guid.NewGuid().ToString("P");
private string _contentRegionid = string.Empty;
private string ContentRegionID
{
get
{
if (_contentRegionid == string.Empty)
_contentRegionid = "contentRegion_" + _controlGUID;
return _contentRegionid;
}
}
Browser Compatibility
This control works fine with Internet Explorer, FireFox, Safari, Opera and Google Chrome. Because I use image to render panel, the look-and-feel is pretty much the same for all browsers, except for some slight differences among browsers. The different browsers treat “width:100%
” in different ways. As you look at the body of function Render()
, you can see the following code snippet that defeats a bug which occurs only in Internet Explorer 8.0, Safari and Chrome.
if (Page.Request.Browser.Browser.ToLower() == "applemac-safari" ||
(Page.Request.Browser.Browser.ToLower() == "ie" &&
Page.Request.Browser.Version == "8.0")
)
sbOut.AppendLine("<td style='WIDTH:" + _maxWidth +
"px; BACKGROUND: url(" + imageWebResourceUrl +
")'></td>");
else
sbOut.AppendLine("<td style='BACKGROUND: url(" +
imageWebResourceUrl + ")'></td>");
DOCTYPE
DOCTYPE
is also a problem for browser compatibility. I came across this when I found that my Web page contained the DOCTYPE
:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
My Web page worked fine in Internet Explorer (version 5.5, 6.0 and 7.0), but for browsers Internet Explorer 8.0, FireFox, Safari, Opera and Chrome, the look-and-feel has been broken due to issue of the above DOCTYPE
.
So in order to use this panel control correctly, you should avoid using the above DOCTYPE
.
Known Issues
- Performance
If we set width=”auto”
, the control will search child controls to determine the maximum width. This could be time-consuming if there are lots of child/nested controls, leading to low performance for rendering the whole container. To avoid this, we will need to set the fixed width for container.
Example: width=”300px”
- Icon Size
If you set icon size too big, the layout might be broken. This container control is designed in such a way that icon size is supposed to be 16x16.
Summary
No size fits all. This container might not work fine in some unknown special cases, but could be definitely customized to fit your own needs. Please let me know if there are some other things that need to be added.
Any suggestion could be mailed to me:
Henry, Pham Dinh Truong (Mr.)
Email: phdtruong@yahoo.com
Address: GrapeCity Inc., 6 Yen The st, Hanoi, Vietnam
Happy coding!
History
- Version 1.0 (15 May, 2009) - Initial release