代码中经常要用到DataGrid或Repeater的排序功能,即单击列为该列重新排序,.net提供了排序功能,但会有刷新整个页面的缺点,如果用ajax,要输出整个列表不知道要写多少js,而且以前用DataGrid写的列表都要改成js输出,时间上也不允许,于是想到了自定义用户控件,如果把项目中经常用到的列排序功能的js整合到自定义的DataGrid中,修改改起来就会方便得多。
由于排序js要用到Thead,Tbody而DataGrid生成的Html代码中是没有的,于是重写Render为DataGrid生成的Table添加Thead,Tbody:
protected override void Render(HtmlTextWriter output)
{
output.Write(this.AddTHeadTBody());
}
private string AddTHeadTBody()
{ 
// 插入THead标签和TBody标签 
StringWriter writer = new StringWriter(); 
HtmlTextWriter buffer = new HtmlTextWriter(writer); 
base.Render(buffer); 
string temp = writer.ToString(); 

temp = temp.Insert(temp.IndexOf(">") + ">".Length, "<thead>"); 
temp = temp.Insert( temp.IndexOf("</tr>") + "</tr>".Length,"</thead><tbody>"); 
temp = temp.Replace("</table>", "</tbody></table>"); 
return temp; 
}
将sortabletabl.js设置为程序集嵌入的资源:


同样可以设置SortableDataGrid.bmp为嵌入的资源作为生成控件的图标
[ToolboxBitmap(typeof(SortableDataGrid))]
public class SortableDataGrid : System.Web.UI.WebControls.DataGrid
{
Sortabletable.js的读取方式如下
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender (e);
if(!Page.IsClientScriptBlockRegistered("SortJs")) 
{ 
System.Reflection.Assembly assembly = 
System.Reflection.Assembly.GetExecutingAssembly(); 
System.IO.Stream stream =
assembly.GetManifestResourceStream("ControlLibray.sortabletable.js"); 
System.IO.StreamReader reader = new System.IO.StreamReader(stream); 

Page.RegisterClientScriptBlock("SortJs",reader.ReadToEnd()); 
} 
}
编译,运行成功

然而,存在一个问题,就是虽然继承自DataGrid的控件可以客户端排序了,但却失去了DataGrid的intellisense功能,如输入:
<wbl:SortableDataGrid id="SortableDataGrid1" runat="server">
<Columns>
<asp:BoundColumn DataField="au_fname" HeaderText="作者姓" />
<asp:BoundColumn DataField="au_lname" HeaderText="作者名" />
<asp:BoundColumn DataField="phone" HeaderText="电话" />
<asp:BoundColumn DataField="city" HeaderText="城市" />
<asp:BoundColumn DataField="state" HeaderText="州" />
</Columns>
</wbl:SortableDataGrid> 
不像DataGrid输入<或空格时会弹出提示。也就是失去了intellisense功能。
这里非常感谢Truly()和LoveCherry提供的文档
1.《为 ASP.NET 控件添加设计时支持》
2.《Learn how Visual Studio implements intellisense for Web Forms》
相关帖子:http://community.csdn.net/Expert/topic/4780/4780874.xml?temp=.4131281
原来,.net在
[root]\Program Files\Microsoft Visual Studio .NET 2003\Common7\Packages\schemas\xml\
提供了对intellisense的支持,
于是找出asp.xsd中与DataGrid 相关的节点,做了相应修改:
<?xml version="1.0" encoding="utf-8" ?> 
<xsd:schema
targetNamespace="urn:http://blog.csdn.net/berlin8600"
elementFormDefault="qualified"
xmlns="urn:http://blog.csdn.net/berlin8600"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:vs="http://schemas.microsoft.com/Visual-Studio-Intellisense"
vs:friendlyname="Blog Control Schema"
vs:ishtmlschema="false" 
vs:iscasesensitive="false" 
vs:requireattributequotes="true" >
<xsd:annotation>
<xsd:documentation>
SortableDataGrid Control schema.
</xsd:documentation>
</xsd:annotation>
<xsd:element name="SortableDataGrid" type="SortableDataGridDef" />
<!-- <asp:SortableDataGrid> 省略…-->
<!-- < BaseDataList attributes >省略…-->
<!-- < WebControl attributes >省略…-->
<!-- < Control attributes >省略…-->
</xsd:schema>
并命名为wbl.xsd存入该目录。上面省略了.xsd中相关DataGrid的较长的部份,相关代码可以通过注释中的关键字在Asp.xsd中找到。
这里名称并不是关键,主要是targetNamespace,xmlns要与页面的body xmlns保持一致
<body xmlns:wbl="urn:http://blog.csdn.net/berlin8600">
这里wbl对应着控件
<%@ Register TagPrefix="wbl" Namespace="ControlLibray" Assembly="ControlLibray" %>
中的TagPrefix
再次输入<或空格时就会像DataGrid一样弹出提示了 :)
输入<时:

输入空格时:


浙公网安备 33010602011771号