views:

13

answers:

0

Hi all, I'm extending asp:Repeater to use DataPager, and now my code work with SqlDataSource. To get better performance, I want to use ObjectDataSource with it, but I have to use QueryStringField of DataPager, otherwise I have to click page number twice to make it work. Can any one help on this? this is my code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI.WebControls;
using System.Web.UI;

namespace WebTest.UserControl
{
    public class PageableRepeater : Repeater,
       System.Web.UI.WebControls.IPageableItemContainer
    {
        private static readonly object EventTotalRowCountAvailable = new object();

        private int _startRowIndex = 0;
        private int _maximumRows = -1;
        private int _totalRowCount = -1;

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            Page.RegisterRequiresControlState(this);
        }

        protected override void LoadControlState(object savedState)
        {
            _startRowIndex = 0;
            _maximumRows = -1;
            _totalRowCount = -1;
            object[] state = savedState as object[];

            if (state != null)
            {
                base.LoadControlState(state[0]);

                if (state[1] != null)
                {
                    _totalRowCount = (int)state[1];
                }

            }
            else
            {
                base.LoadControlState(null);
            }

            if (!IsViewStateEnabled)
            {
                OnTotalRowCountAvailable(new PageEventArgs(_startRowIndex, _maximumRows, _totalRowCount));
            }
        }

        protected override object SaveControlState()
        {
            object baseState = base.SaveControlState();
            if (baseState != null || _totalRowCount != -1)
            {

                object[] state = new object[2];

                state[0] = baseState;
                state[1] = _totalRowCount;

                return state;
            }
            return true;
        }

        protected override System.Collections.IEnumerable GetData()
        {
            ListViewPagedDataSource pagedDataSource = new ListViewPagedDataSource();

            pagedDataSource.StartRowIndex = _startRowIndex;
            pagedDataSource.MaximumRows = _maximumRows;
            if (DataSource is ObjectDataSource)
            {
                SelectArguments.StartRowIndex = _startRowIndex;
                SelectArguments.MaximumRows = _maximumRows;
                SelectArguments.RetrieveTotalRowCount = true;

                pagedDataSource.DataSource = base.GetData();
                _totalRowCount = SelectArguments.TotalRowCount;
                pagedDataSource.AllowServerPaging = true;
                pagedDataSource.TotalRowCount = _totalRowCount;
            }
            else
            {
                pagedDataSource.DataSource = base.GetData();
                pagedDataSource.AllowServerPaging = false;
                pagedDataSource.TotalRowCount = 0;
                _totalRowCount = pagedDataSource.DataSourceCount;
            }
            return pagedDataSource;
        }

        protected override void CreateControlHierarchy(bool useDataSource)
        {
            base.CreateControlHierarchy(useDataSource);
            OnTotalRowCountAvailable(new PageEventArgs(_startRowIndex, _maximumRows, _totalRowCount));
        }

        private void OnTotalRowCountAvailable(PageEventArgs pageEventArgs)
        {
            EventHandler<PageEventArgs> handler = (EventHandler<PageEventArgs>)Events[EventTotalRowCountAvailable];
            if (handler != null)
            {
                handler(this, pageEventArgs);
            }
        }

        #region System.Web.UI.WebControls.IPageableItemContainer
        public int MaximumRows
        {
            get { return _maximumRows; }
        }

        public int StartRowIndex
        {
            get { return _startRowIndex; }
        }

        public void SetPageProperties(int startRowIndex, int maximumRows, bool databind)
        {
            if (maximumRows < 1)
            {
                throw new ArgumentOutOfRangeException("maximumRows");
            }
            if (startRowIndex < 0)
            {
                throw new ArgumentOutOfRangeException("startRowIndex");
            }

            _startRowIndex = startRowIndex;
            _maximumRows = maximumRows;

            if (databind)
            {
                RequiresDataBinding = true;
            }
        }

        public event EventHandler<PageEventArgs> TotalRowCountAvailable
        {
            add
            {
                Events.AddHandler(EventTotalRowCountAvailable, value);
            }
            remove
            {
                Events.RemoveHandler(EventTotalRowCountAvailable, value);
            }
        }
        #endregion
    }
}

By the way, I found another implementation to this on CodeProject: http://beta.codeproject.com/KB/webforms/DataPagerAndRepeater.aspx, but I don't think it use IPageableItemContainer very well.