C# 使用带有LinkButton和ViewState的ObjectDataSource对ListView进行排序
我正在使用ListView显示分页数据:C# 使用带有LinkButton和ViewState的ObjectDataSource对ListView进行排序,c#,asp.net,listview,viewstate,objectdatasource,C#,Asp.net,Listview,Viewstate,Objectdatasource,我正在使用ListView显示分页数据: ... ... 数据源定义: ... 后面的相关代码由以下两种方法组成: public IEnumerable<ListDocumentsResult> SelectItems( int maximumRows, int startRowIndex) { var results = Controller.ListDocuments(new ListDocumentsRequest()); Proper
...
...
数据源定义:
...
后面的相关代码由以下两种方法组成:
public IEnumerable<ListDocumentsResult> SelectItems(
int maximumRows,
int startRowIndex)
{
var results = Controller.ListDocuments(new ListDocumentsRequest());
PropertyInfo sortProperty;
try
{
sortProperty = typeof (ListDocumentsResult).GetProperty((string) ViewState["mainListSortColumn"]);
}
catch
{
sortProperty = null;
}
Func<ListDocumentsResult, object> sortFunction = sortProperty == null
? (Func<ListDocumentsResult, object>) (ldr => ldr.LastUpdatedDate)
: (ldr => sortProperty.GetValue(ldr, new object[0]));
return
(sortProperty == null || !((bool) ViewState["mainListSortAsc"])
? results.OrderByDescending(sortFunction)
: results.OrderBy(sortFunction))
.Skip(startRowIndex)
.Take(maximumRows);
}
protected void SortItems(object sender, CommandEventArgs e)
{
if (e.CommandName == "SortMainList")
{
var sortColumn = (string) e.CommandArgument;
if ((string)ViewState["mainListSortColumn"] == sortColumn)
{
ViewState["mainListSortAsc"] = !(bool)ViewState["mainListSortAsc"];
}
else
{
ViewState["mainListSortAsc"] = true;
ViewState["mainListSortColumn"] = sortColumn;
}
DataBind();
}
}
public IEnumerable SelectItems(
int最大行数,
int startRowIndex)
{
var results=Controller.ListDocuments(新的ListDocumentsRequest());
财产信息或财产;
尝试
{
sortProperty=typeof(ListDocumentsResult).GetProperty((字符串)ViewState[“mainListSortColumn”]);
}
抓住
{
sortProperty=null;
}
Func sortFunction=sortProperty==null
?(Func)(ldr=>ldr.lastUpdateDate)
:(ldr=>sortProperty.GetValue(ldr,新对象[0]);
返回
(sortProperty==null | |!((bool)ViewState[“mainListSortAsc”])
?results.OrderByDescending(排序函数)
:results.OrderBy(sortFunction))
.Skip(startRowIndex)
.取(最大行数);
}
受保护的无效SortItems(对象发送方,CommandEventArgs e)
{
if(e.CommandName==“SortMainList”)
{
var sortColumn=(字符串)e.CommandArgument;
如果((字符串)视图状态[“mainListSortColumn”]==sortColumn)
{
ViewState[“mainListSortAsc”]=!(bool)ViewState[“mainListSortAsc”];
}
其他的
{
ViewState[“mainListSortAsc”]=true;
ViewState[“mainListSortColumn”]=sortColumn;
}
数据绑定();
}
}
因此,我的意图是:当用户单击“名称”列标题中包含的LinkButton
时(为了清晰起见,我省略了除一列以外的所有列),调用SortItems
方法:它将排序的列名和排序顺序设置为视图状态
,然后使用DataBind
方法重新加载ListView
。在ObjectDataSource
的Select方法中,我们读取这个ViewState
值,并使用它们对数据进行排序
将断点放在所有这些方法上,当我单击链接按钮时,我可以看到调用序列:
OnLoad
SortItems
SelectItems
我遇到的问题是,当我使用SelectItems
方法时,ViewState
完全为空(它有0个键):如果我在页面的Load方法上设置断点,我会看到包含所有这些内容的控件只加载一次。DataBind
方法似乎不会触发控件的任何加载,它似乎只是触发控件新实例的SelectItems
方法(这意味着,如果我没有使用ViewState
,而是在SortItems
方法中设置了一个实例字段,那么当进入SelectItems
方法时,该字段为空)
我确信ViewState
在页面上处于活动状态(例如,我可以使用Firefox扩展在浏览器端找到ViewState
键)
我不太清楚页面/控件的生命周期。有人能解释一下它是什么吗?有很多更简单的方法
首先,不是自定义的命令名
,而是将一个内置名称放入排序链接按钮中。该名称为排序
那么你有
<asp:LinkButton ID="SortByName" runat="server" CommandArgument="Name" CommandName="Sort" />
然后将数据提供程序方法修改为:
public IEnumerable<ListDocumentsResult> SelectItems(
string OrderBy,
int maximumRows,
int startRowIndex)
这也很简单
请注意,动态linq中存在一个小错误(或不便之处)——当排序顺序为空时,它会抛出一个异常
然后查找此代码(第47行及以下)
并手动将其更改为
public static IQueryable OrderBy(this IQueryable source, string ordering, params object[] values) {
if ( string.IsNullOrEmpty( ordering ) ) return source;
if (source == null) throw new ArgumentNullException("source");
if (ordering == null) throw new ArgumentNullException("ordering");
完成。有很多更简单的方法
首先,不是自定义的命令名
,而是将一个内置名称放入排序链接按钮中。该名称为排序
那么你有
<asp:LinkButton ID="SortByName" runat="server" CommandArgument="Name" CommandName="Sort" />
然后将数据提供程序方法修改为:
public IEnumerable<ListDocumentsResult> SelectItems(
string OrderBy,
int maximumRows,
int startRowIndex)
这也很简单
请注意,动态linq中存在一个小错误(或不便之处)——当排序顺序为空时,它会抛出一个异常
然后查找此代码(第47行及以下)
并手动将其更改为
public static IQueryable OrderBy(this IQueryable source, string ordering, params object[] values) {
if ( string.IsNullOrEmpty( ordering ) ) return source;
if (source == null) throw new ArgumentNullException("source");
if (ordering == null) throw new ArgumentNullException("ordering");
完成。如果SelectMethod
不是静态的,则ObjectDataSource
控件将创建TypeName
中指定类型的新实例,并对该实例调用该方法
您需要将排序表达式的参数添加到select方法并在ObjectDataSource
上设置,或者需要处理并将ObjectInstance
设置到现有控件实例。如果SelectMethod
不是静态的,则ObjectDataSource
控件将创建一个新的在TypeName
中指定的类型的实例,并调用该实例上的方法
您需要将排序表达式的参数添加到select方法中,并在ObjectDataSource
上设置,或者需要处理并将ObjectInstance
设置到现有控件实例。感谢您提供了详尽的答案。由于我想不起来的原因,我认为SortParameterName属性处于启用状态当ObjectDataSource与GridView(与ListView相反)一起使用时使用。但不,它实际上是按照您所说的那样工作的。我还没有研究Dynamic.cs,所以我当然还需要修改代码来处理“Name DESC”的情况,-这并没有使我的代码变得更漂亮…但它可以工作。您不需要修改任何东西。正如我所说的“Name”和“Name DESC”将在