【问题标题】:How to sort grid view data when bound with List与List绑定时如何对网格视图数据进行排序
【发布时间】:2014-07-19 06:30:55
【问题描述】:

我正在将 ASP.Net 网格视图与列表对象绑定。我创建了继承自各自接口的 Country 和 City 类。

public interface ICountry
{
    int cmID { get; set; }
    string cmName { get; set; }        
}

public interface ICity 
{
    int ctyId { get; set; }
    string ctyName { get; set; }    
}

public class Country : ICountry
{
    public int cmID { get; set; }
    public string cmName { get; set; }     
}

 public class City : ICity
{
    public int ctyId { get; set; }
    public string ctyName { get; set; }
    public ICountry Country { get; set; }   


public List<City> GetAllCity(string SortDirection, string SortExpression)
{
   DataTable dt = FillCity()            //returns city,country in a table
   List<City> obj = new List<City>();          
   foreach(DataRow dr in dt.Rows)
   {
       City o = new City();
       o.ctyName = dr["ctyName"].ToString();
       o.Country.cmName = dr["cmName"].ToString();
       obj.Add(o);
   }

       dt.Dispose();
       return obj;          
}


    <asp:GridView ID="GridView1" runat="server" Width="100%" AutoGenerateColumns="false" PageSize="15"
AllowPaging="true" OnPageIndexChanging="GRV1_PageIndexChanging"
AllowSorting="true" onsorting="GRV1_Sorting">                                    
<Columns>
    <asp:TemplateField ItemStyle-Width="10%" ItemStyle-HorizontalAlign="Left" HeaderText="City" SortExpression="ctyName ">
        <ItemTemplate>
            <%# Eval("ctyName")%>
        </ItemTemplate>
    </asp:TemplateField>
    <asp:TemplateField ItemStyle-Width="15%" ItemStyle-HorizontalAlign="Left" HeaderText="Country" SortExpression="Country.cmName">
        <ItemTemplate>
            <%# Eval("Country.cmName")%>
        </ItemTemplate>
    </asp:TemplateField>
</Columns></asp:GridView>

我尝试使用 Linq 进行排序,但没有这样做。如何使用 List 对网格视图中的数据进行排序?

我尝试过使用以下但没有用

            if (obj != null)
        {

            var param = Expression.Parameter(typeof(MemorandaClosing), SortExpression);
            var sortExpression = Expression.Lambda<Func<MemorandaClosing, object>>(Expression.Convert(Expression.Property(param, SortExpression), typeof(object)), param);

            if (SortDirection == "ASC")
            {
                obj.AsQueryable<MemorandaClosing>().OrderBy(sortExpression);
            }
            else
            {
                obj.AsQueryable<MemorandaClosing>().OrderByDescending(sortExpression);
            };
        }

【问题讨论】:

  • 什么是“这个”?它指的是什么对象实例?
  • 好吧,我的错。它是一个城市对象实例...但是你为什么一次又一次地添加同一个实例到List&lt;City&gt;
  • 好的,发布编辑,现在有意义了。

标签: c# asp.net


【解决方案1】:

除了@Ganesh_Devlekar 所说的,您也可以通过以下方式订购:

return obj.OrderByDescending(x => x.ctyName).ToList()

甚至使用Where 或其他东西进行某种过滤;)

希望对你有帮助

【讨论】:

    【解决方案2】:

    在方法GetAllCity()中尝试这样的操作

    这将按 CityName 排序

    return obj.OrderBy(x => x.ctyName).ToList();  
    

    【讨论】:

    • 如果我必须将排序表达式和排序方向传递给 GetAllCity() 方法。比如如果我需要使用 Country Name 进行排序怎么办?
    【解决方案3】:

    必须手动进行排序。根据您的要求,它可能会很复杂 - 例如,如果您想要 3 级排序。假设您要参考单个字段对数据进行排序。您需要执行以下操作:

    1. 在 ViewState 中跟踪排序方向
    2. 处理 GridView 的排序事件,并从后端适当地查询数据。

    这是一个改编自here的示例sn-p:

    public SortDirection GridViewSortDirection
    {
        get
        {
            if (ViewState["sortDirection"] == null)
                ViewState["sortDirection"] = SortDirection.Ascending;
    
            return (SortDirection)ViewState["sortDirection"];
        }
        set { ViewState["sortDirection"] = value; }
    }
    
    protected void gridView_Sorting(object sender, GridViewSortEventArgs e)
    {           
        if (GridViewSortDirection == SortDirection.Ascending)
        {
            myGridView.DataSource = GetData(e.SortExpression, SortDirection.Ascending);
            GridViewSortDirection = SortDirection.Descending;
        }
        else
        {
            myGridView.DataSource = GetData(e.SortExpression, SortDirection.Descending);
            GridViewSortDirection = SortDirection.Ascending;
        };
        myGridView.DataBind();        
    }
    

    【讨论】:

      【解决方案4】:

      如果您想对可能两个不同的字段进行排序,则需要一些更复杂的东西。具体来说,您需要向GetAllCity() 方法指定要对哪个 字段进行排序。这是一种可能的方法(当然不是最优雅的):

      public List<City> GetAllCity(bool SortOnCity, bool SortOnCountry)
      {
          //main code omitted for brevity
      
          if (SortOnCity && !SortOnCountry)
              return obj.OrderBy(x => x.ctyName).ToList();
          else if (SortOnCountry && !SortOnCity)
              return obj.OrderBy(x => x.Country.cmName).ToList();
          else if (SortOnCity && SortOnCountry)
              return obj.OrderBy(x => new {x.ctyName, x.Country.cmName}).ToList();
      }
      

      为了我的钱,我会传入一个 lambda 表达式参数,该参数会传递给 OrderBy 方法,而不是使用这么脏的 if...else...else,但我认为上面的代码更好地展示了这些概念。

      要重写上面的代码,将 SortOrder 和 SortExpression 作为变量传递,您可以执行以下操作:

      public List<City> GetAllCity<TKey>(SortDirection order, Expression<Func<City, TKey>> SortExpression)
      {
          //main code omitted for brevity
      
          if (order == SortDirection.Ascending)
              return obj.OrderBy(SortExpression);
          else
              return obj.OrderByDescending(SortExpression);
      
      }
      

      然后您将传入一个表示您想要排序的属性的 lambda 表达式,类似于:

      GetAllCity(SortDirection.Ascending, c => new {c.ctyName, c.Country.cmName});
      

      请注意,这只是一个示例,可能需要根据您的具体情况进行调整。

      【讨论】:

      • 你的最后一个 else-if 条件永远不会运行
      • 您是绝对正确的先生 - 我会纠正它。谢谢:)
      • 现在看起来不错,但我更喜欢写if (SortOnCity &amp;&amp; SortOnCountry){}else if (SortOnCity){}else if (SortOnCountry){}
      • 我永远不会编写这样的生产代码 - 这纯粹是为了演示这个概念。
      • @Katstevens 感谢您的建议。您能否演示如何使用传递给 OrderBy 方法的 lambda 表达式参数。
      【解决方案5】:

      感谢大家为我提供解决问题的提示。在这里,我发现堆栈溢出中的帖子在我的情况下非常适合。

      Building an OrderBy Lambda expression based on child entity's property

      【讨论】:

        猜你喜欢
        • 2010-10-11
        • 2015-06-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多