Wisej实现自定义Grid分页控件

不说废话,直接上代码。此代码是根据BindingNavigator控件代码修改而来。

第一阶段

本来打算使用内置分页,只需要设定DataSource后,就能自动分页,但是反射时出了些状况,所以以下代码仅作为归档参考。真正使用的代码在第二部分。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data.Entity.Infrastructure;
using System.Drawing;
using System.Globalization;
using System.Linq;using Wisej.Base;
using Wisej.Web;

namespace XXXX
{

    [ToolboxItem(true)]
    public class PageNavigator : FlowLayoutPanel, ISupportInitialize
    {
        private string _countItemFormat = PageNavigator.DefaultCountItemFormat;
        private bool initializing;

        private Button _moveFirstPage;
        private Button _movePreviousItem;
        private Button _moveNextItem;
        private Button _moveLastItem;
        private NumericUpDown _positionPage;
        private int _currPage;
        private int _sourceCount;
        private int _pagesCount;
        private object _dataSource;
        private Label _countPages;

        private Orientation _orientation;
        /// <summary>Required designer variable.</summary>
        private IContainer components;

        [EditorBrowsable(EditorBrowsableState.Never)]
        public PageNavigator()
          : this(true)
        {
        }


        public PageNavigator(object dataSource)
          : this(true)
        {
            this.DataSource = dataSource;
        }

        public PageNavigator(object dataSource,Wisej.Web.DataGridView binGrid)
            : this(true)
        {
            this.DataSource = dataSource;
            this.BindGrid = binGrid;
        }


        [EditorBrowsable(EditorBrowsableState.Never)]
        public PageNavigator(IContainer container)
          : this(true)
        {
            if (container == null)
                throw new ArgumentNullException(nameof(container));
            container.Add((IComponent)this);
        }

        public PageNavigator(bool addStandardItems)
        {
            if (!addStandardItems)
                return;
            if (PageSize <= 0)
            {
                PageSize = 20;
            }
            this.AddStandardItems();
        }


        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler PanelCollapsed
        {
            add
            {
                base.PanelCollapsed += value;
            }
            remove
            {
                base.PanelCollapsed -= value;
            }
        }


        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler PanelExpanded
        {
            add
            {
                base.PanelExpanded += value;
            }
            remove
            {
                base.PanelExpanded -= value;
            }
        }


        [Browsable(true)]
        [EditorBrowsable(EditorBrowsableState.Always)]
        public new event EventHandler TextChanged
        {
            add
            {
                base.TextChanged += value;
            }
            remove
            {
                base.TextChanged -= value;
            }
        }


        protected override void OnTextChanged(EventArgs e)
        {
            base.OnTextChanged(e);
        }


        [SRCategory("CatBehavior")]
        [SRDescription("BindingNavigatorRefreshItemsEventDescr")]
        public event EventHandler RefreshItems
        {
            add
            {
                this.AddHandler((object)"RefreshItems", (Delegate)value);
            }
            remove
            {
                this.RemoveHandler((object)"RefreshItems", (Delegate)value);
            }
        }


        protected virtual void OnRefreshItems(EventArgs e)
        {
            this.RefreshItemsCore();
            EventHandler eventHandler = (EventHandler)this.Events[(object)"RefreshItems"];
            if (eventHandler == null)
                return;
            eventHandler((object)this, e);
        }


        protected override void OnDockChanged(EventArgs e)
        {
            switch (this.Dock)
            {
                case DockStyle.Left:
                case DockStyle.Right:
                    this.Orientation = Orientation.Vertical;
                    break;
                default:
                    this.Orientation = Orientation.Horizontal;
                    break;
            }
            base.OnDockChanged(e);
        }


        [SRCategory("CatAppearance")]
        [SRDescription("BindingNavigatorCountItemFormatPropDescr")]
        public string CountItemFormat
        {
            get
            {
                return this._countItemFormat;
            }
            set
            {
                if (!(this._countItemFormat != value))
                    return;
                this._countItemFormat = value;
                this.RefreshItemsInternal();
            }
        }

        private void ResetCountItemFormat()
        {
            this._countItemFormat = PageNavigator.DefaultCountItemFormat;
        }

        private bool ShouldSerializeCountItemFormat()
        {
            return this._countItemFormat != PageNavigator.DefaultCountItemFormat;
        }

        private static string DefaultCountItemFormat
        {
            get
            {
                return Wisej.Base.SR.GetString("BindingNavigatorCountItemFormat");
            }
        }



        [SRCategory("CatItems")]
        [SRDescription("BindingNavigatorMoveFirstItemPropDescr")]
        [TypeConverter(typeof(ReferenceConverter))]
        public Button MoveFirstItem
        {
            get
            {
                if (this._moveFirstPage != null && this._moveFirstPage.IsDisposed)
                    this._moveFirstPage = (Button)null;
                return this._moveFirstPage;
            }
            set
            {
                this.WireButton(ref this._moveFirstPage, value, new EventHandler(this.OnMoveFirst));
            }
        }


        [SRCategory("CatItems")]
        [SRDescription("BindingNavigatorMovePreviousItemPropDescr")]
        [TypeConverter(typeof(ReferenceConverter))]
        public Button MovePreviousItem
        {
            get
            {
                if (this._movePreviousItem != null && this._movePreviousItem.IsDisposed)
                    this._movePreviousItem = (Button)null;
                return this._movePreviousItem;
            }
            set
            {
                this.WireButton(ref this._movePreviousItem, value, new EventHandler(this.OnMovePrevious));
            }
        }


        [SRCategory("CatItems")]
        [SRDescription("BindingNavigatorMoveNextItemPropDescr")]
        [TypeConverter(typeof(ReferenceConverter))]
        public Button MoveNextItem
        {
            get
            {
                if (this._moveNextItem != null && this._moveNextItem.IsDisposed)
                    this._moveNextItem = (Button)null;
                return this._moveNextItem;
            }
            set
            {
                this.WireButton(ref this._moveNextItem, value, new EventHandler(this.OnMoveNext));
            }
        }


        [SRCategory("CatItems")]
        [SRDescription("BindingNavigatorMoveLastItemPropDescr")]
        [TypeConverter(typeof(ReferenceConverter))]
        public Button MoveLastItem
        {
            get
            {
                if (this._moveLastItem != null && this._moveLastItem.IsDisposed)
                    this._moveLastItem = (Button)null;
                return this._moveLastItem;
            }
            set
            {
                this.WireButton(ref this._moveLastItem, value, new EventHandler(this.OnMoveLast));
            }
        }


        [SRCategory("CatItems")]
        [SRDescription("BindingNavigatorPositionItemPropDescr")]
        [TypeConverter(typeof(ReferenceConverter))]
        public NumericUpDown PositionPage
        {
            get
            {
                if (this._positionPage != null && this._positionPage.IsDisposed)
                    this._positionPage = null;
                return this._positionPage;
            }
            set
            {
                this.WireNumericBox(ref this._positionPage, value, new EventHandler(this.OnNumeric_ValueChanged));
            }
        }

        [SRCategory("CatItems")]
        [SRDescription("BindingNavigatorCountItemPropDescr")]
        [TypeConverter(typeof(ReferenceConverter))]
        public Label CountItem
        {
            get
            {
                if (this._countPages != null && this._countPages.IsDisposed)
                    this._countPages = (Label)null;
                return this._countPages;
            }
            set
            {
                this.WireLabel(ref this._countPages, value);
            }
        }

        [DefaultValue(null)]
        [SRCategory("CatData")]
        [SRDescription("DataSource")]
        [TypeConverter(typeof(ReferenceConverter))]
        public object DataSource
        {
            get => _dataSource;
            set
            {
                if (value!=null && value!=_dataSource)
                {
                    _dataSource = value;
                    _sourceCount = Convert.ToInt32(DynamicExt.CallGenericMethodExt(typeof(System.Linq.Enumerable), "Count", _dataSource));
                    _currPage = 1;
                    _pagesCount = ((_sourceCount / PageSize) + (_sourceCount % PageSize > 0 ? 1 : 0));
                    _countPages.Text = _pagesCount.ToString();
                    TakeSome(_currPage);
                }
            }
        }


        [DefaultValue(null)]
        [SRCategory("CatData")]
        [SRDescription("DataSource")]
        [TypeConverter(typeof(ReferenceConverter))]
        public Wisej.Web.DataGridView BindGrid { get; set; }


        [DefaultValue(null)]
        [SRCategory("CatData")]
        [SRDescription("PageSize")]
        [TypeConverter(typeof(ReferenceConverter))]
        public int PageSize { get; set; }


        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override bool AutoSize
        {
            get
            {
                return false;
            }
            set
            {
                

            }
        }


        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override ComponentToolCollection Tools
        {
            get
            {
                return (ComponentToolCollection)null;
            }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override bool ShowCloseButton
        {
            get
            {
                return false;
            }
            set
            {
            }
        }


        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override bool Collapsed
        {
            get
            {
                return false;
            }
            set
            {
            }
        }


        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override HeaderPosition CollapseSide
        {
            get
            {
                return HeaderPosition.Top;
            }
            set
            {
            }
        }


        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override PanelAutoShowMode AutoShow
        {
            get
            {
                return PanelAutoShowMode.Never;
            }
            set
            {
            }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override HeaderPosition HeaderPosition
        {
            get
            {
                return HeaderPosition.Top;
            }
            set
            {
            }
        }


        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override HorizontalAlignment HeaderAlignment
        {
            get
            {
                return HorizontalAlignment.Left;
            }
            set
            {
            }
        }


        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override bool ShowHeader
        {
            get
            {
                return false;
            }
            set
            {
            }
        }


        [Browsable(false)]
        [Localizable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override AutoSizeMode AutoSizeMode
        {
            get
            {
                return AutoSizeMode.GrowAndShrink;
            }
            set
            {
            }
        }


        [Browsable(true)]
        [Localizable(true)]
        [EditorBrowsable(EditorBrowsableState.Always)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public override string Text
        {
            get
            {
                return base.Text;
            }
            set
            {
                base.Text = value;
            }
        }


        [Browsable(false)]
        [SRCategory("CatAppearance")]
        [SRDescription("BindingNavigatorOrientationDescr")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public Orientation Orientation
        {
            get
            {
                return this._orientation;
            }
            set
            {
                if (this._orientation == value)
                    return;
                this._orientation = value;
                Orientation orientation = value == Orientation.Horizontal ? Orientation.Vertical : Orientation.Horizontal;
                Control.ControlCollection controls = this.Controls;
                for (int index = 0; index < controls.Count; ++index)
                {
                    ControlBase controlBase;
                    try
                    {
                        controlBase = (ControlBase)controls[index];
                    }
                    catch
                    {
                        break;
                    }
                    if (controlBase is Line)
                        ((Line)controlBase).Orientation = orientation;
                }
            }
        }


        protected override void Dispose(bool disposing)
        {
            if (disposing && this.components != null)
                this.components.Dispose();
            base.Dispose(disposing);
        }


        public virtual void AddStandardItems()
        {
            Button button1 = new Button();
            Button button2 = new Button();
            Button button3 = new Button();
            Button button4 = new Button();
            NumericUpDown textBox = new NumericUpDown();
            Label label = new Label();
            Line line1 = new Line();
            Line line2 = new Line();
            this.MoveFirstItem = button1;
            this.MovePreviousItem = button2;
            this.MoveNextItem = button3;
            this.MoveLastItem = button4;
            this.PositionPage = textBox;
            this.CountItem = label;
            this.SuspendLayout();
            button1.ImageSource = "icon-first";
            button1.Location = new Point(0, 0);
            button1.Name = "buttonMoveFirst";
            button1.Size = new Size(37, 28);
            button1.TabIndex = 0;
            button2.ImageSource = "icon-left";
            button2.Location = new Point(37, 0);
            button2.Name = "buttonMovePrevious";
            button2.Size = new Size(37, 28);
            button2.TabIndex = 1;
            button3.ImageSource = "icon-right";
            button3.Location = new Point(191, 0);
            button3.Name = "buttonMoveNext";
            button3.Size = new Size(37, 28);
            button3.TabIndex = 2;
            button4.ImageSource = "icon-last";
            button4.Location = new Point(228, 0);
            button4.Name = "buttonMoveLast";
            button4.Size = new Size(37, 28);
            button4.TabIndex = 3;
            textBox.AutoSize = false;
            textBox.Location = new Point(88, 0);
            textBox.Name = "textBoxPosition";
            textBox.Size = new Size(50, 28);
            textBox.TabIndex = 6;
            label.AutoSize = false;
            label.Location = new Point(138, 0);
            label.Name = "labelCount";
            label.Size = new Size(39, 28);
            label.TabIndex = 7;
            label.Text = "of {0}";
            label.TextAlign = ContentAlignment.MiddleCenter;
            line1.Location = new Point(74, 0);
            line1.Name = "separatorLeft";
            line1.Orientation = Orientation.Vertical;
            line1.Padding = new Padding(0, 5, 0, 5);
            line1.Size = new Size(14, 28);
            line1.TabIndex = 8;
            line2.Location = new Point(177, 0);
            line2.Name = "separatorRight";
            line2.Orientation = Orientation.Vertical;
            line2.Padding = new Padding(0, 5, 0, 5);
            line2.Size = new Size(14, 28);
            line2.TabIndex = 7;
            this.Controls.Add((Control)button1);
            this.Controls.Add((Control)button2);
            this.Controls.Add((Control)line1);
            this.Controls.Add((Control)textBox);
            this.Controls.Add((Control)label);
            this.Controls.Add((Control)line2);
            this.Controls.Add((Control)button3);
            this.Controls.Add((Control)button4);

            this.Name = nameof(PageNavigator);
            this.ResumeLayout(false);
            this.PerformLayout();
        }

        /// <summary>
        /// Disables updates to the controls of during the component's initialization.</summary>
        public void BeginInit()
        {
            this.initializing = true;
        }

        /// <summary>
        /// Enables updates to the controls after the component's initialization has completed.
        /// </summary>
        public void EndInit()
        {
            this.initializing = false;
            this.RefreshItemsInternal();
        }

        private void RefreshItemsInternal()
        {
            if (this.initializing)
                return;
            this.OnRefreshItems(EventArgs.Empty);
        }

        private void CancelNewPosition()
        {
            this.RefreshItemsInternal();
        }


        private void OnBindingSourceStateChanged(object sender, EventArgs e)
        {
            this.RefreshItemsInternal();
        }

        private void OnBindingSourceListChanged(object sender, ListChangedEventArgs e)
        {
            this.RefreshItemsInternal();
        }


        [EditorBrowsable(EditorBrowsableState.Advanced)]
        protected virtual void RefreshItemsCore()
        {
            int num1 = 0;
            int num2 = 0;
            if (this._dataSource != null)
            {
                 num1 = _pagesCount;
                 num2 = _currPage + 1;
            }
            if (!this.DesignMode)
            {
                if (this.MoveFirstItem != null)
                    this._moveFirstPage.Enabled = num2 > 1;
                if (this.MovePreviousItem != null)
                    this._movePreviousItem.Enabled = num2 > 1;
                if (this.MoveNextItem != null)
                    this._moveNextItem.Enabled = num2 < num1;
                if (this.MoveLastItem != null)
                    this._moveLastItem.Enabled = num2 < num1;

                if (this.PositionPage != null)
                    this._positionPage.Enabled = num2 > 0 && num1 > 0;
                if (this.CountItem != null)
                    this._countPages.Enabled = num1 > 0;
            }
            if (this._positionPage != null)
                this._positionPage.Text = num2.ToString();
            if (this._countPages == null)
                return;
            this._countPages.Text = this.DesignMode ? this.CountItemFormat : string.Format(this.CountItemFormat, (object)num1);
        }


        public bool Validate()
        {
            bool allowFocusChange = false;
            return this.ValidateActiveControl(out allowFocusChange, true);
        }


        private void WireButton(ref Button oldButton, Button newButton, EventHandler clickHandler)
        {
            if (oldButton == newButton)
                return;
            if (oldButton != null)
                oldButton.Click -= clickHandler;
            if (newButton != null)
                newButton.Click += clickHandler;
            oldButton = newButton;
            this.RefreshItemsInternal();
        }

        private void WireLabel(ref Label oldLabel, Label newLabel)
        {
            if (oldLabel == newLabel)
                return;
            oldLabel = newLabel;
            this.RefreshItemsInternal();
        }

        private void WireNumericBox(
          ref NumericUpDown oldNumericBox,
          NumericUpDown newNumericBox,
          EventHandler valueChanged)
        {
            if (oldNumericBox == newNumericBox)
                return;
            if (oldNumericBox != null)
            {
                oldNumericBox.ValueChanged += valueChanged;
            }
            if (newNumericBox != null)
            {
                newNumericBox.ValueChanged += valueChanged;
            }
            oldNumericBox = newNumericBox;
            this.RefreshItemsInternal();
        }


        /// <summary>
        /// 原本打算实现内置分页方法,可惜此处反射会在特定情况下失效,只能改为外置订阅事件的方式实现。
        /// </summary>
        /// <param name="positionPage"></param>
        private void TakeSome(int positionPage)
        {
            if (this._dataSource == null)
                return;
            if (BindGrid != null && positionPage<=_pagesCount)
            {
                object obj = DynamicExt.CallGenericMethodExt(typeof(System.Linq.Enumerable), "Skip", _dataSource, (positionPage - 1) * PageSize);
                obj = DynamicExt.CallGenericMethodExt(typeof(System.Linq.Enumerable), "Take", _dataSource,PageSize);
                obj = DynamicExt.CallGenericMethodExt(typeof(System.Linq.Enumerable), "ToList", _dataSource);
                BindGrid.DataSource = obj;
                _currPage = positionPage;
                _positionPage.Text = _currPage.ToString();
            }
            RefreshItemsInternal();
        }

        private void OnMoveFirst(object sender, EventArgs e)
        {
            TakeSome(1);
        }

        private void OnMoveLast(object sender, EventArgs e)
        {
            TakeSome(_pagesCount);
        }

        private void OnMoveNext(object sender, EventArgs e)
        {
            TakeSome(++_currPage);
        }

        private void OnMovePrevious(object sender, EventArgs e)
        {
            TakeSome(--_currPage);
        }

        private void OnNumeric_ValueChanged(object sender, EventArgs e)
        {
            if (sender is NumericUpDown num && num.Value>0)
            {
                if (num.Value>_pagesCount)
                {
                    num.Value = _pagesCount;
                }
                else
                {
                    TakeSome(Convert.ToInt32(num.Value));
                }
            }
        }
    }



    public class PageNaviEventArgs : EventArgs
    {
        public int PageCount { get; set; }
        public int PagePosition { get; set; }
        public int PageSize { get; set; }
    }

}

第二阶段代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data.Entity.Infrastructure;
using System.Drawing;
using System.Globalization;
using System.Linq;
using Wisej.Base;
using Wisej.Web;

namespace XXXX
{

    [ToolboxItem(true)]
    public class PageNavigator : FlowLayoutPanel, ISupportInitialize
    {
        private bool initializing;
        private Button _moveFirstPage;
        private Button _movePreviousItem;
        private Button _moveNextItem;
        private Button _moveLastItem;
        private NumericUpDown _positionPage;
        private int _currPage;
        private int _recordsTotal;
        private int _pagesCount;
        private Label _countPages;

        private Orientation _orientation;
        /// <summary>Required designer variable.</summary>
        private IContainer components;


        [EditorBrowsable(EditorBrowsableState.Never)]
        public PageNavigator()
          : this(true)
        {
        }


        [EditorBrowsable(EditorBrowsableState.Never)]
        public PageNavigator(IContainer container)
          : this(true)
        {
            if (container == null)
                throw new ArgumentNullException(nameof(container));
            container.Add((IComponent)this);
        }

        public PageNavigator(bool addStandardItems)
        {
            if (!addStandardItems)
                return;
            if (PageSize <= 0)
            {
                PageSize = 20;
            }
            AddStandardItems();
        }

        /// <summary>
        /// 分页导航被改变
        /// </summary>
        public event Handlers.PageEventHandler PagePositionChanged;


        protected virtual void OnRefreshItems(EventArgs e)
        {
            this.RefreshItemsCore();
            EventHandler eventHandler = (EventHandler)this.Events[(object)"RefreshItems"];
            eventHandler?.Invoke((object)this, e);
        }


        protected override void OnDockChanged(EventArgs e)
        {
            switch (this.Dock)
            {
                case DockStyle.Left:
                case DockStyle.Right:
                    this.Orientation = Orientation.Vertical;
                    break;
                default:
                    this.Orientation = Orientation.Horizontal;
                    break;
            }
            base.OnDockChanged(e);
        }


        [SRCategory("CatItems")]
        [SRDescription("PageNavigatorMoveFirstItemPropDescr")]
        [TypeConverter(typeof(ReferenceConverter))]
        public Button MoveFirstItem
        {
            get
            {
                if (this._moveFirstPage != null && this._moveFirstPage.IsDisposed)
                    this._moveFirstPage = (Button)null;
                return this._moveFirstPage;
            }
            set
            {
                this.WireButton(ref this._moveFirstPage, value, new EventHandler(this.OnMoveFirst));
            }
        }


        [SRCategory("CatItems")]
        [SRDescription("PageNavigatorMovePreviousItemPropDescr")]
        [TypeConverter(typeof(ReferenceConverter))]
        public Button MovePreviousItem
        {
            get
            {
                if (this._movePreviousItem != null && this._movePreviousItem.IsDisposed)
                    this._movePreviousItem = (Button)null;
                return this._movePreviousItem;
            }
            set
            {
                this.WireButton(ref this._movePreviousItem, value, new EventHandler(this.OnMovePrevious));
            }
        }


        [SRCategory("CatItems")]
        [SRDescription("PageNavigatorMoveNextItemPropDescr")]
        [TypeConverter(typeof(ReferenceConverter))]
        public Button MoveNextItem
        {
            get
            {
                if (this._moveNextItem != null && this._moveNextItem.IsDisposed)
                    this._moveNextItem = (Button)null;
                return this._moveNextItem;
            }
            set
            {
                this.WireButton(ref this._moveNextItem, value, new EventHandler(this.OnMoveNext));
            }
        }


        [SRCategory("CatItems")]
        [SRDescription("PageNavigatorMoveLastItemPropDescr")]
        [TypeConverter(typeof(ReferenceConverter))]
        public Button MoveLastItem
        {
            get
            {
                if (this._moveLastItem != null && this._moveLastItem.IsDisposed)
                    this._moveLastItem = (Button)null;
                return this._moveLastItem;
            }
            set
            {
                this.WireButton(ref this._moveLastItem, value, new EventHandler(this.OnMoveLast));
            }
        }


        [SRCategory("CatItems")]
        [SRDescription("PageNavigatorPositionItemPropDescr")]
        [TypeConverter(typeof(ReferenceConverter))]
        public NumericUpDown PositionPage
        {
            get
            {
                if (this._positionPage != null && this._positionPage.IsDisposed)
                    this._positionPage = null;
                return this._positionPage;
            }
            set
            {
                this.WireNumericBox(ref this._positionPage, value, new EventHandler(this.OnNumeric_ValueChanged));
            }
        }

        [SRCategory("CatItems")]
        [SRDescription("PageNavigatorCountItemPropDescr")]
        [TypeConverter(typeof(ReferenceConverter))]
        public Label CountItem
        {
            get
            {
                if (this._countPages != null && this._countPages.IsDisposed)
                    this._countPages = (Label)null;
                return this._countPages;
            }
            set
            {
                this.WireLabel(ref this._countPages, value);
            }
        }



        [DefaultValue(null)]
        [SRCategory("CatData")]
        [SRDescription("DataSource")]
        [TypeConverter(typeof(ReferenceConverter))]
        public Wisej.Web.DataGridView BindGrid { get; set; }


        [DefaultValue(null)]
        [SRCategory("CatData")]
        [SRDescription("PageSize")]
        public int PageSize { get; set; }


        public virtual void ShowPage(int pageNum)
        {
            _currPage = ((pageNum > _pagesCount && pageNum > 0) ? _pagesCount : pageNum);
            OnPagePositionChanged();
        }

        /// <summary>
        /// 记录总数,仅运行时配置
        /// </summary>
        public virtual int RecordsTotal { get=>_recordsTotal;
            set
            {
                _pagesCount = ((value / PageSize) + (value % PageSize > 0 ? 1 : 0));
                _recordsTotal = value;
                RefreshItemsCore();
            }
        }


        [Browsable(false)]
        [SRCategory("CatAppearance")]
        [SRDescription("PageNavigatorOrientationDescr")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public Orientation Orientation
        {
            get
            {
                return this._orientation;
            }
            set
            {
                if (this._orientation == value)
                    return;
                this._orientation = value;
                Orientation orientation = value == Orientation.Horizontal ? Orientation.Vertical : Orientation.Horizontal;
                Control.ControlCollection controls = this.Controls;
                for (int index = 0; index < controls.Count; ++index)
                {
                    ControlBase controlBase;
                    try
                    {
                        controlBase = (ControlBase)controls[index];
                    }
                    catch
                    {
                        break;
                    }
                    if (controlBase is Line)
                        ((Line)controlBase).Orientation = orientation;
                }
            }
        }


        protected override void Dispose(bool disposing)
        {
            if (disposing && this.components != null)
                this.components.Dispose();
            base.Dispose(disposing);
        }


        public void AddStandardItems()
        {
            Button button1 = new Button();
            Button button2 = new Button();
            Button button3 = new Button();
            Button button4 = new Button();
            NumericUpDown textBox = new NumericUpDown(){Maximum = Decimal.MaxValue};
            Label label = new Label();
            Line line1 = new Line();
            Line line2 = new Line();
            this.MoveFirstItem = button1;
            this.MovePreviousItem = button2;
            this.MoveNextItem = button3;
            this.MoveLastItem = button4;
            this.PositionPage = textBox;
            this.CountItem = label;
            this.SuspendLayout();
            button1.ImageSource = "icon-first";
            button1.Location = new Point(0, 0);
            button1.Name = "buttonMoveFirst";
            button1.Size = new Size(37, 28);
            button1.TabIndex = 0;
            button2.ImageSource = "icon-left";
            button2.Location = new Point(37, 0);
            button2.Name = "buttonMovePrevious";
            button2.Size = new Size(37, 28);
            button2.TabIndex = 1;
            button3.ImageSource = "icon-right";
            button3.Location = new Point(191, 0);
            button3.Name = "buttonMoveNext";
            button3.Size = new Size(37, 28);
            button3.TabIndex = 2;
            button4.ImageSource = "icon-last";
            button4.Location = new Point(228, 0);
            button4.Name = "buttonMoveLast";
            button4.Size = new Size(37, 28);
            button4.TabIndex = 3;
            textBox.AutoSize = false;
            textBox.Location = new Point(88, 0);
            textBox.Name = "textBoxPosition";
            textBox.Size = new Size(100, 28);
            textBox.TabIndex = 6;
            label.AutoSize = false;
            label.Location = new Point(188, 0);
            label.Name = "labelCount";
            label.Size = new Size(50, 28);
            label.TabIndex = 7;
            label.Text = "of {0}";
            label.TextAlign = ContentAlignment.MiddleCenter;
            line1.Location = new Point(74, 0);
            line1.Name = "separatorLeft";
            line1.Orientation = Orientation.Vertical;
            line1.Padding = new Padding(0, 5, 0, 5);
            line1.Size = new Size(14, 28);
            line1.TabIndex = 8;
            line2.Location = new Point(238, 0);
            line2.Name = "separatorRight";
            line2.Orientation = Orientation.Vertical;
            line2.Padding = new Padding(0, 5, 0, 5);
            line2.Size = new Size(14, 28);
            line2.TabIndex = 7;
            this.Controls.Add((Control)button1);
            this.Controls.Add((Control)button2);
            this.Controls.Add((Control)line1);
            this.Controls.Add((Control)textBox);
            this.Controls.Add((Control)label);
            this.Controls.Add((Control)line2);
            this.Controls.Add((Control)button3);
            this.Controls.Add((Control)button4);
            this.Name = nameof(PageNavigator);
            this.ResumeLayout(false);
            this.PerformLayout();
        }

        /// <summary>
        /// Disables updates to the controls of during the component's initialization.</summary>
        public void BeginInit()
        {
            this.initializing = true;
        }

        /// <summary>
        /// Enables updates to the controls after the component's initialization has completed.
        /// </summary>
        public void EndInit()
        {
            this.initializing = false;
            this.RefreshItemsInternal();
        }

        private void RefreshItemsInternal()
        {
            if (this.initializing)
                return;
            this.OnRefreshItems(EventArgs.Empty);
        }


        [EditorBrowsable(EditorBrowsableState.Advanced)]
        protected virtual void RefreshItemsCore()
        {
            int num1 = _pagesCount;
            int num2 = _currPage;
            if (!this.DesignMode)
            {
                if (this.MoveFirstItem != null)
                    this._moveFirstPage.Enabled = num2 > 1;
                if (this.MovePreviousItem != null)
                    this._movePreviousItem.Enabled = num2 > 1;
                if (this.MoveNextItem != null)
                    this._moveNextItem.Enabled = num2 < num1;
                if (this.MoveLastItem != null)
                    this._moveLastItem.Enabled = num2 < num1;
                if (this.PositionPage != null)
                    this._positionPage.Enabled = num1 > 0;
                if (this.CountItem != null)
                    this._countPages.Enabled = num1 > 0;
            }
            if (this._positionPage != null)
                this._positionPage.Text = num2.ToString();
            if (this._countPages == null)
                return;
            this._countPages.Text = $"{_pagesCount}";
        }


        private void WireButton(ref Button oldButton, Button newButton, EventHandler clickHandler)
        {
            if (oldButton == newButton)
                return;
            if (oldButton != null)
                oldButton.Click -= clickHandler;
            if (newButton != null)
                newButton.Click += clickHandler;
            oldButton = newButton;
            this.RefreshItemsInternal();
        }

        private void WireLabel(ref Label oldLabel, Label newLabel)
        {
            if (oldLabel == newLabel)
                return;
            oldLabel = newLabel;
            this.RefreshItemsInternal();
        }

        private void WireNumericBox(
          ref NumericUpDown oldNumericBox,
          NumericUpDown newNumericBox,
          EventHandler valueChanged)
        {
            if (oldNumericBox == newNumericBox)
                return;
            if (oldNumericBox != null)
            {
                oldNumericBox.ValueChanged += valueChanged;
            }
            if (newNumericBox != null)
            {
                newNumericBox.ValueChanged += valueChanged;
            }
            oldNumericBox = newNumericBox;
            this.RefreshItemsInternal();
        }



        private void OnMoveFirst(object sender, EventArgs e)
        {
            _currPage = 1;
            OnPagePositionChanged();
        }

        private void OnMoveLast(object sender, EventArgs e)
        {
            _currPage = _pagesCount;
            OnPagePositionChanged();
        }

        private void OnMoveNext(object sender, EventArgs e)
        {
            _currPage = ++_currPage;
            OnPagePositionChanged();
        }

        private void OnMovePrevious(object sender, EventArgs e)
        {
            _currPage = --_currPage;
            OnPagePositionChanged();
        }

        private void OnNumeric_ValueChanged(object sender, EventArgs e)
        {
            if (sender is NumericUpDown num && num.Value>0)
            {
                if (num.Value>_pagesCount)
                {
                    num.Value = _pagesCount;
                }
                else
                {
                    _currPage = Convert.ToInt32(num.Value);
                    OnPagePositionChanged();
                }
            }
        }

        protected virtual void OnPagePositionChanged()
        {
            PagePositionChanged?.Invoke(this,
                new PageNaviEventArgs()
                    {PageCount = this._pagesCount, PagePosition = _currPage, PageSize = this.PageSize});
            RefreshItemsInternal();
        }
    }

    public class Handlers
    {
        [System.Runtime.InteropServices.ComVisible(true)]
        [Serializable]
        public delegate void PageEventHandler(object sender, PageNaviEventArgs e);

    }

    public class PageNaviEventArgs : EventArgs
    {
        public int PageCount { get; set; }
        public int PagePosition { get; set; }
        public int PageSize { get; set; }
    }

}

调用代码如下:

        private void PageNavigator1_PagePositionChanged(object sender, Controls.PageNaviEventArgs e)
        {
            pageNavigator1.BindGrid.DataSource = SqlDml.Select<ProcInst>(Common.Configs.GetContext()).Skip((e.PagePosition - 1) * e.PageSize).Take(e.PageSize).ToList();
        }

        private void this_Load(object sender, EventArgs e)
        {
            pageNavigator1.PagePositionChanged += PageNavigator1_PagePositionChanged;

            pageNavigator1.RecordsTotal = SqlDml.Select<ProcInst>(Common.Configs.GetContext()).Count();
            pageNavigator1.ShowPage(1);
        }

实现效果如文章顶部截图。

原文地址:https://www.cnblogs.com/honk/p/12672001.html