我在使用 Listview 控件时遇到了类似的问题。
我是这样解决的。
首先,我使用 Marc Gravell 这篇文章中的代码IEnumerable 上的动态 LINQ OrderBy
在我的列表视图的“OnSorting”事件中,我添加了以下代码。
protected void lv_Sorting(object sender, ListViewSortEventArgs e)
{
e.Cancel = true;
ViewState["OrderBy"] = e.SortExpression;
lvList.DataBind();
}
我添加了一种相当标准的方法来捕获排序方向列表
public SortDirection sortDirection
{
get
{
if (ViewState["sortdirection"] == null)
{
ViewState["sortdirection"] = SortDirection.Ascending;
return SortDirection.Ascending;
}
else if ((SortDirection)ViewState["sortdirection"] == SortDirection.Ascending)
{
ViewState["sortdirection"] = SortDirection.Descending;
return SortDirection.Descending;
}
else
{
ViewState["sortdirection"] = SortDirection.Ascending;
return SortDirection.Ascending;
}
}
set
{
ViewState["sortdirection"] = value;
}
}
在我的列表视图中,Select 方法如下所示(使用 Marc 的扩展方法)
public IQueryable<SomeObject> GetObjects([ViewState("OrderBy")]String OrderBy = null)
{
var list = GETSOMEOBJECTS();
if (OrderBy != null)
{
switch (sortDirection)
{
case SortDirection.Ascending:
list = list.OrderByDescending(OrderBy);
break;
case SortDirection.Descending:
list = list.OrderBy(OrderBy);
break;
default:
list = list.OrderByDescending(OrderBy);
break;
}
}
return list;
}
我还没有用 GridView 尝试过,但我相当确定它会起到同样的作用。
EDIT这是应该起作用的 linq 扩展类的示例
public static class LinqExtensions
{
public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string property)
{
return ApplyOrder<T>(source, property, "OrderBy");
}
public static IOrderedQueryable<T> OrderByDescending<T>(this IQueryable<T> source, string property)
{
return ApplyOrder<T>(source, property, "OrderByDescending");
}
public static IOrderedQueryable<T> ThenBy<T>(this IOrderedQueryable<T> source, string property)
{
return ApplyOrder<T>(source, property, "ThenBy");
}
public static IOrderedQueryable<T> ThenByDescending<T>(this IOrderedQueryable<T> source, string property)
{
return ApplyOrder<T>(source, property, "ThenByDescending");
}
static IOrderedQueryable<T> ApplyOrder<T>(IQueryable<T> source, string property, string methodName)
{
string[] props = property.Split('.');
Type type = typeof(T);
ParameterExpression arg = Expression.Parameter(type, "x");
Expression expr = arg;
foreach (string prop in props)
{
// use reflection (not ComponentModel) to mirror LINQ
PropertyInfo pi = type.GetProperty(prop);
expr = Expression.Property(expr, pi);
type = pi.PropertyType;
}
Type delegateType = typeof(Func<,>).MakeGenericType(typeof(T), type);
LambdaExpression lambda = Expression.Lambda(delegateType, expr, arg);
object result = typeof(Queryable).GetMethods().Single(
method => method.Name == methodName
&& method.IsGenericMethodDefinition
&& method.GetGenericArguments().Length == 2
&& method.GetParameters().Length == 2)
.MakeGenericMethod(typeof(T), type)
.Invoke(null, new object[] { source, lambda });
return (IOrderedQueryable<T>)result;
}
}
只需将 using 'whatevernamespaceyouused' 添加到页面即可。