I have a paged ASP.NET ListView. The data shown is filtered, which can be controlled by a form. When the filter form changes, I create a new query, and perform a DataBind.
The problem however, when I go to the next page, and set a filter, the ListView shows "No data was returned". That is not weird, because after the filter is applied, there is only one page of data.
So what I want to do is reset the pager. Is that a correct solution to the problem? And how do I do that?
I use this hack in my Load handler. It'll not reset the pager if the number of result items is the same, but the page index will still be valid so I can live with that for now.
if (IsPostBack)
{
DataPager pgr = MyListView.FindControl("MyPager") as DataPager;
if (pgr != null && MyListView.Items.Count != pgr.TotalRowCount)
{
pgr.SetPageProperties(0, pgr.MaximumRows, false);
}
}
If you know how to do it, it is simple. I added the code below to my onchange
-events of my filter:
DataPager pager = ListViewReference.FindControl("DataPagerId") as DataPager;
if (pager != null)
{
pager.SetPageProperties(0, pager.PageSize, true);
}
Either of the above solutions are correct as they both call the same method. I just think it should be pointed out that you should call yourPagerElement.SetPageProperties(...)
wherever you want your datasource (ie a list or an array, etc.) to be updated. For example, after applying some filtration or something that greatly changes the list size.
You may have problems if your listview is automatically bounded (i.e. ObjectDataSource)
Load event handler doesn't work, because you haven't yet the new DataPager.TotalRowPage value, but you can handle Page_PreRenderComplete, like this:
protected void Page_PreRenderComplete(object sender, EventArgs e)
{
// PreRenderComplete occurs just after databindings page events
// And saves to viewstate
// Trick on search to avoid "No data" on results when old page is greater than actual row count
if (DataPager1.StartRowIndex > DataPager1.TotalRowCount )
DataPager1.SetPageProperties(0, DataPager1.MaximumRows, true);
}
This always leaves ListView in a page with data. If page is greater than TotalRow, switch to first page.
Notes: I'm using efective paging, and returning only the data to be displayed, so I need to rebind de datasource (last parameter (true))
Cons: Double databind if StartRowIndex is greater than TotalRowCount.