1. 程式人生 > >Winform 通用分頁控制元件實戰篇(提供原始碼下載)

Winform 通用分頁控制元件實戰篇(提供原始碼下載)

在Web中,以前寫過相關的分頁控制元件的例項教程,如: 

在Winform中,分頁有時候也是必不可少的一項,因此, 新手Mark一下有時候是必要的。

下面開始簡單介紹一下:

既然是分頁控制元件,說明它是個控制元件,因此,繼承控制元件繼承自使用者控制元件如下:

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

        public PagerControl()
        {
            InitializeComponent();
        }

然後就是對介面拉一些控制元件了,如下圖:

 

 各個控制元件的ID就不一個個打了,下面的程式碼看名稱就知道了。

 按下來定義幾個屬性(第幾頁,每頁幾條,記錄總數,這幾個是國際性慣例必須的)

    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;
            }
        }
        /// <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;         }        #endregion

上面順帶多了一個計算頁總數的程式碼。

接著定義一個事件,用於在引發分頁時,方便外部重新獲取資料繫結:

public event EventHandler OnPageChanged; 

再往下就是點選按鈕的分頁和引發的控制元件重繪了:

看“首頁,上一頁,下一頁,尾頁”事件:

        private void lnkFirst_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            PageIndex = 1;
            DrawControl(true);
        }

        private void lnkPrev_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            PageIndex = Math.Max(1, PageIndex - 1);
            DrawControl(true);
        }

        private void lnkNext_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            PageIndex = Math.Min(PageCount, PageIndex + 1);
            DrawControl(true);
        }

        private void lnkLast_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            PageIndex = PageCount;
            DrawControl(true);

        } 

程式碼是在分頁類裡,這裡就不重複再寫上面的寫過的程式碼了。

然後是重繪控制元件的程式碼:

        ///<summary>/// 外部呼叫
        
///</summary>        public void DrawControl(int count)
        {
            recordCount = count;
            DrawControl(false);
        }
        ///<summary>/// 頁面控制元件呈現
        
///</summary>        private void DrawControl(bool callEvent)
        {
            btnGo.Text = JumpText;
            lblCurrentPage.Text = PageIndex.ToString();
            lblPageCount.Text = PageCount.ToString();
            lblTotalCount.Text = RecordCount.ToString();
            txtPageSize.Text = PageSize.ToString();

            if (callEvent && OnPageChanged != null)
            {
                OnPageChanged(thisnull);//當前分頁數字改變時,觸發委託事件            }
            SetFormCtrEnabled();
            if (PageCount == 1)//有且僅有一頁            {
                lnkFirst.Enabled = false;
                lnkPrev.Enabled = false;
                lnkNext.Enabled = false;
                lnkLast.Enabled = false;
                btnGo.Enabled = false;
            }
            else if (PageIndex == 1)//第一頁            {
                lnkFirst.Enabled = false;
                lnkPrev.Enabled = false;
            }
            else if (PageIndex == PageCount)//最後一頁            {
                lnkNext.Enabled = false;
                lnkLast.Enabled = false;
            }
        }
        private void SetFormCtrEnabled()
        {
            lnkFirst.Enabled = true;
            lnkPrev.Enabled = true;
            lnkNext.Enabled = true;
            lnkLast.Enabled = true;
            btnGo.Enabled = true;

        } 

OK,分頁的程式碼基本就完了,為了提升一點小使用者體驗,包括改變分頁大小,或在輸入跳轉頁後按加車也能執行事件,這裡加多一點處理程式碼:

        ///<summary>/// enter鍵功能
        
///</summary>        private void txtPageNum_KeyPress(object sender, KeyPressEventArgs e)
        {
            btnGo_Click(nullnull);
        }

        ///<summary>/// 跳轉頁數限制
        
///</summary>        private void txtPageNum_TextChanged(object sender, EventArgs e)
        {
            int num = 0;
            if (int.TryParse(txtPageNum.Text.Trim(), out num) && num > 0)
            {
                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;
            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;
                lnkFirst_LinkClicked(nullnull);
            }
        }

到這裡,分頁的原始碼就寫完了,各位自己有空也多寫寫,就那麼幾個事件和步驟。

控制元件出來了,接下就是弄個簡單的介面示例意思意思一下,然後提供下原始碼了。

新建winform專案、往裡拖一個DataGridView+剛才的分頁控制元件,如下圖:

 

接下來是winform的測試程式碼,這裡引用CYQ.Data操作文字資料庫進行簡單示例:

private void StartForm_Load(object sender, EventArgs e)
        {
            //建立檔案資料庫表。            MDataTable.CreateSchema("Users.txt"falsenew string[] { "UserName""Password""Enabled" }, SqlDbType.NVarChar, SqlDbType.NVarChar, SqlDbType.Bit);
            for (int i = 0; i < 200; i++)//插入200條資料。            {
                using (MAction action = new MAction("Users.txt""Txt Path={0}"))
                {
                    action.Set("UserName""UserName_" + i);
                    action.Set("Password""Password_" + i);
                    action.Set("Enabled", i%2==0);
                    action.Insert(InsertOp.None);
                }
            }
            pagerControl1.OnPageChanged += new EventHandler(pagerControl1_OnPageChanged);
            LoadData();
        }

        void pagerControl1_OnPageChanged(object sender, EventArgs e)
        {
            LoadData();
        }
        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);
            }
        }

 程式碼很簡單,重點在

pagerControl1.OnPageChanged事件裡呼叫LoadData來繫結資料,重繪分佈控制元件時呼叫 pagerControl1.DrawControl(傳進記錄總數);

 於是資料出來了,效果如下圖: