Reputation: 3444
I have an application where paging is done in the database. That is, the call to retrieve a list of items includes the page number, the page size, and will return only that pages' data. For example:
ItemCollection items = ListAllItems(1, 20); // page 1, show 20 items per page
ItemCollection includes a PagingUtil property that is a class that contains properties to support paging without retrieving all records.
public class PagingUtil
{
public int StartRow { get; private set; }
public int EndRow { get; private set; }
public int TotalPages { get; private set; }
public bool HasPrevPage { get; private set; }
public bool HasNextPage { get; private set; }
public int TotalCount { get; private set; }
private PagingUtil() {}
public PagingUtil(int pageNumber, int visiblePerPage, int totalCount)
{
... logic for setting property values here ...
}
}
I would like to use the BindingNavigator Control UI in a Windows Forms application without having to specify a BindingSource.
The problem is, the BindingNavigator will only be rendered as enabled if a BindingSource is set. Setting the Enabled property to true both in the designer and in code is not respected and I cannot seem to find a workaround or alternative stock control.
Is it possible to use the BindingNavigator this way? I can create a custom paging control if needed, but would prefer not to if I don't have to.
Upvotes: 3
Views: 8291
Reputation: 311
I tried to do a similar thing today, and just ended up inventing some data objects for the BindingNavigator to manage which then represented the pages of the actual data in the database. A BindingSource can be given an IListSource as its DataSource, from which it will then draw the list of data to bind against.
class PageList : System.ComponentModel.IListSource
{
private const int itempagesize = 250;
private long totalitems;
public PageList(string tablename, long totalrecords)
{
this.TableName = tablename;
totalitems = totalrecords;
}
public bool ContainsListCollection { get; protected set; }
public System.Collections.IList GetList()
{
List<ItemPage> pages = new List<ItemPage>();
int totalPages = (int)Math.Ceiling((double)totalitems / (double)itempagesize);
pages.AddRange(Enumerable.Range(0, totalPages).Select(
pageidx => new ItemPage(itempagesize, pageidx * itempagesize)));
return pages;
}
public string TableName { get; protected set; }
public class ItemPage
{
public ItemPage(int limit, int offset)
{
this.Limit = limit;
this.Offset = offset;
}
public readonly int Limit;
public readonly int Offset;
}
}
So I have a BindingNavigator tied to a BindingSource, and when I want to set the total number of available pages of data I just do a:
bsDataPages.DataSource = new PageList(tableName, recordCount);
Then the binding source event handler is fired when the navigator is used
private void bsDataPages_CurrentChanged(object sender, EventArgs e)
{
PageList list = bsDataPages.DataSource as PageList;
PageList.ItemPage page = bsDataPages.Current as PageList.ItemPage;
var items = m_datastore.GetTableItems(m_conn,
list.TableName,page.Limit,page.Offset);
}
and I can go and fetch that page of data from the database.
Upvotes: 6
Reputation: 3444
There was no way to override the binding behavior in the BindingNavigator which is comprised of a ToolStrip and several controls to support navigation. I ended up copying the controls from the BindingNavigator into a new ToolStrip and added my paging support there.
Upvotes: 3