2008-09-26 80 views
4

我无法让我的GridView使用户在使用自定义SqlDataSource时对数据列进行排序。如何使用自定义数据源对ASP.NET GridView中的列进行排序?

我有一个GridView,其中在ASP参考它在HTML代码是最小的:

<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(); 

在当用户点击列标题时,我预计它会对列数据进行排序时,什么也没有发生。任何人有任何想法我失踪?

如果有更好的方法来做到这一点,这也会有帮助,因为这看起来很乱!

回答

4

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

<asp:GridView AllowSorting="True" OnSorting="gvName_Sorting" ... 

然后该事件是这样的:

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

基本上,你必须重新获取数据。

你说得对,它看起来凌乱,有一个更好的办法:ASP.Net MVC

不幸的是,这是一个显着不同的页面模型。

0

我不确定这个,但是如果你使用标准的SqlDataSource并且你点击一个字段根据这个字段进行排序,那么SqlDataSource会再次填充数据并且它会被反弹回网格。所以排序不会发生在客户端,也可以只在SQLDataSource的selectmethod不是DataReader时才能完成。

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

我绝对相信你必须将SqlDataSource重新弹回到网格,并且由于您在运行中创建它,所以必须重新填充它。

+0

此刻,我根本不处理排序事件,而是将它留给它的默认行为。但是,我已经检查过在排序事件中SortExpression和SortDirection是合理的,而不是空白。 数据源在回发后重新绑定到网格, – 2008-09-26 09:57:11

+0

您应该像Keith提到的那样处理事件。使用标准的SqlDataSource控件它会自动完成,但在这种情况下,您还应该自己处理。 – Biri 2008-09-26 09:59:20

0

比从未更好的迟到?

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

事实是,你必须处理gridView_Sorting事件的排序问题。 以前不需要DataBind(),例如在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 

不需要编码数据源中的任何排序功能,如将排序参数传递给存储过程。所有的排序都在上面的代码段中进行。

而且,这是很好的有gridView.EnableViewState切换为False这导致页面是网络流量和浏览器以及轻得多。可以做到这一点,因为无论何时页面被回传,网格都会被完全重新创建。

有一个愉快的一天!

马丁

4

你也可以只重新分配在分拣处理程序的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; 
} 

我希望这可以帮到你。让我知道你是否需要额外的帮助来实现它。

享受!

相关问题