Monday, August 1, 2011

DataPagerRepeater in ASP.NET

 Repeater is a type of datasource control which is used to display the data. Moreover it is a readonly control. You can only just able to display the data and not do any kind of insert or delete operation.


But there may be a requirement for you where you want to do paging for the repeater control, well if that is the case then  there is a bad news for you that is the repeater doesnot supports paging.


You may say why go for repeater control in that case instead of ListView control, repeater is readonly so by performance wise it is faster than ListView control.


So how to support paging for repeater control itz simple create a custom repeater server control which  implements IPageableItemContainer and also you should need to include the reference of System.Web.Extensions.


Below is the code which you can create as a custom server control and make use of this DataPagerRepeater control.



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


namespace DataPagerRepeater
{


    [ToolboxData("<{0}:DataPagerRepeater runat=server PersistentDataSource=true>")]
    public class DataPagerRepeater : Repeater,
       System.Web.UI.WebControls.IPageableItemContainer, INamingContainer
    {
        ///
        /// Number of rows to show
        ///

        public int MaximumRows { get { return ViewState["MaximumRows"] != null ? (int)ViewState["MaximumRows"] : -1; } }


        ///
        /// First row to show
        ///

        public int StartRowIndex { get { return ViewState["StartRowIndex"] != null ? (int)ViewState["StartRowIndex"] : -1; } }


        ///
        /// Total rows. When PagingInDataSource is set to true you must get the total records from the datasource (without paging) at the FetchingData event
        /// When PagingInDataSource is set to true you also need to set this when you load the data the first time.
        ///

        public int TotalRows { get { return ViewState["TotalRows"] != null ? (int)ViewState["TotalRows"] : -1; } set { ViewState["TotalRows"] = value; } }


        ///
        /// If repeater should store data source in view state. If false you need to get and bind data at post back. When using a connected data source this is handled by the data source.  
        ///       

        public bool PersistentDataSource
        {
            get { return ViewState["PersistentDataSource"] != null ? (bool)ViewState["PersistentDataSource"] : true; }
            set { ViewState["PersistentDataSource"] = value; }
        }


        ///
        /// Set to true if you want to handle paging in the data source. 
        /// Ex if you are selecting data from the database and only select the current rows 
        /// you must set this property to true and get and rebind data at the FetchingData event. 
        /// If this is true you must also set the TotalRecords property at the FetchingData event.     
        ///

        ///
        ///
        public bool PagingInDataSource
        {
            get { return ViewState["PageingInDataSource"] != null ? (bool)ViewState["PageingInDataSource"] : false; }
            set { ViewState["PageingInDataSource"] = value; }
        }
        ///


        /// Checks if you need to rebind data source at postback
        ///

        public bool NeedsDataSource
        {
            get
            {
                if (PagingInDataSource)
                    return true;
                if (IsBoundUsingDataSourceID == false && !Page.IsPostBack)
                    return true;
                if (IsBoundUsingDataSourceID == false && PersistentDataSource == false && Page.IsPostBack)
                    return true;
                else
                    return false;
            }
        }


        ///
        /// Loading ViewState
        ///

        ///
        protected override void LoadViewState(object savedState)
        {
            base.LoadViewState(savedState);




            //if (Page.IsPostBack)
            //{




            //    if (!IsBoundUsingDataSourceID && PersistentDataSource && ViewState["DataSource"] != null)
            //    {
            //        this.DataSource = ViewState["DataSource"];
            //        this.DataBind(true);
            //    }
            //    if (IsBoundUsingDataSourceID)
            //    {
            //        this.DataBind();
            //    }
            //}
        }


        protected override void OnLoad(System.EventArgs e)
        {
            if (Page.IsPostBack)
            {
                if (NeedsDataSource && FetchingData != null)
                {
                    if (PagingInDataSource)
                    {
                        SetPageProperties(StartRowIndex, MaximumRows, true);
                    }
                    FetchingData(this, null);
                }


                if (!IsBoundUsingDataSourceID && PersistentDataSource && ViewState["DataSource"] != null)
                {
                    this.DataSource = ViewState["DataSource"];
                    this.DataBind();
                }
                if (IsBoundUsingDataSourceID)
                {
                    this.DataBind();
                }


            }


            base.OnLoad(e);
        }


        ///
        /// Method used by pager to set totalrecords
        ///

        /// startRowIndex
        /// maximumRows
        /// databind
        public void SetPageProperties(int startRowIndex, int maximumRows, bool databind)
        {
            ViewState["StartRowIndex"] = startRowIndex;
            ViewState["MaximumRows"] = maximumRows;


            if (TotalRows > -1)
            {
                if (TotalRowCountAvailable != null)
                {
                    TotalRowCountAvailable(this, new PageEventArgs((int)ViewState["StartRowIndex"], (int)ViewState["MaximumRows"], TotalRows));
                }
            }
        }


        ///
        /// OnDataPropertyChanged
        ///

        protected override void OnDataPropertyChanged()
        {
            if (MaximumRows != -1 || IsBoundUsingDataSourceID)
            {
                this.RequiresDataBinding = true;
            }


            base.OnDataPropertyChanged();
        }


        ///
        /// Renders only current items selected by pager
        ///

        ///
        protected override void RenderChildren(HtmlTextWriter writer)
        {
            if (!PagingInDataSource && MaximumRows != -1)
            {
                foreach (RepeaterItem item in this.Items)
                {
                    if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
                    {
                        item.Visible = false;
                        if (item.ItemIndex >= (int)ViewState["StartRowIndex"] && item.ItemIndex < ((int)ViewState["StartRowIndex"] + (int)ViewState["MaximumRows"]))
                        {
                            item.Visible = true;
                        }
                    }
                    else
                    {
                        item.Visible = true;
                    }
                }
            }
            base.RenderChildren(writer);
        }




        ///
        /// Get Data
        ///

        ///
        protected override System.Collections.IEnumerable GetData()
        {
            System.Collections.IEnumerable dataObjects = base.GetData();


            if (dataObjects == null && this.DataSource != null)
            {
                if (this.DataSource is System.Collections.IEnumerable)
                    dataObjects = (System.Collections.IEnumerable)this.DataSource;
                else
                    dataObjects = ((System.ComponentModel.IListSource)this.DataSource).GetList();
            }


            if (!PagingInDataSource && MaximumRows != -1 && dataObjects != null)
            {
                int i = -1;


                if (dataObjects != null)
                {
                    i = 0;
                    foreach (object o in dataObjects)
                    {
                        i++;
                    }


                }


                ViewState["TotalRows"] = i;


                if (!IsBoundUsingDataSourceID && PersistentDataSource)
                    ViewState["DataSource"] = this.DataSource;


                SetPageProperties(StartRowIndex, MaximumRows, true);


            }


            if (PagingInDataSource && !Page.IsPostBack)
            {
                SetPageProperties(StartRowIndex, MaximumRows, true);
            }


            return dataObjects;
        }


        ///
        /// Event when pager/repeater have counted total rows
        ///

        public event System.EventHandler TotalRowCountAvailable;


        ///
        /// Event when repeater gets the data on postback
        ///

        public event System.EventHandler FetchingData;
    }
}

1 comment: