如同比萨饼厨师的擀面杖,DataGrid 控件,对于一个熟练的ASP.NET开发者来说是非常基本而且有用的工具(译者:老外的比喻,感觉好奇怪)。 虽然,在 ASP.NET 1.x 中,DataGrid已经是非常强大而且用途广泛的控件和服务器工具。 但是,我们依然可以通过给它加一点客户端脚本,来使它的功能变得更加强大。 最近,我看到了Dave Massy在几年前为 MSDN Online 的“ASP">DHTML Dude”栏目写的一些精彩内容。 Dave 论述了一些使 HTML的 <Table> 元素功能强大的创造性的方法,其中之一就是如何对table的内容进行排序和在Table中拖动列。
他还演示了<Table>元素的的DHTMLBehavior的用法。我意识到,当DataGrid控件在浏览器上呈现为 HTML 时,它完全就是一个<Table>元素; 虽然它可能包含了许多样式属性,但它的基本结构依然是一个典型的 HTML Table。这使我意识到我可以创建带客户端排序和可拖动列功能的 DataGrid 控件。 这就是我们这个月的栏目内容,你可以下载源代码来验证我所说并非虚言。
DHTML Behavior快速指南
DHTML Behavior在我们的扩展的 DataGrid 控件中扮演非常重要的角色。 一会儿你就会注意到:我并没有使用Dave在他的原始form中使用的方法,为了使 behavior 在 ASP.NET 控件可以工作,我做了一点更改。 虽然使用这个修改后的组件不需要任何 JavaScript 技能,但是了解一下 DHTML Behavior的技术可以使你更好的理解服务器端和客户端协同工作的机制。
DHTML Behavior 就是利用 CSS(cascading style sheet层叠样式表)的 behavior 样式,绑定到一个 HTML 标记的脚本组件 对于那些不支持CSS或不识别 behavior 样式的老浏览器中,将自动怱略未识别的样式。要想深入了解 DHTML 请参见: ASP?TARGET=/mind/0499/HTMLbehaviors/HTMLbehaviors.ASP">Scripting Evolves to a More Powerful Technology: HTML Behaviors in Depth 一个 DHTML behavior 就是一个 JavaScrip 函数集,这个函数集中加入了一些由特殊句法定义的公共成员。一般来讲,这些公共成员是一些属性和事件,有时也可能是方法;Behavior 工作在现有的 HTML 元素之上, 允许你覆盖和扩展 HTML 元素的 behavior 。方法是:behavior 把它自己定义的代码关联到 DHTML 的事件上。例如,提供拖动列功能的 behavior 操作 onmousedown 和 onmouseup 事件。而且,所有关键的 DHTML behavior 都支持 oncontentready 事件,当 HTML subtree(在指定元素内的所有 HTML)被解析完成时将激发这一事件。当 oncontentreadey 事件激发时,是初始化 behavior 的好时机。
其实,behavior 的核心就是向 Microsoft Internet Explorer(4.0或更高版本)浏览器暴露一系列接口的 COM 对象。最终就是你可以把它写成 C++ 元组件或 HTML 组件(HTC)文本文件 HTC文件可以布署在承载应用它们的文件(HTML,ASP,ASP.NET)的服务器上,不需要在客户端安装。
下面代码表示如何通过使用 “dragdrop.htc”behavior 添加一个具有可拖动列功能的<table≷标签:
可拖动的 DataGrid
在阅读了 Dave Massy 的文章之后,我下载了 dragdrop.htc 示例组件,然后我尝试在一个实验页面中把它绑定到 DataGrid 组件。如下:
有两个办法解决这一问题:重写一个不使用 THEAD 和 TBODY 的 behavior ;自己写一个生成带 THEAD 和 TBODY 标签的 Table 的 DataGrid 控件。 对于一个象我这样的 ASP.NET 开发者来说,我相信开发一个自定义控件比编写一个 behavior 要容易。因为至少我们可以进行有效的进行代码根踪调试。 于是,我新建一个 Visual Studio .NET 解决方案,添加一个 ASP.NET 应用程序工程和一个 Web 控件库工程。就有了下面的新 DataGrid 控件的雏形:
[ToolboxData("<{0}:DataGrid runat=\"server\" />")]
public class DataGrid : System.Web.UI.WebControls.
DataGrid
{
public DataGrid() : base()
{
EnableColumnDrag = true;
DragColor = Color.Empty;
HitColor = Color.Empty;
}
...
}
构造器初始化三个公共自定义属性:EnableColumnDrag、DragColor和HitColor。EnableColumnDrag 是一个表示是否可以拖动列的布尔属性。 如果此属性设置成 False ,自定义 DataGrid 控件将不会添加拖动列 behavior。另外两个属性分别表示被拖动的列的背景色和将下压列的颜色。
注意这两个颜色属性不会影响 DataGrid 服务器控件的任何逻辑。他们是那种仅输出 HTML 值(这个值只对客户端 behavior 有用)的服务器端属性。 这两个属性的值被呈现为由 grid 的生成的 <table> 标签的自定义属性。DataGrid 的标记代码是在控件的 Render 方法中创建的,如下:
protected override void Render(HTMLTextWriter output)
{
// Sets attributes for the DragDrop behavior
if (EnableColumnDrag)
{
if (DragColor != Color.Empty)
Attributes["DragColor"] = DragColor.Name.ToLower();
if (HitColor != Color.Empty)
Attributes["HitColor"] =
HitColor.Name.ToLower(); // Capture
the default
output
of the DataGrid StringWriter
writer =
new StringWriter(); HTMLTextWriter
buffer =
new HTMLTextWriter(writer); base.Render(buffer);
string gridMarkup =
writer.ToString(); //
Parse the markup to insert missing tags //
Find the first occurrence of > and insert