如果使用自定义DataSource,如何对ASP.NET GridView中的列进行排序?

当我使用自定义SqlDataSource时,我无法使用GridView使用户能够对数据列进行排序。

我有一个GridView,其中HTML中引用它的代码是最小的:

  

在代码隐藏中,我附加了一个动态创建的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(); 

当我希望它对列数据进行排序时,当用户点击列标题时,没有任何反应。 任何想法,我缺少什么?

如果有一个更好的方式这样做也会有所帮助,因为这对我来说看起来很麻烦!

首先,您需要添加一个事件:

  

那个事件看起来像:

 protected void gvName_Sorting( object sender, GridViewSortEventArgs e ) { ... //rebind gridview } 

您基本上必须再次获取数据。

你是对的,它看起来很乱,有一个更好的方法:ASP.Net MVC

不幸的是,这是一个截然不同的页面模型。

您也可以在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; } 

我希望这有帮助。 如果您需要额外的帮助来实现它,请告诉我。

请享用!

我不确定这个,但如果您使用标准的SqlDataSource并且您单击某个字段以根据该字段进行排序,则会再次使用数据填充SqlDataSource并将其反弹到网格中。 因此,排序不会发生在客户端,也只能在SQLDataSource的select方法不是DataReader时才能完成。

处理排序事件时,是否重新创建SqlDataSource并将其重新绑定到GridView? 您可以将排序字段和方向放在您使用的generatedSelectCommand中吗? 或者将它放到SQLDataSource的SortParameterName属性中?

我绝对相信你必须将SqlDataSource重新绑定到网格,并且由于你在运行中创建它,你必须再次填充它。

迟到总比不到好?

Keith建议的一些补充基本上是正确的。

事实是,你必须处理gridView_Sorting事件的排序。 之前不需要DataBind()GridView,例如在Page_Load事件中。 你应该只调用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 

无需在数据源中编写任何排序function,例如将排序参数传递给存储过程。 所有排序都在上面的代码中进行。

此外,将gridView.EnableViewState切换为False是一件好事,这会使页面对于网络流量和浏览器来说更轻松。 可以这样做,因为每当页面回发时都会重新创建网格。

祝你今天愉快!

马丁