C# Winform自定义的UI分页控件

发布于:2024-12-21 ⋅ 阅读:(18) ⋅ 点赞:(0)

效果展示:

自定义控件源代码:

using System;
using System.Drawing;
using System.Windows.Forms;
using static NPOI.HSSF.Util.HSSFColor;

namespace TestSystemManager
{
    public class PaginationControl : UserControl
    {
        // 事件:当页码切换时触发
        public event EventHandler<int> PageChanged = null!;

        // 当前页码
        private int _currentPage = 1;
        public int CurrentPage
        {
            get => _currentPage;
            set
            {
                if (value >= 1 && value <= TotalPages)
                {
                    _currentPage = value;
                    Console.WriteLine($"CurrentPage updated to: {_currentPage}"); // 调试输出
                    UpdatePagination();
                }
            }
        }

        // 总页数
        private int _totalPages = 1;
        public int TotalPages
        {
            get => _totalPages;
            set
            {
                _totalPages = value > 0 ? value : 1;
                UpdatePagination();
            }
        }

        // 布局面板
        private FlowLayoutPanel flowLayoutPanel;

        // 每页显示的最大按钮数量
        private int MaxButtons => this.Width / 50; // 按钮宽度约50像素

        // 分页控件初始化
        public PaginationControl()
        {
            this.Height = 60; // 增加高度
            this.AutoSize = true;

            // 初始化 FlowLayoutPanel
            flowLayoutPanel = new FlowLayoutPanel
            {
                Dock = DockStyle.Fill,
                AutoSize = true,
                FlowDirection = FlowDirection.LeftToRight,
                WrapContents = false,
                Padding = new Padding(10)
            };

            this.Controls.Add(flowLayoutPanel);

            // 响应控件大小调整
            this.Resize += (s, e) => UpdatePagination();
        }

        // 更新分页显示
        private void UpdatePagination()
        {
            flowLayoutPanel.Controls.Clear(); // 清除控件

            if (TotalPages <= 1)
                return;

            // 计算需要显示的页码范围
            int maxButtons = MaxButtons; // 最多显示按钮数量
            int startPage = Math.Max(1, CurrentPage - maxButtons / 2);
            int endPage = Math.Min(TotalPages, startPage + maxButtons - 1);

            if (endPage - startPage + 1 < maxButtons)
            {
                startPage = Math.Max(1, endPage - maxButtons + 1);
            }

            // 调试输出页码范围
            Console.WriteLine($"startPage: {startPage}, endPage: {endPage}, CurrentPage: {CurrentPage}");

            // 添加省略号前的页码按钮
            if (startPage > 1)
            {
                flowLayoutPanel.Controls.Add(CreateButton("1", true, () => CurrentPage = 1));
                if (startPage > 2)
                {
                    // 添加“上一页”按钮
                    flowLayoutPanel.Controls.Add(CreateButton("<<", CurrentPage > 1, () => CurrentPage = Math.Max(1, CurrentPage - 1)));
                }
            }

            // 添加可见的页码按钮
            for (int i = startPage; i <= endPage; i++)
            {
                var isCurrent = i == CurrentPage;
                flowLayoutPanel.Controls.Add(CreateButton(i.ToString(), !isCurrent, () => CurrentPage = i));
            }

            // 添加省略号后的页码按钮
            if (endPage < TotalPages)
            {
                if (endPage < TotalPages - 1)
                {
                    // 添加“下一页”按钮
                    flowLayoutPanel.Controls.Add(CreateButton(">>", CurrentPage < TotalPages, () => CurrentPage = Math.Min(TotalPages, CurrentPage + 1)));
                }
                flowLayoutPanel.Controls.Add(CreateButton(TotalPages.ToString(), true, () => CurrentPage = TotalPages));
            }

            flowLayoutPanel.Invalidate(); // 强制刷新
        }

        // 创建按钮
        private Krypton.Toolkit.KryptonButton CreateButton(string text, bool isEnabled, Action onClick)
        {
            var button = new Krypton.Toolkit.KryptonButton
            {
                Text = text,
                Enabled = isEnabled,
                Width = 40, // 设置按钮宽度
                Height = 30, // 设置按钮高度
                Margin = new Padding(5),
                ForeColor = isEnabled ? Color.Black : Color.Gray,
                BackColor = isEnabled ? Color.White : Color.LightGray,
                Tag = text
            };

            button.StateCommon.Back.Color1 = Color.FromArgb(255, 224, 192);
            button.StateCommon.Back.Color2 = Color.FromArgb(128, 255, 128);
            if (isEnabled)
            {
                button.Click += (s, e) =>
                {
                    // 确保事件逻辑只针对当前按钮
                    if (button.Tag.ToString() != ">>" && button.Tag.ToString() != "<<")
                    {
                        int clickedPage = int.Parse(button.Tag.ToString()!);
                        CurrentPage = clickedPage;

                        PageChanged?.Invoke(this, CurrentPage);
                    }
                };
            }

            return button;
        }

        // 创建省略号标签
        private Label CreateEllipsis()
        {
            return new Label
            {
                Text = "...",
                AutoSize = true,
                Margin = new Padding(5),
                TextAlign = ContentAlignment.MiddleCenter,
                ForeColor = Color.Gray
            };
        }
    }
}

UI窗体实现分页控件展示代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TestSystemManager
{
    public partial class DataBaseDataManager_TestData_WinFrm : Form
    {
        private PaginationControl pagination = null!;
        private string testWebApi = string.Empty;

        public DataBaseDataManager_TestData_WinFrm(string testWebApi)
        {
            InitializeComponent();
            this.testWebApi = testWebApi;

            //创建分页控件
            this.pagination = new PaginationControl {
                TotalPages = 93, // 设置总页数
                Dock = DockStyle.Bottom // 自动停靠在底部
            };

            // 绑定 PageChanged 事件
            this.pagination.PageChanged += Pagination_PageChanged!;

            // 添加到窗体
            this.splitContainer2.Panel2.Controls.Add(this.pagination);

            // 响应父容器大小调整
            this.splitContainer2.Panel2.Resize += (s, e) =>
            {
                this.pagination.Width = this.splitContainer2.Panel2.Width;
            };
        }

        #region 处理页码切换事件
        private void Pagination_PageChanged(object sender, int currentPage)
        {
            MessageBox.Show($"您单击了第 {currentPage} 页", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        #endregion
    }
}