I think you are trying to use the wrong aspect to do the work which is why you are finding it painful to achieve.
Getting the entire collection of objects and then rendering a subset of them is incredibly wasteful, how do you know your user is going to look at all the pages? What if there are 10,000 objects?
You want to retrieve 2 pieces of information from the database, the first page of objects and a count of the total number of objects - this should be handled from your controller ( preferably by calling into some form of service rather than directly to the database but thats an argument for another day ). Package that information into a class that contains any rendering helpers you need and send that class to the view. Given the object count and the page size, you can build simple navigation links which post back to the action passing the new page number.
public class GridView<T>
{
private Dictionary<string, Func<T, string> _columnMap;
public GridView( IEnumerable<T> items, long totalItems, long currentPage )
{
Items = items;
Count = totalItems;
CurrentPage = currentPage;
}
public long Count { get; private set; }
public long CurrentPage { get; private set; }
public IEnumerable<string> Columns { get; }
public IEnumerable<T> Items { get; private set; }
public void AddColumn( string name, Func<T, string> data )
{
_columnMap.Add( columnName, data );
}
public string GetColumnValue( string name, T item )
{
var valueExtractor = _columnMap[name];
return valueExtractor(item);
}
public string GetPageCount()
{
// Calculate page count, convert to string and return
}
// Might be easier to make these two extension methods for the html helper class
// so that you get easier access to the context of the current action
public string GetPreviousLink()
{
}
public string GetNextLink()
{
}
}
In the controller ...
// Use the route definition to set the page to default to 1
public ActionResult ShowProducts( int page )
{
// Get the list of products for the requested page
var currentPageData = ...
// Get the total number of products
var productCount = ...
var gridData = new GridView<Product>( currentPageData, productCount, page );
gridData.AddColumn( "Name", p => p.ProductName );
gridData.AddColumn( "Price", p => p.Price.ToString("c") );
gridData.AddColumn( "In Stock", p => p.StockLevel.ToString());
return View( gridData );
}
Somewhere in the view ...
<% =Html.RenderPartial( "GridView", Model ) %>
In the partial ...
<table>
<tr>
<% foreach( var column in Model.Columns ) { %>
<th><% =column %></td>
<% } %>
</tr>
<% foreach( var item in Model.Items ) { %>
<tr>
<% foreach( var column in Model.Columns ) { %>
<td><% =Model.GetColumnValue( column, item ) %></td>
<% } %>
<tr>
<% } %>
<tr>
<td colspan="<% =Model.Columns.Count %>">Showing Page <% =Model.CurrentPage %> of <% =Model.GetPageCount() %></td>
</tr>
<tr>
<td colspan="<% =Model.Columns.Count %>"><% =Model.GetPreviousLink() %> | <% =Model.GetNextLink() %></td>
</tr>
</table>
Please note, all code shown is aircode and is not guaranteed to work, merely demonstrate a series of concepts.