1. 程式人生 > >WinForm下編寫分頁控制元件,實現DataGridView的分頁效果

WinForm下編寫分頁控制元件,實現DataGridView的分頁效果



    前幾天做C/S專案的時候用到了分頁查詢,所以就想去網上找一些封裝好的分頁控制元件,類似BS專案中的那種。但是找了好幾個都不是特別的好,沒有自己想要的。而且WinForm 裡面的DataGridView也不像WebForm裡面的GridView那樣有自帶的分頁功能。沒辦法還是自己動手封裝一個吧,以後複用也方便。

從網上找了幾個demo做了一下,實現挺簡單的。

用到的方法就是編寫一個使用者控制元件,下面說明如何實現:

一,先畫介面

新建一個使用者控制元件,然後拖拽幾個標籤,文字框和按鈕,排列好。如下圖所示:

二,編寫程式碼

    public partial class PagerControl : UserControl
    {
        #region 建構函式

        public PagerControl()
        {
            InitializeComponent();
        }

        #endregion

        #region 分頁欄位和屬性

        private int pageIndex = 1;
        /// <summary>
        /// 當前頁數
        /// </summary>
        public virtual int PageIndex
        {
            get { return pageIndex; }
            set { pageIndex = value; }
        }

        private int pageSize = 100;
        /// <summary>
        /// 每頁記錄數
        /// </summary>
        public virtual int PageSize
        {
            get { return pageSize; }
            set { pageSize = value; }
        }

        private int recordCount = 0;
        /// <summary>
        /// 總記錄數
        /// </summary>
        public virtual int RecordCount
        {
            get { return recordCount; }
            set { recordCount = value; }
        }

        private int pageCount = 0;
        /// <summary>
        /// 總頁數
        /// </summary>
        public int PageCount
        {
            get
            {
                if (pageSize != 0)
                {
                    pageCount = GetPageCount();
                }
                return pageCount;
            }
        }

        #endregion

        #region 頁碼變化時觸發事件

        public event EventHandler OnPageChanged;

        #endregion

        #region 分頁及相關事件功能實現

        /// <summary>
        /// 設窗體控制元件全部可用
        /// </summary>
        private void SetFormCtrEnabled()
        {
            linkFirst.Enabled = true;
            linkPrevious.Enabled = true;
            linkNext.Enabled = true;
            linkLast.Enabled = true;
            btnGo.Enabled = true;
        }

        /// <summary>
        /// 計算總頁數
        /// </summary>
        /// <returns></returns>
        private int GetPageCount()
        {
            if (PageSize == 0)
            {
                return 0;
            }
            int pageCount = RecordCount / PageSize;
            if (RecordCount % PageSize == 0)
            {
                pageCount = RecordCount / PageSize;
            }
            else
            {
                pageCount = RecordCount / PageSize + 1;
            }
            return pageCount;
        }
        /// <summary>
        /// 用於客戶端呼叫
        /// </summary>
        public void DrawControl(int count)
        {
            recordCount = count;
            DrawControl(false);
        }
        /// <summary>
        /// 根據不同的條件,改變頁面控制元件的呈現狀態
        /// </summary>
        private void DrawControl(bool callEvent)
        {
            
            lblCurrentPage.Text = PageIndex.ToString();
            lblPageCount.Text = PageCount.ToString();
            lblTotalCount.Text = RecordCount.ToString();
            txtPageSize.Text = PageSize.ToString();

            if (callEvent && OnPageChanged != null)
            {
                OnPageChanged(this, null);//當前分頁數字改變時,觸發委託事件
            }
            SetFormCtrEnabled();
            if (PageCount == 1)//有且僅有一頁時
            {
                linkFirst.Enabled = false;
                linkPrevious.Enabled = false;
                linkNext.Enabled = false;
                linkLast.Enabled = false;
                btnGo.Enabled = false;
            }
            else if (PageIndex == 1)//當前頁為第一頁時
            {
                linkFirst.Enabled = false;
                linkPrevious.Enabled = false;
            }
            else if (PageIndex == PageCount)//當前頁為最後一頁時
            {
                linkNext.Enabled = false;
                linkLast.Enabled = false;
            }
        }

        #endregion

        #region 相關控制元件事件

        //首頁按鈕
        private void linkFirst_Click(object sender, EventArgs e)
        {
            PageIndex = 1;
            DrawControl(true);
        }

        //上一頁按鈕
        private void linkPrevious_Click(object sender, EventArgs e)
        {
            PageIndex = Math.Max(1, PageIndex - 1);
            DrawControl(true);
        }

        //下一頁按鈕
        private void linkNext_Click(object sender, EventArgs e)
        {
            PageIndex = Math.Min(PageCount, PageIndex + 1);
            DrawControl(true);
        }

        //尾頁按鈕
        private void linkLast_Click(object sender, EventArgs e)
        {
            PageIndex = PageCount;
            DrawControl(true);
        }

        /// <summary>
        /// 按下enter鍵,執行跳轉頁面功能
        /// </summary>
        private void txtPageNum_KeyPress(object sender, KeyPressEventArgs e)
        {
            btnGo_Click(null, null);
        }

        /// <summary>
        /// 跳轉頁數限制
        /// </summary>
        private void txtPageNum_TextChanged(object sender, EventArgs e)
        {
            int num = 0;
            if (int.TryParse(txtPageNum.Text.Trim(), out num) && num > 0)
            {   //TryParse 函式,將字串轉換成等效的整數,返回bool型,判斷是否轉換成功。
                //輸入除數字以外的字元是轉換不成功的

                if (num > PageCount)   //輸入數量大於最大頁數時,文字框自動顯示最大頁數
                {
                    txtPageNum.Text = PageCount.ToString();
                }
            }
        }

        /// <summary>
        /// 跳轉按鈕
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnGo_Click(object sender, EventArgs e)
        {
            int num = 0;
            if (int.TryParse(txtPageNum.Text.Trim(), out num) && num > 0)
            {
                PageIndex = num;
                DrawControl(true);
            }
        }

        #endregion
        bool isTextChanged = false;
        /// <summary>
        /// 每頁顯示的記錄數改變時
        /// </summary>
        private void txtPageSize_TextChanged(object sender, EventArgs e)
        {
            int num = 0;
            //輸入不符合規範時,預設設定為100
            if (!int.TryParse(txtPageSize.Text.Trim(), out num) || num <= 0)
            {
                num = 100;
                txtPageSize.Text = "100";
            }
            else
            {
                isTextChanged = true;
                
            }
            pageSize = num;
        }
        /// <summary>
        /// 游標離開 每頁設定文字框時,顯示到首頁
        private void txtPageSize_Leave(object sender, EventArgs e)
        {
            if (isTextChanged)
            {
                isTextChanged = false;
                linkFirst_Click(null, null);
            }
        }
    }

三,客戶端呼叫

    public partial class frmPagerDemo : Form
    {
        public frmPagerDemo()
        {
            InitializeComponent();
        }

        private void StartForm_Load(object sender, EventArgs e)
        {
            //建立一個檔案資料庫表。
            MDataTable.CreateSchema("Users.txt", false, new string[] { "選擇", "使用者名稱", "密碼", "性別", "註冊日期" }, SqlDbType.Bit, SqlDbType.NVarChar, SqlDbType.NVarChar, SqlDbType.NVarChar, SqlDbType.NVarChar);

            
            for (int i = 0; i < 200; i++)//插入200條資料。
            {
                using (MAction action = new MAction("Users.txt", "Txt Path={0}"))
                {
                    action.Set("選擇", i % 2 == 0);
                    action.Set("使用者名稱", "Obama_" + i);
                    action.Set("密碼", "123" + i);
                    action.Set("性別", "男");
                    action.Set("註冊日期", DateTime .Now.ToShortDateString());
                    action.Insert(InsertOp.None);
                }
            }

            LoadData();

            //啟用OnPageChanged事件
            pagerControl1.OnPageChanged += new EventHandler(pagerControl1_OnPageChanged);
        }

        /// <summary>
        /// 頁數變化時呼叫繫結資料方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pagerControl1_OnPageChanged(object sender, EventArgs e)
        {
            LoadData();
        }

        /// <summary>
        /// 重新載入資料
        /// </summary>
        private void LoadData()
        {
            int count;
            using (MAction action = new MAction("Users.txt", "Txt Path={0}"))
            {
                action.Select(pagerControl1.PageIndex, pagerControl1.PageSize, string.Empty, out count).Bind(gvUsers);
                pagerControl1.DrawControl(count);
            }
        }
    }


四,顯示效果

至此一個WinForm版的分頁控制元件製作就完成了。

有問題的地方歡迎指出。