这是我解决排序表达式绑定问题的方法。
我没有设置SortExpression
为真实的属性名称,而是将其设置为列的序号位置。
<Columns>
<asp:TemplateField HeaderText="Name" SortExpression="1" >
<ItemTemplate>
<%# Item.Name %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Job Title" SortExpression="2" >
<ItemTemplate>
<%# Item.JobTitle %>
</ItemTemplate>
</asp:TemplateField>
</Columns>
然后,将处理程序附加到 gridview 的Sorting
事件。
<asp:GridView runat="server"
OnSorting="Sorting"
...
事件参数之一是您之前定义的排序表达式(即"1"
or "2"
)。您可以使用此值以编程方式将排序表达式重新绑定到实际属性名称。
注意:遵循这种方法意味着放弃升序/降序排序之间的自动切换。不过,重新实现它并不是特别困难。
注意:我使用基于反射的方法在执行时确定属性名称。
protected void Sorting(object sender, GridViewSortEventArgs e)
{
int columnPosition;
if (!int.TryParse(e.SortExpression, out columnPosition))
{
return;
}
switch (columnPosition)
{
case 1:
e.SortExpression = Reflector.GetPropertyName<Employee>(o => o.Name);
break;
case 2:
e.SortExpression = Reflector.GetPropertyName<Employee>(o => o.JobTitle);
break;
}
var grid = (GridView)sender;
if (grid.SortExpression == e.SortExpression)
{
if (grid.SortDirection == SortDirection.Ascending)
{
e.SortDirection = SortDirection.Descending;
}
}
}
最后,这是我Reflector
在上面示例中使用的类的代码。
/// <summary>Utility class. Provides static reflection-based utility methods.</summary>
public static class Reflector
{
#region Public Methods and Operators
/// <summary>Gets the name of the property that is accessed by the given expression. Usage: <c>Reflector.GetPropertyName<MyClass>(obj => obj.MyProperty);</c></summary>
/// <param name="selectorExpression">The expression that selects the property of which the name should be returned.</param>
/// <typeparam name="T">The type that defines the property.</typeparam>
/// <returns>The name of the property.</returns>
public static string GetPropertyName<T>(Expression<Func<T, object>> selectorExpression) where T : class
{
MemberExpression memberExpression;
var unaryExpression = selectorExpression.Body as UnaryExpression;
if (unaryExpression != null)
{
memberExpression = unaryExpression.Operand as MemberExpression;
}
else
{
memberExpression = selectorExpression.Body as MemberExpression;
}
if (memberExpression == null)
{
return null;
}
return memberExpression.Member.Name;
}
#endregion
}