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(); }
解决方案
问题核心是排序时未过滤空行,直接对包含空行的数据集排序导致空行前置。需要先过滤非空记录排序,再将空行追加到排序结果末尾,具体修改如下:
修改
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(); }优化空行判断逻辑
如果ProdId不是合适的判断字段,可以换成其他关键字段(比如ProdName),只要能区分空行和有效记录即可。动态计算空行数量(可选)
如果空行数量不是固定值,而是根据总记录数和页面大小计算的(比如凑满整页),可以在BindGridview方法中计算并保存这个数值,供排序方法使用。
内容的提问来源于stack exchange,提问作者Bharat Gunjal
相关产品推荐
相关产品推荐

