跨浏览器面板 Web 控件






4.61/5 (17投票s)
标准面板控件在大多数浏览器中布局不佳。这里介绍一个全新的面板网页控件,它在所有浏览器中都具有一致的外观和感受。

引言
微软推出的控件都很简单,很少被市场上实际的Web应用程序使用。面板就是这样的一个控件。由于其简单性,面板控件的外观在每个浏览器中都不一致。
背景
面板控件在大多数Web应用程序中扮演着关键角色。微软推出了面板控件,它将相关的部件分组在一起。特别是,它绘制一个带圆角的面板,标题显示在左上方,如下所示。很有趣,不是吗?
<asp:Panel ID="panel1" runat="server" GroupingText="Product Information">
…</asp:Panel>
不幸的是,在其他浏览器(FireFox、Safari、Opera和Chrome)中,其外观并不相同。圆角面板变成了矩形。右上角和左下角都损坏了。当我查看一些开源框架时,我发现它们没有提供任何解决方案或变通方法。

我在网上搜索了一些变通方法,但外观仍然不如在Internet Explorer浏览器中显示的好。我试图在网上寻找一个更好的面板,但没有一个能完美满足我的要求。于是我决定编写自己的面板网页控件。
使用扩展面板网页控件
通过添加对包含面板控件的单独库项目的引用,您可以在代码中轻松使用它。
考虑到面板网页控件(命名为“PDTPanel
”),代码如下
<webcontrols:PDTPanel ID="pnlTest" runat="server"
GroupingTitle="Product Information" GroupingIconUrl="icon_edit.gif"
Shadow="true" Width="200px" AllowExpandCollapse="true" />
现在您可以在各种浏览器中看到一致的外观:Internet Explorer、FireFox、Safari、Opera和Google Chrome。

通过添加一些自定义,我得到了一个更强大的容器控件,如下所示

看起来不错,不是吗?

面板控件支持“展开/折叠”功能。您可以通过设置AllowExpandCollapse=true
来启用此功能。
现在您可以查看面板控件目前支持的以下属性
属性 | 描述 |
宽度 |
如果您将其值设置为“Auto ”,控件将自动收缩以适应其内容 |
阴影 |
在面板周围投射阴影 |
分组标题 |
面板标题 |
分组图标网址 |
在GroupingTitle 旁边显示一个图标 |
允许展开折叠 |
允许/不允许展开/折叠功能(出现在右上角) |
展开图标网址 |
指定将覆盖内置展开图标(嵌入图像)的图标URL |
折叠图标网址 |
指定将覆盖内置折叠图标(嵌入图像)的图标URL |
InitialState |
指定初始状态(展开|折叠)。默认情况下,它处于“展开”状态。 |
展开工具提示 |
当用户将鼠标悬停在展开/折叠图标上时,指定其工具提示。默认值为“点击展开” |
折叠工具提示 |
当用户将鼠标悬停在展开/折叠图标上时,指定其工具提示。默认值为“点击折叠” |
背景网址 |
用指定的背景填充整个内部区域 |
调整宽度 |
一个额外的属性,用于解决Internet Explorer的bug(Internet Explorer 8.0除外)。由于Internet Explorer的bug,面板控件无法完美收缩以适应其内部内容。 为了解决这个问题," AdjustedWidth "的固定值将覆盖面板控件的当前宽度 |
注意:Google Chrome不接受没有指定斜杠“/”的图片URL。它要求图片URL必须始终以斜杠开头,否则图片无法正确显示。同时,其他浏览器(Internet Explorer、FireFox、Safari、Opera)接受没有斜杠“/”的图片URL。
示例
BackgroundUrl="/background.gif"
GroupingIconUrl="/icon_edit.gif"
ExpandIconUrl="/expand.gif
CollapseIconUrl="/collapse.gif"
C# Web控件代码内部
我将所有内容都放在一个程序集中,包括一个Web控件和嵌入的图像/CSS。

这个控件的实现非常简单。首先,将所有子控件/嵌套控件放入一个ArrayList
变量中(由一些private
功能使用)。重写函数AddParsedSubObject()
和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);
}
}
其次,面板的外观将通过重写函数Render()
来完成
protected override void Render(HtmlTextWriter output)
{
...//Main code goes here
}
结果,HTML表格和单元格渲染如下

嵌入式资源
因为我将所有图像/CSS文件与Web控件放在同一程序集中,所以这些资源必须是嵌入式的。请在MSDN上了解更多关于Web资源的信息。
所有资源嵌入后,以下代码片段将提取资源的URL
string imageWebResourceUrl;
imageWebResourceUrl = Page.ClientScript.GetWebResourceUrl(this.GetType(),
"TruongPham.WebControls.Images" +
((Shadow == true) ? ".WithShadow" : "") +
".DetailLeftTop.gif");
动态 ClientID:ContentRegionID
这是一个分配给面板控件内部内容区域的private
属性。它用于JavaScript代码片段来触发展开/折叠事件。请注意,ContentRegionID
不应是固定值,否则在同一Web页面中使用多个面板控件时会发生冲突。最好将此属性与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;
}
}
浏览器兼容性

此控件在 Internet Explorer、FireFox、Safari、Opera 和 Google Chrome 中运行良好。由于我使用图像渲染面板,因此所有浏览器的外观基本相同,只是浏览器之间略有差异。不同的浏览器处理“width:100%
”的方式不同。当您查看函数 Render()
的主体时,您可以看到以下代码片段,它解决了仅在 Internet Explorer 8.0、Safari 和 Chrome 中出现的 bug。
//Safari, Google Chrome
if (Page.Request.Browser.Browser.ToLower() == "applemac-safari" ||
(Page.Request.Browser.Browser.ToLower() == "ie" &&
Page.Request.Browser.Version == "8.0") //IE 8.0
)
sbOut.AppendLine("<td style='WIDTH:" + _maxWidth +
"px; BACKGROUND: url(" + imageWebResourceUrl +
")'></td>");
else
sbOut.AppendLine("<td style='BACKGROUND: url(" +
imageWebResourceUrl + ")'></td>");
DOCTYPE
DOCTYPE
也是浏览器兼容性的一个问题。当我发现我的网页包含 DOCTYPE
时,我遇到了这个问题
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
我的网页在 Internet Explorer(版本 5.5、6.0 和 7.0)中运行良好,但对于浏览器 Internet Explorer 8.0、FireFox、Safari、Opera 和 Chrome,由于上述 DOCTYPE
的问题,外观被破坏了。

因此,为了正确使用此面板控件,您应该避免使用上述 DOCTYPE
。
已知问题
- 性能
如果我们设置
width=”auto”
,控件将搜索子控件以确定最大宽度。如果子控件/嵌套控件很多,这可能会很耗时,导致整个容器渲染性能低下。为了避免这种情况,我们需要为容器设置固定宽度。
示例:width=”300px”
- 图标大小
如果图标尺寸设置得太大,布局可能会被破坏。此容器控件的设计使得图标尺寸应为 16x16。
摘要
没有万能的尺寸。此容器在某些未知特殊情况下可能无法正常工作,但绝对可以根据您的需求进行定制。如果还有其他需要添加的功能,请告诉我。
任何建议都可以发送给我
Henry, Pham Dinh Truong (先生)
电子邮件:phdtruong@yahoo.com
地址:GrapeCity Inc.,越南河内 Yen The 街 6 号
祝您编码愉快!
历史
- 版本 1.0 (2009年5月15日) - 首次发布