<asp:DataPager ID="pgrFooBars" PagedControlID="lvFooBars" QueryStringField="page" runat="server" > <Fields> <asp:NumericPagerField /> </Fields> </asp:DataPager>
代码背后
protected void Page_Load(object sender,EventArgs e) { ConfigureBlogPostListView(); } private void ConfigureBlogPostListView() { int pageNum; int.TryParse(Request.Params["page"],out pageNum); int pageSize = 20; PagedList<IFooBar> FooBars = FooService.GetPagedFooBars( new PagingSettings(pageNum,pageSize)); ListViewPagedDataSource ds = new ListViewPagedDataSource(); ds.AllowServerPaging = true; ds.DataSource = FooBars; ds.MaximumRows = pageSize; ds.StartRowIndex = pageNum; //TotalCount is the total number of records in the entire set,not just those loaded. ds.TotalRowCount = FooBars.TotalCount; lvFooBars.DataSource = ds; lvFooBars.DataBind(); pgrFooBars.PageSize = pageSize; pgrFooBars.SetPageProperties(pageNum,FooBars.TotalCount,true); }
PagedList来自RobConery的有用的帖子http://blog.wekeroad.com/2007/12/10/aspnet-mvc-pagedlistt/.
问题是DataPager似乎正在使用ListView的Count属性来确定记录的总数,在这种情况下为20.不知怎的,它需要知道有1500个记录,而不是20个记录. DataPager有一个属性TotalRowCount,但这是只读.
我从未看到服务器端分页的DataPager示例,但假设它可以做服务器端分页,否则QueryStringField属性有什么好处?
我知道您可以使用像这样的4GuysFromRolla http://www.4guysfromrolla.com/articles/031506-1.aspx这样的方法来做一个自定义的分页解决方案,但是我首先想知道在创建自定义解决方案之前是否可以使用DataPager解决方案.
UPDATE
我看到的越多,我得出的结论是越多,这是不可能的,不幸的是,数据页是仅针对小型网站的控件.如果控件正确构建,我想做的应该非常简单.我想能说
dpFooBars.TotalRowCountComputed = false; dpFooBars.TotalRowCount = AnyNumberThatISoChoose;
我一直在寻找一些破解来完成同样的事情,但是看起来数据库的TotalRowCount是根据它绑定到的数据源中的实际数量来计算的.对我来说似乎很奇怪,Microsoft将同时创建一个ListViewPagedDataSource()类和一个DataPager,而不是一起工作,但这似乎是发生了什么.
更新2(AHA MOMENT?)
似乎已经可以通过使用ObjectDataSource并自定义SelectCountMethod()来从.Net 2.0进行服务器端分页.我相信应该可以定制ObjectDataSource来满足我的需要.嗯.我会在周末离开,所以这将是几天,我看看这是否有效.敬请关注,真信徒.
解决方法
这可能不会对您的情况有任何帮助,因为我注意到,您调用某种服务可能不会(并且不应该)返回一个IQueryable结果,这对于此工作是必需的.无论如何,无论如何,你有兴趣…
aspx标记:
<asp:ListView ID="lvFooBars" DataSourceID="dsLinq" ....> ...... </asp:ListView> <asp:DataPager ID="pgrFooBars" PagedControlID="lvFooBars" QueryStringField="page" runat="server" > <Fields> <asp:NumericPagerField /> </Fields> </asp:DataPager> <asp:LinqDataSource id="dsLinq" runat="server" OnSelecting="dsLinq_Selecting" />
protected void dsLinq_Selecting(object sender,LinqDataSourceSelectEventArgs e) { //notice this method on FooService requires no paging variables e.Result = FooService.GetIQueryableFooBars(); }
注意,MSDN关于QueryStringField属性的状态:
Setting this property is useful if you
want to have all the pages of data
indexed by a search engine. This
occurs because the control produces a
different URL for each page of data.
更新:实际上,您可以使用ObjectDataSource控件(而不是LinqDataSource控件)使用ObjectDataSource控件来工作 – 请参阅this article and download the sample.使用ObjectDataSource并不像使用LinqDataSource控件那么简单,它使用的是较少的魔术linq内容(而是使用堆映射到业务/数据层方法的魔术字符串),并允许IEnumerable暴露您的数据访问方法而不是IQueryable.
尽管如此,我从来没有真正在我的UI标记中嵌入任何类型的DataSource控件(我相信这是必要的)的粉丝,所以我可能会指导DataBager控件,除了您在第一次更新中建议的小应用程序.
约翰,我注意到的另一件事是,你正在试图将标准的Asp.Net服务器控件(依赖于ViewState)与用作Asp.Net Mvc应用程序的辅助类开发的PagedList类结合在一起.虽然这可能有效,但可能会有更简单的路线.