如果使用自定义数据源,如何在ASP.NET GridView中对列进行排序?
使用自定义SqlDataSource时,无法使GridView使用户能够对数据列进行排序。
我有一个GridView,其中HTML中的ASP引用中的代码很少:
<asp:GridView id="grid" runat="server" AutoGenerateColumns="False" AllowSorting="True"> </asp:GridView>
在后面的代码中,我添加了动态创建的SqlDataSource(它包含的列并不总是相同的,因此用于创建它的SQL在运行时构造)。例如:
我设置了列...
BoundField column = new BoundField(); column.DataField = columnName; column.HeaderText = "Heading"; column.SortExpression = columnName; grid.Columns.Add(column);
数据源...
SqlDataSource dataSource = new SqlDataSource( "System.Data.SqlClient", connectionString, generatedSelectCommand);
然后是GridView ...
grid.DataSource = dataSource; grid.DataKeyNames = mylistOfKeys; grid.DataBind();
目前,当用户单击列标题(我希望它对列数据进行排序)时,什么也没有发生。任何人有什么想法我想念的吗?
如果有更好的方法可以这样做,这对我来说也很混乱!
解决方案
我不确定这一点,但是如果我们使用标准的SqlDataSource,然后单击一个字段以根据该字段进行排序,则SqlDataSource会再次填充数据,然后反弹到网格中。因此,排序不会在客户端发生,也只能在SQLDataSource的selectmethod不是DataReader的情况下进行。
处理排序事件时,是否重新创建SqlDataSource并将其反弹到GridView?我们可以将排序字段和方向放到所使用的generateSelectCommand上吗?还是将其放入SQLDataSource的SortParameterName属性?
我绝对确定我们必须将SqlDataSource反弹到网格,并且由于是在运行中创建它,因此必须再次填充它。
首先,我们需要添加一个事件:
<asp:GridView AllowSorting="True" OnSorting="gvName_Sorting" ...
然后,该事件如下所示:
protected void gvName_Sorting( object sender, GridViewSortEventArgs e ) { ... //rebind gridview }
基本上,我们必须再次获取数据。
没错,它看起来很乱,还有更好的方法:ASP.Net MVC
不幸的是,这是完全不同的页面模型。
迟到总比不到好?
基思建议的一些补充,基本上是正确的。
事实是,我们必须处理gridView_Sorting事件的排序。
例如,在Page_Load事件中,不需要对GridView进行DataBind()处理。在那里,我们仅应调用GridView.Sort()方法,而不是.DataBind()。这是怎么回事:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load If Not IsPostBack Then Me.gridView.Sort(Request.QueryString("sortExpression"), Request.QueryString("sortDirection")) End If End Sub
接下来,让我们看一下gridView_Sorting事件。
在那里,我们必须将数据源推入正确的排序。 GridView本身不处理(至少在这种情况下)。
Protected Sub gridView_Sorting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewSortEventArgs) Handles gridView.Sorting If IsPostBack Then e.Cancel = True Dim sortDir As SortDirection = SortDirection.Ascending If e.SortExpression = Me.Q_SortExpression And Me.Q_SortDirection = SortDirection.Ascending Then sortDir = SortDirection.Descending End If RedirectMe(e.SortExpression, sortDir) Else Dim sortExpr As String = e.SortExpression + " " + IIf(e.SortDirection = SortDirection.Ascending, "ASC", "DESC") Dim dv As System.Data.DataView = Me.dsrcView.Select(New DataSourceSelectArguments(sortExpr)) Me.gridView.DataSource = dv Me.gridView.DataBind() End If End Sub
无需在数据源中编写任何排序功能,例如将排序参数传递给存储过程。所有排序都在上述代码段中进行。
此外,最好将gridView.EnableViewState切换为False,这会使页面对于网络流量和浏览器的访问更加轻松。可以做到这一点,因为每当页面回发时便会完全重新创建网格。
祝你今天过得愉快!
马丁
我们也可以在Sorting处理程序中调用DataBind()之前重新分配datasource.SelectCommand。像这样的东西:
protected void gvItems_Sorting(object sender, GridViewSortEventArgs e) { GridView gv = (GridView)sender; SqlDataSource ds = (SqlDataSource)gv.DataSource; ds.SelectCommand = ds.SelectCommand + " order by " + e.SortExpression + " " + GetSortDirection(e.SortDirection); gvItems.DataSource = ds; gvItems.DataBind(); } string GetSortDirection(string sSortDirCmd) { string sSortDir; if ((SortDirection.Ascending == sSortDirCmd)) { sSortDir = "asc"; } else { sSortDir = "desc"; } return sSortDir; }
希望对我们有所帮助。让我知道我们是否需要额外的帮助来实施它。
享受!