近日给GridView套了个比较炫酷的skin,用 jquery easyui 里的 datagrid 美化了下显示效果,经过调试功能都已匹配。
原有GridView显示:
套用 jquery easyui 的 datagrid 后给效果如下,表格列宽可调整,分页功能可用,但分页依然是有刷,用url参数实现的,因为内核依然是 GridView,没有大改。
页面源代码:(基本是拖进来自动生成的标准GridView)
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default7.aspx.cs" Inherits="Default7" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="X-UA-Compatible" content="IE=10" /> <title>测试3!</title> <link rel="stylesheet" type="text/css" href="js/themes/default/easyui.css" /> <link rel="stylesheet" type="text/css" href="js/themes/icon.css" /> <script type="text/javascript" src="js/jquery.min.js"></script> <script type="text/javascript" src="js/jquery.easyui.min.js"></script> <script type="text/javascript" src="js/locale/easyui-lang-zh_CN.js"></script> <script type="text/javascript" src="js/URLParser.js"></script> </head> <body> <form id="form1" runat="server"> <div> <asp:GridView ID="GridView1" runat="server" AllowPaging="True" AllowSorting="True" AutoGenerateColumns="False" DataKeyNames="ID" DataSourceID="SqlDataSource1" EmptyDataText="没有可显示的数据记录。" onprerender="GridView1_PreRender" onrowupdating="GridView1_RowUpdating"> <Columns> <asp:CommandField ShowDeleteButton="True" ShowEditButton="True" /> <asp:BoundField DataField="ID" HeaderText="ID" ReadOnly="True" SortExpression="ID" /> <asp:BoundField DataField="留言人" HeaderText="留言人" SortExpression="留言人" /> <asp:BoundField DataField="留言人Email" HeaderText="留言人Email" SortExpression="留言人Email" /> <asp:BoundField DataField="留言内容" HeaderText="留言内容" SortExpression="留言内容" /> <asp:BoundField DataField="留言时间" HeaderText="留言时间" SortExpression="留言时间" /> <asp:BoundField DataField="管理员回复内容" HeaderText="管理员回复内容" SortExpression="管理员回复内容" /> <asp:BoundField DataField="管理员回复时间" HeaderText="管理员回复时间" SortExpression="管理员回复时间" /> </Columns> </asp:GridView> <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:LiuYanConnectionString1 %>" DeleteCommand="DELETE FROM [T_留言板] WHERE [ID] = @ID" InsertCommand="INSERT INTO [T_留言板] ([留言人], [留言人Email], [留言内容], [留言时间], [管理员回复内容], [管理员回复时间]) VALUES (@留言人, @留言人Email, @留言内容, @留言时间, @管理员回复内容, @管理员回复时间)" ProviderName="<%$ ConnectionStrings:LiuYanConnectionString1.ProviderName %>" SelectCommand="SELECT [ID], [留言人], [留言人Email], [留言内容], [留言时间], [管理员回复内容], [管理员回复时间] FROM [T_留言板]" UpdateCommand="UPDATE [T_留言板] SET [留言人] = @留言人, [留言人Email] = @留言人Email, [留言内容] = @留言内容, [留言时间] = @留言时间, [管理员回复内容] = @管理员回复内容, [管理员回复时间] = @管理员回复时间 WHERE [ID] = @ID" onselected="SqlDataSource1_Selected"> <DeleteParameters> <asp:Parameter Name="ID" Type="Int32" /> </DeleteParameters> <InsertParameters> <asp:Parameter Name="留言人" Type="String" /> <asp:Parameter Name="留言人Email" Type="String" /> <asp:Parameter Name="留言内容" Type="String" /> <asp:Parameter Name="留言时间" Type="DateTime" /> <asp:Parameter Name="管理员回复内容" Type="String" /> <asp:Parameter Name="管理员回复时间" Type="DateTime" /> </InsertParameters> <UpdateParameters> <asp:Parameter Name="留言人" Type="String" /> <asp:Parameter Name="留言人Email" Type="String" /> <asp:Parameter Name="留言内容" Type="String" /> <asp:Parameter Name="留言时间" Type="DateTime" /> <asp:Parameter Name="管理员回复内容" Type="String" /> <asp:Parameter Name="管理员回复时间" Type="DateTime" /> <asp:Parameter Name="ID" Type="Int32" /> </UpdateParameters> </asp:SqlDataSource> </div> </form> </body> </html>
为了便于套用,主要代码都已经写成 2 个函数,在 GridView 及 SQLDataSource 的3个事件里调用即可。如果不启用 GridView 的编辑功能,则 GridView1_RowUpdating 事件里的代码可省略,这段代码是为了去除掉用 datagrid 显示后,更新时莫名其妙的会带着oldValue。其中 SqlDataSource1_Selected 事件里目的是取得记录总行数,datagrid 的分页需要这个参数来计算和统计分页。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; public partial class Default7 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void GridView1_PreRender(object sender, EventArgs e) { EasyUITools.datagridSkin(GridView1); } protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e) { EasyUITools.datagridSkinUpdate(e); } protected void SqlDataSource1_Selected(object sender, SqlDataSourceStatusEventArgs e) { GridView1.Attributes.Add("total", e.AffectedRows.ToString()); } }
其中<head>中载入的 URLParser.js 是用于解析 url 的 js 类,百度出来的,感谢原作者,代码如下:
/** *@param {string} url 完整的URL地址 *@returns {object} 自定义的对象 *@description 用法示例:var myURL = parseURL('http://abc.com:8080/dir/index.html?id=255&m=hello#top'); myURL.file='index.html' myURL.hash= 'top' myURL.host= 'abc.com' myURL.query= '?id=255&m=hello' myURL.params= Object = { id: 255, m: hello } myURL.path= '/dir/index.html' myURL.segments= Array = ['dir', 'index.html'] myURL.port= '8080' yURL.protocol= 'http' myURL.source= 'http://abc.com:8080/dir/index.html?id=255&m=hello#top' */ function parseURL(url) { var a = document.createElement('a'); a.href = url; return { source: url, protocol: a.protocol.replace(':',''), host: a.hostname, port: a.port, query: a.search, params: (function(){ var ret = {}, seg = a.search.replace(/^\?/,'').split('&'), len = seg.length, i = 0, s; for (;i<len;i++) { if (!seg[i]) { continue; } s = seg[i].split('='); ret[s[0]] = s[1]; } return ret; })(), file: (a.pathname.match(/\/([^\/?#]+)$/i) || [,''])[1], hash: a.hash.replace('#',''), path: a.pathname.replace(/^([^\/])/,'/$1'), relative: (a.href.match(/tps?:\/\/[^\/]+(.+)/) || [,''])[1], segments: a.pathname.replace(/^\//,'').split('/') }; }
主要套用代码 EasyUITools.cs 如下:
using System; using System.Collections.Generic; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; /// <summary> ///EasyUITools 的摘要说明 /// </summary> public class EasyUITools { public static void datagridSkin(GridView gv) { datagridSkin(gv, null); } public static void datagridSkin(GridView gv, string sTitle) { if (gv.Rows.Count > 0) { string sDataOptions = "rownumbers:true,singleSelect:true"; if (gv.AllowPaging) { int iPageNumber = 0; if (int.TryParse(gv.Page.Request.QueryString[gv.ID + "_pn"], out iPageNumber)) gv.PageIndex = iPageNumber - 1; int iPageSize = 10; if (int.TryParse(gv.Page.Request.QueryString[gv.ID + "_ps"], out iPageSize)) gv.PageSize = iPageSize; sDataOptions += ",pagination:true"; } gv.CssClass = "easyui-datagrid"; gv.Attributes.Add("data-options", sDataOptions); gv.Attributes.Add("dg-name", gv.ID); if (sTitle != null) gv.Attributes.Add("title", sTitle); gv.BorderWidth = 1; int i = 0; foreach (TableCell cell in gv.HeaderRow.Cells) { cell.Attributes.Add("data-options", "field:'item" + i.ToString() + "'"); i++; } //使用<TH>替换<TD> gv.UseAccessibleHeader = true; //HeaderRow将被<thead>包裹,数据行将被<tbody>包裹 gv.HeaderRow.TableSection = TableRowSection.TableHeader; //FooterRow将被<tfoot>包裹 //gv.FooterRow.TableSection = TableRowSection.TableFooter; if (gv.AllowPaging) { gv.BottomPagerRow.Visible = false; gv.Page.ClientScript.RegisterStartupScript(gv.Page.GetType(), "_dg_" + gv.ID, @"<script type=""text/javascript""> $(function () { var dg = $(""[dg-name='" + gv.ID + @"']""); var pager = dg.datagrid().datagrid('getPager'); var dgtotal = dg.attr('total'); if (typeof (dgtotal) == 'undefined') alert('未设置GridView的total属性,请在SqlDataSource的Selected事件中或其他方式设置!'); var currentUrl = parseURL(location.href); pager.pagination({ showRefresh: false, total: dgtotal, pageNumber: currentUrl.params['" + gv.ID + @"_pn'], pageSize: currentUrl.params['" + gv.ID + @"_ps'], onSelectPage: function (pageNumber, pageSize) { $(""[dg-name='" + gv.ID + @"']"").datagrid().datagrid('getPager').pagination('loading'); currentUrl.params['" + gv.ID + @"_pn'] = pageNumber; currentUrl.params['" + gv.ID + @"_ps'] = pageSize; var params = []; for (var key in currentUrl.params) params.push(key + '=' + currentUrl.params[key]); location = currentUrl.path + '?' + params.join('&'); return false; } }); }) </script>"); } } } public static void datagridSkinUpdate(GridViewUpdateEventArgs e) { // 清除莫名其妙多出的来的OldValue for (int i = 0; i < e.NewValues.Count; i++) { string oldValue = (string)e.OldValues[i]; string newValue = (string)e.NewValues[i]; if (oldValue == null || oldValue == "") e.NewValues[i] = newValue.Substring(0, newValue.Length - 1); else if (oldValue.Length < newValue.Length) { int iLength = newValue.Length - oldValue.Length; if (newValue.LastIndexOf(oldValue) == iLength) e.NewValues[i] = newValue.Substring(0, iLength - 1); } } } }
有兴趣的朋友可以到这里下载源码: