【问题标题】:How to sort columns in an ASP.NET GridView if using a custom DataSource?如果使用自定义数据源,如何对 ASP.NET GridView 中的列进行排序?
【发布时间】:2010-09-13 09:31:49
【问题描述】:

当我使用自定义 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);

然后是gridview...

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

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

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

【问题讨论】:

    标签: c# asp.net gridview sqldatasource


    【解决方案1】:

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

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

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

    【讨论】:

    • 目前我根本不处理排序事件,并将其保留为默认行为。但是,我已经检查了在排序事件中 SortExpression 和 SortDirection 是合理的而不是空白的。数据源在回发时重新绑定到网格,
    • 您应该像 Keith 提到的那样处理该事件。使用标准的 SqlDataSource 控件,它会自动完成,但在这种情况下,您也应该自己处理它。
    【解决方案2】:

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

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

    那么那个事件看起来像:

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

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

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

    不幸的是,这是一个完全不同的页面模型。

    【讨论】:

      【解决方案3】:

      迟到总比不到好?

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

      事实是,您必须处理 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,这会导致页面对于网络流量和浏览器来说更轻。可以这样做,因为每当回发页面时,都会完全重新创建网格。

      祝你有美好的一天!

      马丁

      【讨论】:

        【解决方案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;
        }
        

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

        享受吧!

        【讨论】:

          猜你喜欢
          • 2012-09-14
          • 2011-04-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-01-16
          • 2019-12-02
          • 2019-05-28
          • 1970-01-01
          相关资源
          最近更新 更多