ASP.NET GridView排序功能的实现与优化

ASP.NET是一个非常强大且广泛使用的 Web 应用程序框架,它提供了丰富的控件和功能来简化开发过程。其中,GridView控件是用于显示和操作数据的常用工具。尽管它功能强大,但在实现排序功能时存在一些限制。本文将介绍如何克服这些限制,实现更加灵活和动态的排序功能。

假设有一个 Person 类型的序列,希望将其绑定到GridView控件,并允许用户通过点击相应的列头来排序数据。Person 类定义如下:

class Person { public string FirstName { get; set; } public string LastName { get; set; } }

通常情况下,可以通过硬编码的方式来指定排序表达式和排序方向。但是,这种方法的缺点是不够灵活,所有的属性和排序方向都是硬编码的。更好的方法是动态地创建这些排序逻辑。

解决方案

为了实现动态排序,可以将逻辑封装到几个专门的类中。第一个类是 SortExpressionConverter,它将 SortDirection 转换为一个函数,该函数接受一个序列和一个函数,并返回按该对象属性排序后的序列。

public static class SortExpressionConverter<T> { private static IDictionary<SortDirection, ISortExpression> expressions = new Dictionary<SortDirection, ISortExpression> { { SortDirection.Ascending, new OrderByAscendingSortExpression() }, { SortDirection.Descending, new OrderByDescendingSortExpression() } }; interface ISortExpression { Func<IEnumerable<T>, Func<T, object>, IEnumerable<T>> GetExpression(); } class OrderByAscendingSortExpression : ISortExpression { public Func<IEnumerable<T>, Func<T, object>, IEnumerable<T>> GetExpression() { return (c, f) => c.OrderBy(f); } } class OrderByDescendingSortExpression : ISortExpression { public Func<IEnumerable<T>, Func<T, object>, IEnumerable<T>> GetExpression() { return (c, f) => c.OrderByDescending(f); } } public static Func<IEnumerable<T>, Func<T, object>, IEnumerable<T>> Convert(SortDirection direction) { ISortExpression sortExpression = expressions[direction]; return sortExpression.GetExpression(); } }

第二个类是 SortLambdaBuilder,它构建一个 lambda 表达式,并返回底层的 lambda 函数:

public static class SortLambdaBuilder<T> { public static Func<T, object> Build(string columnName, SortDirection direction) { // x ParameterExpression param = Expression.Parameter(typeof(T), "x"); // x.ColumnName1.ColumnName2 Expression property = columnName.Split('.').Aggregate<string, Expression>((param, c, m) => Expression.Property(c, m)); // x => x.ColumnName1.ColumnName2 Expression<Func<T, object>> lambda = Expression.Lambda<Func<T, object>>(Expression.Convert(property, typeof(object)), param); Func<T, object> func = lambda.Compile(); return func; } }

最后,将这些类封装到一个扩展方法中:

public static class CollectionExtensions { public static IEnumerable<T> OrderBy<T>(this IEnumerable<T> collection, string columnName, SortDirection direction) { Func<IEnumerable<T>, Func<T, object>, IEnumerable<T>> expression = SortExpressionConverter<T>.Convert(direction); Func<T, object> lambda = SortLambdaBuilder<T>.Build(columnName, direction); IEnumerable<T> sorted = expression(collection, lambda); return sorted; } } protected void gridPersons_Sorting(object sender, GridViewSortEventArgs e) { IEnumerable<Person> persons = GetPersons(); persons = persons.OrderBy(e.SortExpression, e.SortDirection); gridPersons.DataSource = persons.ToArray(); gridPersons.DataBind(); }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485