Problem with Efficient Gridview paging without datasource control

I am trying to do efficient paging with a gridview without using a datasource control. By efficient, I mean I only retrieve the records that I intend to show.

I am trying to use the PagerTemplate to build my pager functionality.

In short, the problem is that if I bind only the records that I intend to show on the current page, the gridview doesn’t render its pager template, so I don’t get the paging controls.

It’s almost as if I MUST bind more records than I intend to show on a given page, which is not something I want to do.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

You need to create a custom gridview control that inherits from GridView. Without the DataSourceControl, the gridview does not have knowledge of the total number of records that could potentially be bound to the control. If you bind 10 out of 100 records and you set the PageSize property to 10, the gridview only knows that there are 10 records which will be less than or equal to the PageSize and the pager control will not display. In order for your gridview to show the pager, it has to know the total number of records that could potentially be retrieved. By inheriting the gridview and overriding the InitializePager method, we can intercept the pagedDataSource and modify the AllowCustomPaging and VirtualCount methods.

This is the one I created

using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI.WebControls;
using System.ComponentModel;

namespace cly.Web.CustomControls
{
    public class clyGridView : GridView
    {
        private const string _virtualCountItem = "bg_vitemCount";
        private const string _sortColumn = "bg_sortColumn";
        private const string _sortDirection = "bg_sortDirection";
        private const string _currentPageIndex = "bg_pageIndex";

        public clyGridView ()
            : base()
        {
        }

        #region Custom Properties
        [Browsable(true), Category("NewDynamic")]
        [Description("Set the virtual item count for this grid")]
        public int VirtualItemCount
        {
            get
            {
                if (ViewState[_virtualCountItem] == null)
                    ViewState[_virtualCountItem] = -1;
                return Convert.ToInt32(ViewState[_virtualCountItem]);
            }
            set
            {
                ViewState[_virtualCountItem] = value;
            }
        }        

        public string GridViewSortColumn
        {
            get
            {
                if (ViewState[_sortColumn] == null)
                    ViewState[_sortColumn] = string.Empty;
                return ViewState[_sortColumn].ToString();
            }
            set
            {
                if (ViewState[_sortColumn] == null || !ViewState[_sortColumn].Equals(value))
                    GridViewSortDirection = SortDirection.Ascending;
                ViewState[_sortColumn] = value;
            }
        }

        public SortDirection GridViewSortDirection
        {
            get
            {
                if (ViewState[_sortDirection] == null)
                    ViewState[_sortDirection] = SortDirection.Ascending;
                return (SortDirection)ViewState[_sortDirection];
            }
            set
            {
                ViewState[_sortDirection] = value;
            }
        }

        private int CurrentPageIndex
        {
            get
            {
                if (ViewState[_currentPageIndex] == null)
                    ViewState[_currentPageIndex] = 0;
                return Convert.ToInt32(ViewState[_currentPageIndex]);
            }
            set
            {
                ViewState[_currentPageIndex] = value;
            }
        }

        private bool CustomPaging
        {
            get { return (VirtualItemCount != -1); }
        }
        #endregion

        #region Overriding the parent methods
        public override object DataSource
        {
            get
            {
                return base.DataSource;
            }
            set
            {
                base.DataSource = value;
                // store the page index so we don't lose it in the databind event
                CurrentPageIndex = PageIndex;
            }
        }

        protected override void OnSorting(GridViewSortEventArgs e)
        {            
            //Store the direction to find out if next sort should be asc or desc
            SortDirection direction = SortDirection.Ascending;
            if (ViewState[_sortColumn] != null &&  (SortDirection)ViewState[_sortDirection] == SortDirection.Ascending)
            {
                direction = SortDirection.Descending;
            }
            GridViewSortDirection = direction;
            GridViewSortColumn = e.SortExpression;
            base.OnSorting(e);
        }

        protected override void InitializePager(GridViewRow row, int columnSpan, PagedDataSource pagedDataSource)
        {
            // This method is called to initialise the pager on the grid. We intercepted this and override
            // the values of pagedDataSource to achieve the custom paging using the default pager supplied
            if (CustomPaging)
            {
                pagedDataSource.VirtualCount = VirtualItemCount;
                pagedDataSource.CurrentPageIndex = CurrentPageIndex;
            }
            base.InitializePager(row, columnSpan, pagedDataSource);
        }

        protected override object SaveViewState()
        {
            //object[] state = new object[3];
            //state[0] = base.SaveViewState();
            //state[1] = this.dirtyRows;
            //state[2] = this.newRows;
            //return state;

            return base.SaveViewState();
        }

        protected override void LoadViewState(object savedState)
        {

            //object[] state = null;

            //if (savedState != null)
            //{
            //    state = (object[])savedState;
            //    base.LoadViewState(state[0]);
            //    this.dirtyRows = (List<int>)state[1];
            //    this.newRows = (List<int>)state[2];
            //}

            base.LoadViewState(savedState);
        }
        #endregion

        public override string[] DataKeyNames
        {
            get
            {
                return base.DataKeyNames;
            }
            set
            {
                base.DataKeyNames = value;
            }
        }

        public override DataKeyArray DataKeys
        {
            get
            {
                return base.DataKeys;
            }
        }

        public override DataKey SelectedDataKey
        {
            get
            {
                return base.SelectedDataKey;
            }
        }
    }
}

Then when you are binding the data:
gv.DataSource = yourListOrWhatever
gv.VirtualItemCount = numOfTotalRecords;
gv.DataBind();


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x