You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET C# GridView升序排序时空行前置问题求助

问题描述

我在ASP.NET GridView中用文本框实现查看、添加、更新和删除操作,页面仅在底部设置一个保存按钮。当前GridView每页显示20条记录,已启用列排序功能,加载时会显示28条有数据的记录和12条空记录。但执行升序排序时,空行会排在有数据的记录前面,我希望排序时忽略这些空行,尝试使用GridView的自定义OnSorting方法后并未解决问题。

ASPX代码

<asp:GridView runat="server" ID="gvDetails" AllowPaging="true" PageSize="20" AllowAutoGenerateColumns="false" DataKeyNames="ProdId" OnPageIndexChanging="gvDetails_PageIndexChanging" OnSorting="gvDetails_OnSorting">
<HeaderStyle CssClass="headerstyle" />
<Columns>
<asp:TemplateField HeaderText="Product Name" SortExpression="ProdName">
<ItemTemplate>
<asp:TextBox ID="txtProductName" runat="server" Text='<%# Eval("ProdName") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Description" SortExpression="ProdDesc">
<ItemTemplate>
<asp:TextBox ID="txtProdDesc" runat="server" Text='<%# Eval("ProdDesc") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Price" SortExpression="ProdPrice">
<ItemTemplate>
<asp:TextBox ID="txtProdPrice" runat="server" Text='<%# Eval("ProdPrice") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Category" SortExpression="ProdCat">
<ItemTemplate>
<asp:TextBox ID="txtProdCat" runat="server" Text='<%# Eval("ProdCat") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Delete">
<ItemTemplate>
<asp:CheckBox ID="chkDelete" runat="server" Checked='<%# Eval("IsDelete") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>

后台C#代码

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        BindGridview();
    }
}

protected DataTable BindGridview()
{
    DataSet ds = new DataSet();
    using (SqlConnection con = new SqlConnection("#"))
    {
        con.Open();
        SqlCommand cmd = new SqlCommand("crudoperations", con);
        cmd.CommandType= CommandType.StoredProcedure;
        cmd.Parameters.AddWithValue("@status","SELECT");
        SqlDataAdapter da = new SqlDataAdapter(cmd);
        da.Fill(ds);
        con.Close();
        if (ds.Tables[0].Rows.Count > 0)
        {
            gvDetails.DataSource = ds;
            gvDetails.DataBind();
        }
        else {
            ds.Tables[0].Rows.Add(ds.Tables[0].NewRow());
            gvDetails.DataSource = ds;
            gvDetails.DataBind();
            int columncount = gvDetails.Rows[0].Cells.Count;
            gvDetails.Rows[0].Cells.Clear();
            gvDetails.Rows[0].Cells.Add(new TableCell());
            gvDetails.Rows[0].Cells[0].ColumnSpan = columncount;
            gvDetails.Rows[0].Cells[0].Text = "No Records Found";
        }
    }
    return ds.Tables[0];
}

public void gvDetails_OnSorting(Object sender, GridViewSortEventArgs e)
{
    string sortingDirection = string.Empty;  
    if (direction == SortDirection.Ascending)  
    {  
        direction = SortDirection.Descending;  
        sortingDirection = "Desc";  

    }  
    else  
    {  
        direction = SortDirection.Ascending;  
        sortingDirection = "Asc";  

    }  
    DataView sortedView = new DataView(BindGridView());  
    sortedView.Sort = e.SortExpression + " " + sortingDirection;  
    gvDetails.DataSource = sortedView;  
    gvDetails.DataBind();  
}
解决方案

问题核心是排序时未过滤空行,直接对包含空行的数据集排序导致空行前置。需要先过滤非空记录排序,再将空行追加到排序结果末尾,具体修改如下:

  1. 修改gvDetails_OnSorting方法
    先从原数据中筛选出非空记录,排序后再把空行加回去(保持空行在末尾用于添加操作):

    // 全局变量保存空行数量,根据实际情况调整
    private int emptyRowCount = 12;
    
    public void gvDetails_OnSorting(Object sender, GridViewSortEventArgs e)
    {
        string sortingDirection = string.Empty;  
        if (direction == SortDirection.Ascending)  
        {  
            direction = SortDirection.Descending;  
            sortingDirection = "Desc";  
        }  
        else  
        {  
            direction = SortDirection.Ascending;  
            sortingDirection = "Asc";  
        }  
    
        DataTable originalTable = BindGridview();
        // 过滤非空记录(以ProdId为判断依据,空行的ProdId为DBNull或空)
        DataTable nonEmptyTable = originalTable.Clone();
        foreach (DataRow row in originalTable.Rows)
        {
            if (!Convert.IsDBNull(row["ProdId"]) && !string.IsNullOrEmpty(row["ProdId"].ToString()))
            {
                nonEmptyTable.ImportRow(row);
            }
        }
    
        // 对非空记录排序
        DataView sortedView = new DataView(nonEmptyTable);  
        sortedView.Sort = e.SortExpression + " " + sortingDirection;  
        DataTable sortedTable = sortedView.ToTable();
    
        // 追加空行到排序结果末尾
        for (int i = 0; i < emptyRowCount; i++)
        {
            sortedTable.Rows.Add(sortedTable.NewRow());
        }
    
        // 绑定到GridView
        gvDetails.DataSource = sortedTable;  
        gvDetails.DataBind();  
    }
    
  2. 优化空行判断逻辑
    如果ProdId不是合适的判断字段,可以换成其他关键字段(比如ProdName),只要能区分空行和有效记录即可。

  3. 动态计算空行数量(可选)
    如果空行数量不是固定值,而是根据总记录数和页面大小计算的(比如凑满整页),可以在BindGridview方法中计算并保存这个数值,供排序方法使用。

内容的提问来源于stack exchange,提问作者Bharat Gunjal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 10:43:12