Проблема при расширении asp: Повторитель с DataPager - PullRequest
1 голос
/ 31 августа 2010

Я расширяю asp: Repeater для использования DataPager, и теперь мой код работает с SqlDataSource.Чтобы повысить производительность, я хочу использовать ObjectDataSource вместе с ним, но мне нужно использовать QueryStringField из DataPager, в противном случае мне придется дважды щелкнуть номер страницы, чтобы он заработал.Может ли кто-нибудь помочь в этом?это мой код:

namespace WebTest.UserControl
{
    public class PageableRepeater : Repeater, 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);
            }
        }

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

Кстати, я нашел другую реализацию этого на CodeProject , но я не думаю, что он очень хорошо использует IPageableItemContainer.

1 Ответ

0 голосов
/ 07 марта 2015

Я знаю, что это старый, но недавно я искал решение для использования Repeater с элементом управления DataPager.

Большинство исследований приводят меня к этой статье CodeProject , но мне кажется, что это что-то вроде хака. Я немного поработал над этой проблемой и отложил ее на некоторое время, пока крутил на ней свои колеса, пока не увидел ваш вопрос и пример кода. Я смог взять ваш код и применить его к моему, чтобы получить рабочее решение (по крайней мере, оно работает для меня). С помощью элемента управления DataPagerRepeater, приведенного ниже, я могу удалить DataPagerRepeater, DataPager и DataSource (ObjectDataSource и т. Д.) На странице. Задайте DataPagerRepeaters DataSource или DataSourceID, чтобы он указывал на источник данных, затем установите для DataPager PagedControlID значение DataPagerRepeater. Кажется, отлично работает.

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

namespace My.Web.UI.WebControls
{
    /// <summary>
    /// Extends the Repeater to be compatable with a DataPager
    /// </summary>
    /// <remarks>
    /// To page through data in a control that implements the IPageableItemContainer interface, DataPager control can be used. 
    /// Repeater does not support paging and does not implement IPageableItemContainer interface. ListView is the only control that works with DataPager. 
    /// 
    /// The DataPager control supports built-in paging user interface (UI). NumericPagerField object enables users to select a page of data by page number.
    /// NextPreviousPagerField object enables users to move through pages of data one page at a time, or to jump to the first or last page of data. 
    /// The size of the pages of data is set by using the PageSize property of the DataPager control. One or more pager field objects can be used in 
    /// a single DataPager control. Custom paging UI can be created by using the TemplatePagerField object. In the TemplatePagerField template, 
    /// the DataPager control is referenced by using the Container property which provides access to the properties of the DataPager control. 
    /// These properties include the starting row index, the page size, and the total number of rows currently bound to the control. 
    /// </remarks>
    [ToolboxData("<my:DataPagerRepeater runat=server></my:DataPagerRepeater>")]
    [Themeable(true)]
    public class DataPagerRepeater : Repeater, IPageableItemContainer
    {
        /// <summary>Gets the maximum number of items to display on a single page of the <see cref="T:InteriorHealth.Web.UI.WebControls.DataPagerRepeater" /> control.
        /// </summary>
        /// <returns>The maximum number of items to display on a single page of the <see cref="T:InteriorHealth.Web.UI.WebControls.DataPagerRepeater" /> control. 
        /// </returns>
        public int MaximumRows
        {
            get;
            //{
            //    return ViewState["maxrows"] != null ? (int)ViewState["maxrows"] : -1;
            //}
            private set;
            //{
            //    ViewState["maxrows"] = value;
            //}
        }

        /// <summary>Gets the index of the first record that is displayed on a page of data in the <see cref="T:InteriorHealth.Web.UI.WebControls.DataPagerRepeater" /> control.
        /// </summary>
        /// <returns>The index of the first record that is displayed on a page of data in the <see cref="T:InteriorHealth.Web.UI.WebControls.DataPagerRepeater" /> control.
        /// </returns>
        public int StartRowIndex
        {
            get;
            //{
            //    return ViewState["startrowindex"] != null ? (int)ViewState["startrowindex"] : -1;
            //}
            private set;
            //{
            //    ViewState["startrowindex"] = value;
            //}
        }

        /// <summary>
        /// Total number of rows that are avialable, regardless of what is currently being displayed
        /// </summary>
        private int TotalRowsAvailable
        {
            get;
            //{
            //    return ViewState["totalrows"] != null ? (int)ViewState["totalrows"] : -1;
            //}
            set;
            //{
            //    ViewState["totalrows"] = value;
            //}
        }

        private static readonly object EventPagePropertiesChanged = new object();
        /// <summary>Occurs when the page properties change, after the <see cref="T:InteriorHealth.Web.UI.WebControls.DataPagerRepeater" /> control sets the new values.
        /// </summary>
        public event EventHandler PagePropertiesChanged
        {
            add
            {
                base.Events.AddHandler(DataPagerRepeater.EventPagePropertiesChanged, value);
            }
            remove
            {
                base.Events.RemoveHandler(DataPagerRepeater.EventPagePropertiesChanged, value);
            }
        }

        private static readonly object EventPagePropertiesChanging = new object();
        /// <summary>Occurs when the page properties change, but before the <see cref="T:InteriorHealth.Web.UI.WebControls.DataPagerRepeater" /> control sets the new values.
        /// </summary>
        public event EventHandler<PagePropertiesChangingEventArgs> PagePropertiesChanging
        {
            add
            {
                base.Events.AddHandler(DataPagerRepeater.EventPagePropertiesChanging, value);
            }
            remove
            {
                base.Events.RemoveHandler(DataPagerRepeater.EventPagePropertiesChanging, value);
            }
        }

        private static readonly object EventTotalRowCountAvailable = new object();
        /// <summary>For a description of this member, see <see cref="E:System.Web.UI.WebControls.IPageableItemContainer.TotalRowCountAvailable" />.
        /// </summary>
        public event EventHandler<PageEventArgs> TotalRowCountAvailable
        {
            add
            {
                base.Events.AddHandler(DataPagerRepeater.EventTotalRowCountAvailable, value);
            }
            remove
            {
                base.Events.RemoveHandler(DataPagerRepeater.EventTotalRowCountAvailable, value);
            }
        }

        /// <summary>
        /// Register the control as one who's control state needs to be persisted
        /// </summary>
        /// <param name="e"></param>
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            Page.RegisterRequiresControlState(this);
        }

        /// <summary>
        /// Initialize the start row index, maximum rows, and total rows available values.  Load the total rows available from viewstate.
        /// </summary>
        /// <param name="savedState"></param>
        protected override void LoadControlState(object savedState)
        {
            this.StartRowIndex = 0;
            this.MaximumRows = -1;
            this.TotalRowsAvailable = -1;
            object[] state = savedState as object[];

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

                if (state[1] != null)
                {
                    this.TotalRowsAvailable = (int)state[1];
                }

            }
            else
            {
                base.LoadControlState(null);
            }

            if (!IsViewStateEnabled)
            {
                OnTotalRowCountAvailable(new PageEventArgs(this.StartRowIndex, this.MaximumRows, this.TotalRowsAvailable));
            }
        }

        /// <summary>
        /// Save the total rows available value to viewstate
        /// </summary>
        /// <returns></returns>
        protected override object SaveControlState()
        {
            object baseState = base.SaveControlState();
            if (baseState != null || this.TotalRowsAvailable != -1)
            {
                object[] state = new object[2];
                state[0] = baseState;
                state[1] = this.TotalRowsAvailable;
                return state;
            }
            return true;
        }


        /// <summary>Sets the properties of a page of data in the <see cref="T:InteriorHealth.Web.UI.WebControls.DataPagerRepeater" /> control.
        /// </summary>
        /// <param name="startRowIndex">The index of the first record on the page.</param>
        /// <param name="maximumRows">The maximum number of items on a single page.</param>
        /// <param name="databind">true to rebind the control after the properties are set; otherwise, false.</param>
        /// <exception cref="T:System.ArgumentOutOfRangeException">
        ///   <paramref name="maximumRows" /> is less than 1.-or-<paramref name="startRowIndex" /> is less than 0.
        ///   </exception>
        public void SetPageProperties(int startRowIndex, int maximumRows, bool databind)
        {
            if (maximumRows < 1)
            {
                throw new ArgumentOutOfRangeException("maximumRows");
            }
            if (startRowIndex < 0)
            {
                throw new ArgumentOutOfRangeException("startRowIndex");
            }
            if (this.StartRowIndex != startRowIndex || this.StartRowIndex != maximumRows)
            {
                PagePropertiesChangingEventArgs pagePropertiesChangingEventArgs = new PagePropertiesChangingEventArgs(startRowIndex, maximumRows);
                if (databind)
                {
                    this.OnPagePropertiesChanging(pagePropertiesChangingEventArgs);
                }

                this.StartRowIndex = pagePropertiesChangingEventArgs.StartRowIndex;
                this.MaximumRows = pagePropertiesChangingEventArgs.MaximumRows;

                if (databind)
                {
                    this.OnPagePropertiesChanged(EventArgs.Empty);
                }
            }
            if (databind)
            {
                this.RequiresDataBinding = true;
            }

            //this.OnTotalRowCountAvailable(new PageEventArgs(this.StartRowIndex, this.MaximumRows, this.TotalRowsAvailable));
        }


        /// <summary>
        /// Creates a control hierarchy, with or without the specified data source.
        /// </summary>
        /// <param name="useDataSource">
        /// Indicates whether to use the specified data source. 
        /// </param>
        protected override void CreateControlHierarchy(bool useDataSource)
        {
            base.CreateControlHierarchy(useDataSource);
            OnTotalRowCountAvailable(new PageEventArgs(this.StartRowIndex, this.MaximumRows, this.TotalRowsAvailable));
        }

        /// <summary>Returns an <see cref="T:System.Collections.IEnumerable" /> interface from the data source.</summary>
        /// <returns>An object implementing <see cref="T:System.Collections.IEnumerable" /> that represents the data from the data source.</returns>
        protected override System.Collections.IEnumerable GetData()
        {
            System.Collections.IEnumerable data = base.GetData();
            this.TotalRowsAvailable = this.SelectArguments.TotalRowCount;

            this.OnTotalRowCountAvailable(new PageEventArgs(this.StartRowIndex, this.MaximumRows, this.TotalRowsAvailable));
            return data;
        }

        /// <summary>Raises the <see cref="E:InteriorHealth.Web.UI.WebControls.DataPagerRepeater.PagePropertiesChanging" /> event.
        /// </summary>
        /// <param name="e">The event data.</param>
        protected virtual void OnPagePropertiesChanging(PagePropertiesChangingEventArgs e)
        {
            EventHandler<PagePropertiesChangingEventArgs> eventHandler = (EventHandler<PagePropertiesChangingEventArgs>)base.Events[DataPagerRepeater.EventPagePropertiesChanging];
            if (eventHandler != null)
            {
                eventHandler(this, e);
            }
        }

        /// <summary>Raises the <see cref="E:InteriorHealth.Web.UI.WebControls.DataPagerRepeater.SelectedIndexChanged" /> event.</summary>
        /// <param name="e">The event data.</param>
        protected virtual void OnPagePropertiesChanged(EventArgs e)
        {
            EventHandler eventHandler = (EventHandler)base.Events[DataPagerRepeater.EventPagePropertiesChanged];
            if (eventHandler != null)
            {
                eventHandler(this, e);
            }
        } 

        /// <summary>Raises the <see cref="E:InteriorHealth.Web.UI.WebControls.DataPagerRepeater.PagePropertiesChanging" /> event.</summary>
        /// <param name="e">The event data.</param>
        protected virtual void OnTotalRowCountAvailable(PageEventArgs e)
        {
            EventHandler<PageEventArgs> eventHandler = (EventHandler<PageEventArgs>)base.Events[DataPagerRepeater.EventTotalRowCountAvailable];
            if (eventHandler != null)
            {
                eventHandler(this, e);
            }
        }


        /// <summary>
        /// Override the selection of rows that we need
        /// </summary>
        /// <returns></returns>
        protected override DataSourceSelectArguments CreateDataSourceSelectArguments()
        {
            DataSourceSelectArguments arg = base.CreateDataSourceSelectArguments();
            arg.StartRowIndex = this.StartRowIndex;
            arg.MaximumRows = this.MaximumRows;

            return arg;
        }
    }
}
...