【发布时间】:2012-11-07 12:36:23
【问题描述】:
我正在使用 ListView 来显示分页数据:
<asp:ListView ID="listOfItems" runat="server" DataSourceID="ItemsDataSource" EnableModelValidation="True" InsertItemPosition="FirstItem" ItemPlaceholderID="ItemRowContainer">
<LayoutTemplate>
<div class="tablecontainer">
<div class="pagination-top">
<custom:TablePaginationControl ID="TablePaginationControl1" runat="server" ControlID="listOfItems" ShowPageSizeList="true" />
</div>
<table class="list-view">
<tr>
<th class="first-column" width="350px">
<asp:LinkButton ID="SortByName" runat="server" CommandArgument="Name" CommandName="SortMainList" OnCommand="SortItems" Text="<%$ Resources:Name %>"></asp:LinkButton>
</th>
...
</tr>
<tbody>
<tr runat="server" id="ItemRowContainer" />
</tbody>
</table>
</div>
</LayoutTemplate>
...
</asp:ListView>
数据源定义:
<asp:ObjectDataSource ID="ItemsDataSource" runat="server" EnablePaging="True" InsertMethod="AddItems" SelectCountMethod="SelectItemsCount" SelectMethod="SelectItems" TypeName="SHLCentral.TheLibrary.Web.View.DocumentManagementControl, ClientPortal.Web, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cd2852a10d692fb9" UpdateMethod="UpdateItems">
...
</asp:ObjectDataSource>
后面的相关代码是由这两种方法组成的:
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();
}
}
所以我的意图是:当用户单击“名称”列标题中包含的LinkButton 时(为了清楚起见,我除了一列之外都省略了),调用SortItems 方法:它设置排序列名称和排序顺序到ViewState,然后使用DataBind 方法重新加载ListView。在ObjectDataSource 的Select 方法中,我们读取了这个ViewState 值并使用它们对数据进行排序。
在所有这些方法上都设置断点,当我点击LinkButton时,我可以看到有这个调用序列:
OnLoadSortItemsSelectItems
我遇到的问题是,当我到达SelectItems 方法时,ViewState 完全为空(它有 0 个键):如果我在页面的 Load 方法上设置断点,我会看到控件包含所有这些只加载一次。 DataBind 方法似乎没有触发控件的任何加载,它似乎只是触发了控件新实例的SelectItems 方法(这意味着如果我设置了一个实例,而不是使用ViewState SortItems方法中的字段,进入SelectItems方法时该字段为空)。
我确信 ViewState 在页面上处于活动状态(例如,我可以使用 Firefox 扩展程序在浏览器端找到 ViewState 键)。
关于页面/控件的生命周期,我不太清楚。有人能解释一下它对我来说是什么吗?
【问题讨论】:
标签: c# asp.net listview viewstate objectdatasource