GridView 排序和分页
Posted
技术标签:
【中文标题】GridView 排序和分页【英文标题】:GridView sorting & paging 【发布时间】:2012-08-23 00:06:27 【问题描述】:我想在我的页面上显示简单的 gridview 并为其提供排序和分页功能。单独排序和分页可以正常工作,但两者的组合却不行。例如,如果我对第一列进行降序排序,然后转到第二页,那么我会看到默认排序(升序)的第二页数据。
我严重依赖这个问题的代码:GridView sorting: SortDirection always Ascending,但问题仍然存在。另外 - 似乎我必须更改我的代码,以便使用 Session 对象而不是 ViewState,还必须弄清楚这一点......
我的代码,经过简化,只有两列:
aspx:
<asp:GridView ID="dgvView" runat="server" AutoGenerateColumns="false" AllowPaging="true"
PageSize="10" AllowSorting="True" OnPageIndexChanging="DgvViewPageIndexChanging" OnSorting="OnSort">
<Columns>
<asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name">
<ItemStyle />
</asp:BoundField>
<asp:BoundField DataField="BirthDate" HeaderText="Birth date" DataFormatString="0:dd.MM.yyyy"
SortExpression="BirthDate">
<ItemStyle />
</asp:BoundField>
</Columns>
</asp:GridView>
还有代码隐藏:
public partial class TestPage :Page
protected void Page_Load(object sender, EventArgs e)
if (!IsPostBack)
DisplayData();
private void DisplayData()
Session["TableView"] = GetUsers();
dgvView.DataSource = Session["TableView"];
dgvView.DataBind();
protected void DgvViewPageIndexChanging(object sender, GridViewPageEventArgs e)
dgvView.PageIndex = e.NewPageIndex;
DisplayData();
private List<MyUser> GetUsers()
var users = new List<MyUser>();
for (int i = 0; i < 100; i++)
users.Add(new MyUser("Name" + i.ToString().PadLeft(2, '0'), new DateTime(2000, 1, 1).AddDays(i)));
return users;
private class MyUser
public string Name get; private set;
public DateTime BirthDate get; private set;
public MyUser(string name, DateTime birthDate)
Name = name;
BirthDate = birthDate;
protected void OnSort(object sender, GridViewSortEventArgs e)
Func<MyUser, object> f;
if (e.SortExpression == "Name") f = u => u.Name;
else f = u => u.BirthDate;
dgvView.DataSource = Sort((List<MyUser>)Session["TableView"], f, GetSortDirection(e.SortExpression));
dgvView.DataBind();
private List<MyUser> Sort<T>(IEnumerable<MyUser> user, Func<MyUser, T> f, SortDirection sortDirection)
if (sortDirection == SortDirection.Ascending) return user.OrderBy(f).ToList();
return user.OrderByDescending(f).ToList();
private SortDirection GetSortDirection(string column)
string sessionVariable = "TableSort" + column;
SortDirection sortDirection;
if (Session[sessionVariable] == null)
sortDirection = SortDirection.Ascending;
else if ((SortDirection)Session[sessionVariable] == SortDirection.Ascending)
sortDirection = SortDirection.Descending;
else
sortDirection = SortDirection.Ascending;
Session[sessionVariable] = sortDirection;
return sortDirection;
【问题讨论】:
【参考方案1】:您必须使用 ViewState 才能持久化您的数据
public string SortVariable
get
if(ViewState["YourKey"] == null)
return string.Empty;
return (string)ViewState["YourKey"];
set
ViewState["YourKey"] = value;
当您更改页面时,使用此解决方案,您可以在排序之前在视图状态中获得索引排序。
当您触发 SortCommand 时,您必须设置所描述的视图状态的值
你不需要 Session,因为你在同一个页面,你不需要导航
protected void OnSort(object sender, GridViewSortEventArgs e)
//Here you set your value SortVariable
SortVariable = e.SortExpression;
...
在显示数据中
你创建数据视图和排序处理
private void DisplayData()
//GetSortVariable
//before bind with dataview you sort
【讨论】:
【参考方案2】:问题出在
protected void DgvViewPageIndexChanging(object sender, GridViewPageEventArgs e)
dgvView.PageIndex = e.NewPageIndex;
DisplayData();
当您调用DisplayData()
方法时,您将您的网格与未排序的全新数据绑定。
在Viewstate
中保存你的排序参数(会话对此无用)
如果您使用的是Asp.Net 4
,为什么不使用datatables 或jQGrid?
【讨论】:
【参考方案3】:我在其他两个答案的帮助下解决了这个问题。
我的解决方案:
public partial class TestPage1 : Page
protected void Page_Load(object sender, EventArgs e)
if (!IsPostBack)
ViewState["Data"] = MyUser.GetUsers();
ViewState["SortExpression"] = "Name";
DisplayData("Name", SortDirection.Ascending);
private void DisplayData(string sortExpression, SortDirection sortDirection)
Func<MyUser, object> f;
if (sortExpression == "Name") f = u => u.Name;
else f = u => u.BirthDate;
if (sortDirection == SortDirection.Ascending)
dgvView.DataSource = ((IEnumerable<MyUser>)ViewState["Data"]).OrderBy(f).ToList();
else
dgvView.DataSource = ((IEnumerable<MyUser>)ViewState["Data"]).OrderByDescending(f).ToList();
dgvView.DataBind();
protected void DgvViewPageIndexChanging(object sender, GridViewPageEventArgs e)
dgvView.PageIndex = e.NewPageIndex;
string sortExpression = ViewState["SortExpression"].ToString();
DisplayData(sortExpression, GetDefaultSortDirection(sortExpression));
protected void OnSort(object sender, GridViewSortEventArgs e)
ViewState["SortExpression"] = e.SortExpression;
ViewState[e.SortExpression] = GetReverseSortDirection(e.SortExpression);
DisplayData(e.SortExpression, (SortDirection)ViewState[e.SortExpression]);
private SortDirection GetDefaultSortDirection(string sortExpression)
if (ViewState[sortExpression] == null)
ViewState[sortExpression] = SortDirection.Ascending;
return (SortDirection)ViewState[sortExpression];
private SortDirection GetReverseSortDirection(string sortExpression)
if (ViewState[sortExpression] == null)
ViewState[sortExpression] = SortDirection.Descending;
else
ViewState[sortExpression] = (SortDirection) ViewState[sortExpression] == SortDirection.Descending ? SortDirection.Ascending : SortDirection.Descending;
return (SortDirection)ViewState[sortExpression];
【讨论】:
以上是关于GridView 排序和分页的主要内容,如果未能解决你的问题,请参考以下文章
GridView 控件中使用 LinqDataSource 和分页的总行数
asp.net中GridView怎样进行分页,编辑,删除操作
如何以编程方式在 ASP.NET 4.0 GridView 上启用分页和排序?