最近要做一个asp.net 的小程序,页面上用到了很多GridView ,既然用到表格那一定想在上面加个排序。但我的GridView都是帮定到DataTable的,不能简单的应用GridView的允许排序功能, 只好自己写了一个排序的类(这其中参考了网的一些方法)。个人认为还是挺有用的,所以拿来给大家分享,并希望高手指点一下。
主要思想是:首先是在邦定数据源之后把DataTable保存下来,我用的中ViewState,然后排序或分页时再重新读出来并重新邦定。
using
System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
/**/ /// <summary>
/// 表格排序类
/// </summary>
public class SortInfo : System.Web.UI.Page // 这里继承了System.Web.UI.Page,因为只有这样才能用ViewState.
... {
public string SortDirection
...{
get
...{
return ViewState["SortDirection"] as string ?? "ASC";
}
set
...{
ViewState["SortDirection"] = value;
}
}
public string SortExpression
...{
get
...{
return ViewState["SortExpression"] as string ?? string.Empty;
}
set
...{
ViewState["SortExpression"] = value;
}
}
/**//// <summary>
/// 排序的表格的数库源,在执行DataBind()方法前,构造些类,
/// 构造之前用Session或页面的静态成员 保存此类,在表格的Sorting事件中重新读出,并调用SortDataBind()方法
/// SortInfo命名规则:si+页面名+控件名
/// </summary>
/// <param name="dt"></param>
public SortInfo(DataTable dt)
...{
ViewState["dt"] = dt;
}
private string GetSortDirection()
...{
switch (SortDirection)
...{
case "ASC":
SortDirection = "DESC";
break;
case "DESC":
SortDirection = "ASC";
break;
}
return SortDirection;
}
private DataView SortDataTable(System.Data.DataTable dt, bool IsPageIndexChanging)
...{
if (dt != null)
...{
DataView dv = new DataView(dt);
if (SortExpression != string.Empty)
...{
if (IsPageIndexChanging)
...{
dv.Sort = string.Format("{0} {1}", SortExpression, SortDirection);
}
else
...{
dv.Sort = string.Format("{0} {1}", SortExpression, GetSortDirection());
}
}
return dv;
}
else
...{
return new DataView();
}
}
public void SortDataBind(GridView gv, int PageIndex, bool GetSort)
...{
DataTable dt = (DataTable)ViewState["dt"];
gv.PageIndex = PageIndex;
gv.DataSource = SortDataTable(dt, GetSort);
gv.DataBind();
}
/**//// <summary>
/// 重新帮定超级链接列
/// </summary>
/// <param name="gv">表格</param>
/// <param name="ColumnIndex">列索引</param>
/// <param name="Address">目标地址,此地址除了值不包括其它都要包括.如SvcCtr_Detail.aspx?id=</param>
/// <param name="Target">打开方式</param>
public void BindLinkButton(GridView gv, int ColumnIndex, string Address, string Target)
...{
for (int i = 0; i < gv.Rows.Count; i++)
...{
gv.Rows[i].Cells[ColumnIndex].Text = "<a href=" + Address + gv.Rows[i].Cells[ColumnIndex].Text.Trim() +
" target=" + Target + ">" + gv.Rows[i].Cells[ColumnIndex].Text + "</a>";
}
}
/**//// <summary>
/// 重新帮定超级链接列,参数是由前缀+列内容组成的.
/// </summary>
/// <param name="gv"></param>
/// <param name="ColumnIndex">必须是一个数字列否则用报错</param>
/// <param name="Address"></param>
/// <param name="Prefix">前缀</param>
/// <param name="Target"></param>
/// <param name="FormatString">格式化列串的格式化串</param>
public void BindLinkButton(GridView gv, int ColumnIndex, string Address, string Prefix, string Target, string FormatString)
...{
for (int i = 0; i < gv.Rows.Count; i++)
...{
gv.Rows[i].Cells[ColumnIndex].Text = "<a href=" + Address + Prefix + Convert.ToInt32(gv.Rows[i].Cells[ColumnIndex].Text).ToString(FormatString) +
" target=" + Target + ">" + gv.Rows[i].Cells[ColumnIndex].Text + "</a>";
}
}
} // End Class SortGrid
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
/**/ /// <summary>
/// 表格排序类
/// </summary>
public class SortInfo : System.Web.UI.Page // 这里继承了System.Web.UI.Page,因为只有这样才能用ViewState.
... {
public string SortDirection
...{
get
...{
return ViewState["SortDirection"] as string ?? "ASC";
}
set
...{
ViewState["SortDirection"] = value;
}
}
public string SortExpression
...{
get
...{
return ViewState["SortExpression"] as string ?? string.Empty;
}
set
...{
ViewState["SortExpression"] = value;
}
}
/**//// <summary>
/// 排序的表格的数库源,在执行DataBind()方法前,构造些类,
/// 构造之前用Session或页面的静态成员 保存此类,在表格的Sorting事件中重新读出,并调用SortDataBind()方法
/// SortInfo命名规则:si+页面名+控件名
/// </summary>
/// <param name="dt"></param>
public SortInfo(DataTable dt)
...{
ViewState["dt"] = dt;
}
private string GetSortDirection()
...{
switch (SortDirection)
...{
case "ASC":
SortDirection = "DESC";
break;
case "DESC":
SortDirection = "ASC";
break;
}
return SortDirection;
}
private DataView SortDataTable(System.Data.DataTable dt, bool IsPageIndexChanging)
...{
if (dt != null)
...{
DataView dv = new DataView(dt);
if (SortExpression != string.Empty)
...{
if (IsPageIndexChanging)
...{
dv.Sort = string.Format("{0} {1}", SortExpression, SortDirection);
}
else
...{
dv.Sort = string.Format("{0} {1}", SortExpression, GetSortDirection());
}
}
return dv;
}
else
...{
return new DataView();
}
}
public void SortDataBind(GridView gv, int PageIndex, bool GetSort)
...{
DataTable dt = (DataTable)ViewState["dt"];
gv.PageIndex = PageIndex;
gv.DataSource = SortDataTable(dt, GetSort);
gv.DataBind();
}
/**//// <summary>
/// 重新帮定超级链接列
/// </summary>
/// <param name="gv">表格</param>
/// <param name="ColumnIndex">列索引</param>
/// <param name="Address">目标地址,此地址除了值不包括其它都要包括.如SvcCtr_Detail.aspx?id=</param>
/// <param name="Target">打开方式</param>
public void BindLinkButton(GridView gv, int ColumnIndex, string Address, string Target)
...{
for (int i = 0; i < gv.Rows.Count; i++)
...{
gv.Rows[i].Cells[ColumnIndex].Text = "<a href=" + Address + gv.Rows[i].Cells[ColumnIndex].Text.Trim() +
" target=" + Target + ">" + gv.Rows[i].Cells[ColumnIndex].Text + "</a>";
}
}
/**//// <summary>
/// 重新帮定超级链接列,参数是由前缀+列内容组成的.
/// </summary>
/// <param name="gv"></param>
/// <param name="ColumnIndex">必须是一个数字列否则用报错</param>
/// <param name="Address"></param>
/// <param name="Prefix">前缀</param>
/// <param name="Target"></param>
/// <param name="FormatString">格式化列串的格式化串</param>
public void BindLinkButton(GridView gv, int ColumnIndex, string Address, string Prefix, string Target, string FormatString)
...{
for (int i = 0; i < gv.Rows.Count; i++)
...{
gv.Rows[i].Cells[ColumnIndex].Text = "<a href=" + Address + Prefix + Convert.ToInt32(gv.Rows[i].Cells[ColumnIndex].Text).ToString(FormatString) +
" target=" + Target + ">" + gv.Rows[i].Cells[ColumnIndex].Text + "</a>";
}
}
} // End Class SortGrid
调用方法:
设置GridView的属性:
<
asp:GridView
ID
="GridView1"
runat
="server"
AllowPaging
="True"
AllowSorting
="True"
Height ="329px" Width ="478px" OnPageIndexChanging ="GridView1_PageIndexChanging" OnSorting ="GridView1_Sorting" >
</ asp:GridView >
Height ="329px" Width ="478px" OnPageIndexChanging ="GridView1_PageIndexChanging" OnSorting ="GridView1_Sorting" >
</ asp:GridView >
在页面的类中声明一个静态的SortInfo:
private
static
SortInfo siForGv
=
null
;
在邦定GridView数据源之后,执行DataBind()方法前保存DataTable。(这里很重要)
GridView1.DataSource = ds.Tables[ 0 ];
siForGv = new SortInfo(ds.Tables[ 0 ]); //这里很重要
GridView1.DataBind();
重写 GridView1的PageIndexChanging和Sorting,当分页和排序时重新邦定数据
protected
void
GridView1_Sorting(
object
sender, GridViewSortEventArgs e)
... {
if (siForGv == null)
...{
return;
}
GridView SortGv = (GridView)sender;
siForGv.SortExpression = e.SortExpression;
int page = SortGv.PageIndex;
siForGv.SortDataBind(SortGv, page, false);
}
protected void GridView1_PageIndexChanging( object sender, GridViewPageEventArgs e)
... {
if (siForGv == null)
...{
return;
}
GridView SortGv = (GridView)sender;
int page = e.NewPageIndex;
siForGv.SortDataBind(SortGv, page, true );
}
... {
if (siForGv == null)
...{
return;
}
GridView SortGv = (GridView)sender;
siForGv.SortExpression = e.SortExpression;
int page = SortGv.PageIndex;
siForGv.SortDataBind(SortGv, page, false);
}
protected void GridView1_PageIndexChanging( object sender, GridViewPageEventArgs e)
... {
if (siForGv == null)
...{
return;
}
GridView SortGv = (GridView)sender;
int page = e.NewPageIndex;
siForGv.SortDataBind(SortGv, page, true );
}
至此应该是可以排序的啦。
完整的代码如下: