I have visual web part with custom logic which retrieves me strongly typed list (not SPList -> .NET list object) which than I bind to gridview which has paging enabled. That works fine. Problem is: PAGING. When I use

public static IEnumerable<TSource> Page<TSource>(this IEnumerable<TSource> source, int page, int pageSize)
                return source.Skip((page - 1) * pageSize).Take(pageSize);

i get data subset. When I bind it to gridview, data show correctly but i loose real page count (all items) which i need for gridview page indicator. Normally I would use objectDataSource(with appropriate method for all items count, and method for paging) BUT surprise: It's not enabled for visual webpart and I can't add it to the page. I looked here on the site, also googled, but I can't find some good, simple and useful solution to solve my problem.

PLEASE any useful suggestion will be greatly appreciated!

1 Answer 1


You are doing the paging yourself, which means the GridView isn't aware of all the items so it doesn't display the count. I would recommend letting the GridView handle the paging using ObjectDataSource like you mention.

I'm not sure if you're using a normal GridView or SPGridView.. but take a look at this good tutorial Building A SPGridView Control – Part 1: Introducing the SPGridView. This makes it easy because you just add the pager and connect it to your grid programmatically:

SPGridViewPager pager = new SPGridViewPager();
pager.GridViewId = grid.ID;

Alternatively, you could just write your own paging code and generate the pages yourself.


Here is a simple example.

// goes in SimpleGridView.cs
class SimpleGridView : CompositeControl
    private ObjectDataSource _gridDS;
    private GridView _grid;

    public DataTable SelectData()
        DataTable dataSource = new DataTable();

        // setup columns
        dataSource.Columns.Add("ID", Type.GetType("System.Int32"));
        dataSource.Columns.Add("Total Sales", Type.GetType("System.Double"));
        dataSource.Columns.Add("Created", Type.GetType("System.DateTime"));

        // add some bogus data
        dataSource.Rows.Add(1, "J. Smith", "Europe", 10000, new DateTime(2010, 10, 7, 8, 0, 0));
        dataSource.Rows.Add(2, "J. Smith", "North America", 15000, new DateTime(2010, 10, 8, 9, 00, 0));
        dataSource.Rows.Add(3, "J. Smith", "Asia", 5000, new DateTime(2010, 10, 7, 10, 0, 0));
        dataSource.Rows.Add(4, "S. Jones", "Europe", 7000, new DateTime(2010, 10, 9, 11, 0, 0));
        dataSource.Rows.Add(5, "S. Jones", "North America", 30000, new DateTime(2010, 10, 7, 9, 00, 0));
        dataSource.Rows.Add(6, "S. Jones", "Asia", 8700, new DateTime(2010, 10, 9, 8, 0, 0));
        dataSource.Rows.Add(7, "W. Nguyen", "Europe", 3000, new DateTime(2010, 10, 8, 8, 0, 0));
        dataSource.Rows.Add(8, "W. Nguyen", "North America", 50000, new DateTime(2010, 10, 7, 12, 30, 0));
        dataSource.Rows.Add(9, "W. Nguyen", "Asia", 25000, new DateTime(2010, 10, 7, 8, 0, 0));
        dataSource.Rows.Add(10, "C. O'Reilly", "Europe", 200, new DateTime(2008, 1, 16, 15, 0, 0));
        dataSource.Rows.Add(11, "C. O'Reilly", "North America", 5000, new DateTime(2009, 11, 1, 16, 0, 0));
        dataSource.Rows.Add(12, "C. O'Reilly", "Asia", 8000, new DateTime(2010, 10, 9, 19, 0, 0));

        return dataSource;

    private void GenerateColumns()
        AddBoundField("Total Sales");

    private void AddBoundField(string name)
        BoundField column = new BoundField();
        column.DataField = name;
        column.SortExpression = name;
        column.HeaderText = name;

    protected sealed override void CreateChildControls()
        const string GRIDID = "grid";
        const string DATASOURCEID = "gridDS";

        // initialize the ODS
        _gridDS = new ObjectDataSource();
        _gridDS.ID = DATASOURCEID;
        // calling our SelectData function in this CompositeControl
        _gridDS.SelectMethod = "SelectData";
        _gridDS.TypeName = this.GetType().AssemblyQualifiedName;
        _gridDS.ObjectCreating += new ObjectDataSourceObjectEventHandler(gridDS_ObjectCreating);


        // Initialize the grid and link it to the ObjectDataSource
        _grid = new GridView();
        _grid.ID = GRIDID;
        _grid.DataSourceID = _gridDS.ID;
        _grid.AutoGenerateColumns = false;

        // Paging
        _grid.AllowPaging = true;
        _grid.PageSize = 10;

        // Sorting
        _grid.AllowSorting = true;



        // setting PagerTemplate to null here will display page numbers for paging
        _grid.PagerTemplate = null;

    private void gridDS_ObjectCreating(object sender, ObjectDataSourceEventArgs e)
        // our ObjectDataSource uses this CompositeControl to select data
        e.ObjectInstance = this;

This goes in your web part class:

protected override void CreateChildControls()

    SimpleGridView grid = new SimpleGridView();
  • I use normal GridView. Also I would LIKE that I can use ObjectDataSource but i can't place it on the form of visual web part. Control, simply said, isn't available in toolbox and I don't know why is that and how bypass that.
    – trip
    Sep 30, 2011 at 14:13
  • I added an example of how to instantiate an ObjectDataSource programmatically with a GridView. Hopefully that helps!
    – Kit Menke
    Sep 30, 2011 at 15:54
  • Thanx Kit. It works perfectly.
    – trip
    Oct 3, 2011 at 13:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.