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

使用ItemTemplate时GridView排序功能失效问题求助

问题分析与解决方案

我仔细看了你的代码,发现排序功能不生效的核心原因就在你的gvwSacBus_Docs_Sorting方法里——你在最后两行又重新绑定了未排序的原始List,直接把之前准备好的排序后的DataView覆盖了!

// 这里你已经把数据源设为排序后的sortedView了
gvwSacBus_Docs.DataSource = sortedView;
// 但紧接着又重新绑定了原始的未排序List,等于白做了排序!
gvwSacBus_Docs.DataSource = cajaBL.sacbus_Consul_Cajas_x_Cont(lbl_SacBus_CliCod.Text, txt_SacBus_Criter.Text);
gvwSacBus_Docs.DataBind();

下面是完整的修正和优化方案:


1. 修正排序事件逻辑

首先去掉覆盖数据源的错误代码,同时优化查询逻辑(避免每次排序都重复调用数据库,提升性能):

protected void gvwSacBus_Docs_Sorting(object sender, GridViewSortEventArgs e)
{
    // 先从缓存获取数据(避免重复查库),如果没有再查询
    List<Cajas> cajaList;
    if (ViewState["CachedCajaList"] == null)
    {
        cajaList = cajaBL.sacbus_Consul_Cajas_x_Cont(lbl_SacBus_CliCod.Text, txt_SacBus_Criter.Text);
        ViewState["CachedCajaList"] = cajaList;
    }
    else
    {
        cajaList = (List<Cajas>)ViewState["CachedCajaList"];
    }

    // 转换为DataTable
    ListtoDataTable lsttodt = new ListtoDataTable();
    DataTable databito = lsttodt.ToDataTable(cajaList);

    // 处理排序方向(用当前排序字段作为ViewState键,支持多字段排序)
    string sortExpression = e.SortExpression;
    SortDirection currentDir;
    if (ViewState["SortDirection_" + sortExpression] == null)
    {
        currentDir = SortDirection.Ascending;
    }
    else
    {
        currentDir = (SortDirection)ViewState["SortDirection_" + sortExpression];
        // 切换排序方向
        currentDir = currentDir == SortDirection.Ascending ? SortDirection.Descending : SortDirection.Ascending;
    }
    ViewState["SortDirection_" + sortExpression] = currentDir;
    string sortDir = currentDir == SortDirection.Ascending ? "Asc" : "Desc";

    // 应用排序
    DataView sortedView = new DataView(databito);
    sortedView.Sort = $"{sortExpression} {sortDir}";

    // 缓存排序后的视图,方便分页使用
    ViewState["SortedCajaView"] = sortedView;
    // 绑定排序后的数据源
    gvwSacBus_Docs.DataSource = sortedView;
    gvwSacBus_Docs.DataBind();
}

2. 适配分页功能

因为你提到应用启用了分页,需要确保分页是基于排序后的数据源。如果使用GridView自带的分页,需要在PageIndexChanging事件里重新绑定排序后的数据源:

protected void gvwSacBus_Docs_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
    gvwSacBus_Docs.PageIndex = e.NewPageIndex;
    // 优先使用缓存的排序后视图,没有则用原始缓存数据
    if (ViewState["SortedCajaView"] != null)
    {
        gvwSacBus_Docs.DataSource = (DataView)ViewState["SortedCajaView"];
    }
    else if (ViewState["CachedCajaList"] != null)
    {
        gvwSacBus_Docs.DataSource = ViewState["CachedCajaList"];
    }
    gvwSacBus_Docs.DataBind();
}

3. 其他优化建议

  • 优化List转DataTable工具类:当前代码没有处理值类型的Nullable属性(如果以后实体类有int?这类字段会报错),可以修改一下:
public class ListtoDataTable {
    public DataTable ToDataTable<T>(List<T> items) {
        DataTable dataTable = new DataTable(typeof(T).Name);
        PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
        
        foreach (PropertyInfo prop in Props) {
            // 获取属性的真实类型(处理Nullable)
            Type colType = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;
            dataTable.Columns.Add(prop.Name, colType);
        }
        
        foreach (T item in items) {
            object[] values = new object[Props.Length];
            for (int i = 0; i < Props.Length; i++) {
                // 获取值,处理Nullable的null情况
                values[i] = Props[i].GetValue(item) ?? DBNull.Value;
            }
            dataTable.Rows.Add(values);
        }
        return dataTable;
    }
}
  • 避免空异常:在数据层的Cajas_Buscar_CajaXCont方法里,dr["F.EMI"]的处理可以更严谨,比如先判断列的索引再检查是否为DBNull:
int fecEmiIndex = dr.GetOrdinal("F.EMI");
if (dr.IsDBNull(fecEmiIndex))
{
    cajaBus.FecEmisionDoc = new DateTime(9999, 1, 1);
}
else
{
    cajaBus.FecEmisionDoc = dr.GetDateTime(fecEmiIndex);
}

这样修改后,你的GridView排序功能应该就能正常工作了,同时分页也能适配排序后的结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:40:55