Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
323 views
in Technique[技术] by (71.8m points)

c# - 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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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();

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...