不说废话,直接上代码。此代码是根据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); }
实现效果如文章顶部截图。