5

当我使用自定义 SqlDataSource 时,我无法让我的 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);

然后是网格视图...

grid.DataSource = dataSource;
grid.DataKeyNames = mylistOfKeys;
grid.DataBind();

目前,当我希望它对列数据进行排序时,当用户单击列标题时,什么也没有发生。有人知道我缺少什么吗?

如果有更好的方法这样做也会有帮助,因为这对我来说看起来很乱!

4

4 回答 4

6

您也可以在排序处理程序中的 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;
}

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

享受!

于 2010-12-13T15:11:07.167 回答
4

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

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

然后那个事件看起来像:

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

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

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

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

于 2008-09-26T09:39:15.823 回答
0

我不确定这个,但是如果您使用标准的 SqlDataSource 并单击一个字段以根据该字段进行排序,则 SqlDataSource 将再次填充数据并将其重新绑定到网格。所以排序不会发生在客户端,也只能在 SQLDataSource 的 selectmethod 不是 DataReader 时进行。

在处理排序事件时,是否重新创建 SqlDataSource 并将其反弹到 GridView?您可以将排序字段和方向放在您使用的生成的SelectCommand 中吗?还是放到 SQLDataSource 的 SortParameterName 属性中?

我绝对确定您必须将 SqlDataSource 重新绑定到网格,并且由于您动态创建它,因此您必须再次填充它。

于 2008-09-26T09:30:22.427 回答
0

迟到总比不到好?

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

事实是,您必须处理 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

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

此外,最好将 gridView.EnableViewState 切换为 False,这会导致页面对于网络流量和浏览器来说更轻。可以这样做,因为只要页面回发,网格就会完全重新创建。

祝你今天过得愉快!

马丁

于 2010-06-03T10:39:24.890 回答