winform中DataGridView實現分頁功能


WinForm輕松實現自定義分頁 (轉載)

WinForm輕松實現自定義分頁 (轉載)

 

轉載至http://xuzhihong1987.blog.163.com/blog/static/267315872011315114240140/

以前都是做web開發,最近接觸了下WinForm,發現WinForm分頁控件好像都沒有,網上搜索了一下,發現有很多網友寫的分頁控件,分頁效果應該都能實現吧,只是其風格都不是很符合我想要的。做web的時候,我習慣了Extjs的Grid分頁效果,所以也想在WinForm中做個類似的效果,所以咬咬牙,做個山寨版本的吧,雖然自己寫費時費力,在項目進度考慮中不是很可取,但是還是特別想山寨一回,做自己喜歡的風格。

按照慣例,還是先看看實現效果圖吧(有圖有真像,才好繼續下文呀)

應用效果:(效果有點難看,因為我是剛裝的

xp系統,還是經典主題,如果換成Win7系統或其他主題,效果還是會很不錯的)

 

我們要做的就是上圖顯示的一個自定義控件,這個效果參考自我做

web開發使用的Extjs之Grid的分頁效果(如下圖)

 

Extjs的動畫效果我們暫時就不實現了,這里只做個外觀看起來想像即可,完全一樣就脫離“山寨”概念了,總要比人家差點吧,誰讓咱是模仿呢!

言歸正傳,我們現在就看看具體怎么實現吧:

 

第一步:先布局

    注:我們創建的是用戶自定義控件,而不是WinForm窗體

就是先做出個顯示效果,這個布局很簡單,在這就不多說,重點就是“首頁、前一頁、后一頁、末頁”圖標,每個圖標分兩種,一是能點擊的高亮效果,一個是灰色不不能點擊。以下是套圖:(大家如果不喜歡,可以去做成自己喜歡的風格圖片)

第二步:編寫分頁代碼

   布局好了,那么第二步我們就要代碼實現正確顯示文字信息,分頁事件,每頁條數選擇事件,公開屬性和事件。以下是完整代碼: 

  1 /// <summary>
  2 /// 聲明委托
  3 /// </summary>
  4 /// <param name="e"></param>
  5 public delegate void EventPagingHandler (EventArgs e);
  6 public partial class Paging : UserControl
  7 {
  8     public Paging()
  9     {
 10         InitializeComponent();
 11     }
 12     public event EventPagingHandler EventPaging;
 13     #region 公開屬性
 14     private int _pageSize = 50;
 15     /// <summary>
 16     /// 每頁顯示記錄數(默認50)
 17     /// </summary>
 18     public int PageSize
 19     {
 20         get
 21         {
 22             return _pageSize;
 23         }
 24         set
 25         {
 26             if (value > 0)
 27             {
 28                 _pageSize = value;
 29             }
 30             else
 31             {
 32                 _pageSize = 50;
 33             }
 34             this.comboPageSize.Text = _pageSize.ToString();
 35         }
 36     }
 37     private int _currentPage = 1;
 38     /// <summary>
 39     /// 當前頁
 40     /// </summary>
 41     public int CurrentPage
 42     {
 43         get
 44         {
 45             return _currentPage;
 46         }
 47         set
 48         {
 49             if (value > 0)
 50             {
 51                 _currentPage = value;
 52             }
 53             else
 54             {
 55                 _currentPage = 1;
 56             }
 57 
 58         }
 59     }
 60     private int _totalCount = 0;
 61     /// <summary>
 62     /// 總記錄數
 63     /// </summary>
 64     public int TotalCount
 65     {
 66         get
 67         {
 68             return _totalCount;
 69         }
 70         set
 71         {
 72             if (value >= 0)
 73             {
 74                 _totalCount = value;
 75             }
 76             else
 77             {
 78                 _totalCount = 0;
 79             }
 80             this.lblTotalCount.Text = this._totalCount.ToString();
 81             CalculatePageCount();
 82             this.lblRecordRegion.Text = GetRecordRegion();
 83         }
 84     }
 85 
 86     private int _pageCount = 0;
 87     /// <summary>
 88     /// 頁數
 89     /// </summary>
 90     public int PageCount
 91     {
 92         get
 93         {
 94             return _pageCount;
 95         }
 96         set
 97         {
 98             if (value >= 0)
 99             {
100                 _pageCount = value;
101             }
102             else
103             {
104                 _pageCount = 0;
105             }
106             this.lblPageCount.Text = _pageCount + "";
107         }
108     }
109     #endregion
110 
111     /// <summary>
112     /// 計算頁數
113     /// </summary>
114     private void CalculatePageCount()
115     {
116         if (this.TotalCount > 0)
117         {
118             this.PageCount = Convert.ToInt32 (Math.Ceiling (Convert.ToDouble (this.TotalCount) / Convert.ToDouble (this.PageSize) ) );
119         }
120         else
121         {
122             this.PageCount = 0;
123         }
124     }
125 
126     /// <summary>
127     /// 獲取顯示記錄區間(格式如:1-50)
128     /// </summary>
129     /// <returns></returns>
130     private string GetRecordRegion()
131     {
132         if (this.PageCount == 1) //只有一頁
133         {
134             return "1-" + this.TotalCount.ToString();
135         }
136         else  //有多頁
137         {
138             if (this.CurrentPage == 1) //當前顯示為第一頁
139             {
140                 return "1-" + this.PageSize;
141             }
142             else if (this.CurrentPage == this.PageCount) //當前顯示為最后一頁
143             {
144                 return ( (this.CurrentPage - 1) * this.PageSize + 1) + "-" + this.TotalCount;
145             }
146             else //中間頁
147             {
148                 return ( (this.CurrentPage - 1) * this.PageSize + 1)   + "-" + this.CurrentPage  * this.PageSize;
149             }
150         }
151     }
152 
153     /// <summary>
154     /// 數據綁定
155     /// </summary>
156     public void Bind()
157     {
158         if (this.EventPaging != null)
159         {
160             this.EventPaging (new EventArgs() );
161         }
162         if (this.CurrentPage > this.PageCount)
163         {
164             this.CurrentPage = this.PageCount;
165         }
166         this.txtBoxCurPage.Text = this.CurrentPage + "";
167         this.lblTotalCount.Text = this.TotalCount + "";
168         this.lblPageCount.Text = this.PageCount + "";
169         this.lblRecordRegion.Text = GetRecordRegion();
170         if (this.CurrentPage == 1)
171         {
172             this.btnFirst.Enabled = false;
173             this.btnPrev.Enabled = false;
174             this.btnFirst.Image = global::CHVM.Properties.Resources.page_first_disabled;
175             this.btnPrev.Image = global::CHVM.Properties.Resources.page_prev_disabled;
176         }
177         else
178         {
179             this.btnFirst.Enabled = true;
180             this.btnPrev.Enabled = true;
181             this.btnFirst.Image = global::CHVM.Properties.Resources.page_first;
182             this.btnPrev.Image = global::CHVM.Properties.Resources.page_prev;
183         }
184         if (this.CurrentPage == this.PageCount)
185         {
186             this.btnNext.Enabled = false;
187             this.btnLast.Enabled = false;
188             this.btnNext.Image = global::CHVM.Properties.Resources.page_next_disabled;
189             this.btnLast.Image = global::CHVM.Properties.Resources.page_last_disabled;
190         }
191         else
192         {
193             this.btnNext.Enabled = true;
194             this.btnLast.Enabled = true;
195             this.btnNext.Image = global::CHVM.Properties.Resources.page_next;
196             this.btnLast.Image = global::CHVM.Properties.Resources.page_last;
197         }
198         if (this.TotalCount == 0)
199         {
200             this.btnFirst.Enabled = false;
201             this.btnPrev.Enabled = false;
202             this.btnNext.Enabled = false;
203             this.btnLast.Enabled = false;
204             this.btnFirst.Image = global::CHVM.Properties.Resources.page_first_disabled;
205             this.btnPrev.Image = global::CHVM.Properties.Resources.page_prev_disabled;
206             this.btnNext.Image = global::CHVM.Properties.Resources.page_next_disabled;
207             this.btnLast.Image = global::CHVM.Properties.Resources.page_last_disabled;
208         }
209     }
210 
211     private void btnFirst_Click (object sender, EventArgs e)
212     {
213         this.CurrentPage = 1;
214         this.Bind();
215     }
216 
217     private void btnPrev_Click (object sender, EventArgs e)
218     {
219         this.CurrentPage -= 1;
220         this.Bind();
221     }
222 
223     private void btnNext_Click (object sender, EventArgs e)
224     {
225         this.CurrentPage += 1;
226         this.Bind();
227     }
228 
229     private void btnLast_Click (object sender, EventArgs e)
230     {
231         this.CurrentPage = this.PageCount;
232         this.Bind();
233     }
234 
235     /// <summary>
236     ///  改變每頁條數
237     /// </summary>
238     /// <param name="sender"></param>
239     /// <param name="e"></param>
240     private void comboPageSize_SelectedIndexChanged (object sender, EventArgs e)
241     {
242         this.PageSize = Convert.ToInt32 (comboPageSize.Text);
243         this.Bind();
244     }
245 }
246 
247 這里重點提兩點:一是圖片切換:
248 this.btnFirst.Image = global::CHVM.Properties.Resources.page_first_disabled;
249 Image對象是在Properties.Resource.resx中自動生成的,代碼如下:
250 internal static System.Drawing.Bitmap page_first
251 {
252     get {
253         object obj = ResourceManager.GetObject ("page-first", resourceCulture);
254         return ( (System.Drawing.Bitmap) (obj) );
255     }
256 }
257 
258 internal static System.Drawing.Bitmap page_first_disabled
259 {
260     get {
261         object obj = ResourceManager.GetObject ("page_first_disabled", resourceCulture);
262         return ( (System.Drawing.Bitmap) (obj) );
263     }
264 }
265 二是應用了委托事件:我們在這定義了一個分頁事件
266 public event EventPagingHandler EventPaging;
267 在數據綁定方法中實現它:
268 /// <summary>
269 /// 數據綁定
270 /// </summary>
271 public void Bind()
272 {
273     if (this.EventPaging != null)
274     {
275         this.EventPaging (new EventArgs() );
276     }
277     //… 以下省略
278 }
279 這里需要大家對C#的委托和事件有一定的了解,不清楚的可以直接使用,或者先去查閱相關參考資料,這里我們就不談委托機制了。
280 
281 第三步:應用
282 值得一提的是,WinForm並不能直接把用戶自定控件往Windows窗體中拖拽,而自動生成實例(ASP.NET是可以直接拖拽的)。那么如果我們需要在應用中使用,只能自己修改Desginer.cs代碼了。
283 先聲明:
284 private CHVM.PagingControl.Paging paging1;
285 然后在InitializeComponent() 方法中實例化:
286 this.paging1 = new CHVM.PagingControl.Paging();
287 //
288 // paging1
289 //
290 this.paging1.CurrentPage = 1;
291 this.paging1.Location = new System.Drawing.Point (3, 347);
292 this.paging1.Name = "paging1";
293 this.paging1.PageCount = 0;
294 this.paging1.PageSize = 50;
295 this.paging1.Size = new System.Drawing.Size (512, 30);
296 this.paging1.TabIndex = 8;
297 this.paging1.TotalCount = 0;
298 //在這里注冊事件
299 this.paging1.EventPaging += new CHVM.PagingControl.EventPagingHandler (this.paging1_EventPaging);

 

 

加完后就能看到效果了,相當於托了一個分頁控件的效果:(如下圖所示)

最后在事件中加入分頁事件需要執行的代碼:

 

復制代碼
  1  /// <summary>  2  3 /// 分頁事件  4  5 /// </summary>  6  7 /// <param name="e"></param>  8  9 private void paging1_EventPaging(EventArgs e)  10  11  {  12  13 GvDataBind(); //DataGridView數據綁定  14  15  }  16  17 /// <summary>  18  19 /// 查詢  20  21 /// </summary>  22  23 /// <param name="sender"></param>  24  25 /// <param name="e"></param>  26  27 private void btnQuery_Click(object sender, EventArgs e)  28  29  {  30  31  paging1_EventPaging(e);  32  33  }  34  35 /// <summary>  36  37 /// gvOperateLogList 數據邦定  38  39 /// </summary>  40  41 private void GvDataBind()  42  43  {  44  45 PagingCondition paging = new PagingCondition()  46  47  {  48  49 startIndex=paging1.CurrentPage,  50  51 pageSize = paging1.PageSize  52  53  };  54  55 MultiCondition condition = new MultiCondition();  56  57 condition.DateSign="FOperateTime";  58  59 condition.BeginDate = dtBegin.Value;  60  61 condition.EndDate = dtEnd.Value;  62  63 if (comboOperator.Text != "")  64  65  {  66  67 condition.Dict.Add("FOperator", comboOperator.Text);  68  69  }  70  71 if (comboType.Text != "")  72  73  {  74  75 condition.Dict.Add("FType", comboType.Text);  76  77  }  78  79 if (comboObject.Text != "")  80  81  {  82  83 condition.Dict.Add("FOptObject", comboObject.Text);  84  85  }  86  87 if (txtBoxContent.Text != "")  88  89  {  90  91 condition.Dict.Add("FContent", txtBoxContent.Text);  92  93  }  94  95 DataTable dt = GetByCondition(paging, condition);  96  97 paging1.TotalCount = Convert.ToInt32(dt.TableName);  98  99 gvOperateLogList.DataSource = dt; 100 101  gvOperateLogList.Columns.Clear(); 102 103 var dict = GetGvColumnsDict(); 104 105  DataGridViewHelp.DisplayColList(gvOperateLogList, dict); 106 107 }
復制代碼

 

注:MultiCondition、PagingCondition是我專門針對分頁綜合查詢定義的兩個類,興趣的話可以去了解一下:

查詢條件就統一定義在MultiCondition中(詳見:http://xuzhihong1987.blog.163.com/blog/static/267315872011294150763 ),

PagingCondition是分頁條件(詳見: http://xuzhihong1987.blog.163.com/blog/static/2673158720112941950801 ),

Extjs+LINQ輕松實現高級綜合查詢:

http://xuzhihong1987.blog.163.com/blog/static/2673158720112943356111/

其他:

 

View Code

 

到此實現就全部完成了,運行效果后就是前面所示的效果!也可以動態修改每頁條數。

說在最后,改功能簡單是簡單,但是涉及到很多知識點,委托、事件、

DataGridView數據動態綁定,綜合查詢,我這里用的是Oracle數據庫,如果用LINQ語法的話查詢數據會比較方便,寫起代碼也會顯得很優雅。

/// <summary>
/// 獲取條件查詢數據
/// </summary>
/// <param name="paging"></param>
/// <param name="conditon"></param>
/// <returns></returns>
private DataTable GetByCondition (PagingCondition paging, MultiCondition conditon)
{
    string strSql = "select * from TOperateLog ";
    string strSqlGetCount = "select count(1) from TOperateLog ";
    string strWhere = " where 1=1 ";
    if (conditon != null)
    {
        if (conditon.DateSign == "FOperateTime"//操作日期
        {
            if (conditon.BeginDate != DateTime.MinValue)
            {
                strWhere += string.Format (" and FOperateTime>='{0}'", conditon.BeginDate.ToString ("yyyy-MM-dd HH:mm:ss") );
            }
            if (conditon.EndDate != DateTime.MaxValue)
            {
                strWhere += string.Format (" and FOperateTime<='{0}'", conditon.EndDate.AddDays (1).ToString ("yyyy-MM-dd HH:mm:ss") );
            }
        }
        var dict = conditon.Dict;
        if (dict != null)
        {
            foreach (var key in dict.Keys)
            {
                if (key.Equals ("FType") ) //操作類型
                {
                    strWhere += string.Format (" and FType='{0}'", dict[key]);
                }
                if (key.Equals ("FOperator") ) //操作人員
                {
                    strWhere += string.Format (" and FOperator='{0}'", dict[key]);
                }
                else if (key.Equals ("FOptObject") )                        //操作對象
                {
                    strWhere += string.Format (" and FOptObject='{0}'", dict[key]);
                }
                else if (key.Equals ("FContent") ) //操作內容
                {
                    strWhere += string.Format (" and FContent like '%{0}%'", dict[key]);
                }
            }
        }
    }
    strWhere += " order by FOperateTime ";
    strSql += strWhere;
    strSqlGetCount += strWhere;
    if (paging != null)
    {
        if (paging.needPaging)
            //   strSql = string.Format ("select * from ( {0} ) where ROWNUM>={1} and ROWNUM<={2}", strSql, paging.startIndex, paging.startIndex + paging.pageSize - 1);
        strSql = string.Format ("select * from (select T.*,RowNum  RN from ({0})T where ROWNUM <={1}) where RN>={2} ", strSql, paging.startIndex + paging.pageSize - 1, paging.startIndex);
    }
}
DataTable dt = DataCon.Query (strSql).Tables[0];
dt.TableName = DataCon.GetSingle (strSqlGetCount) + "";
return dt;
}

==========================================================================

C#開發WinForm分頁控件  

 

閑暇之余,自己動手做了個分頁控件,真是受益良多

 

WinFormPager.dll控件下載地址 WinFormPager源代碼下載地址

 

以下是調用分頁控件WinFormPager方法

 

//第一步:指定返回的記錄數

 

winFormPager1.RecordCount = 返回記錄數;

 

//第二步:在控件的PageChanged事件中執行綁定DataGridView的方法

 

private void winFormPager1_PageChanged()
 {
     dataGridView1.DataSource = GetList(winFormPager1.PageSize,winFormPager1.CurrentPage);//GetList為獲取數據庫記錄方法,不介紹
 }

 

//注:完成以上步驟就可成功調用,其余PageSize屬性等可在屬性瀏覽器中設置

 

以下是分頁控件WinformPager完整代碼:

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using DevComponents.DotNetBar;

 

namespace WinFormPager
{
    public partial class WinFormPager : UserControl
    {
        int currentPage = 1;//當前頁 
        /// <summary>
        /// 當前頁 
        /// </summary>
        [Description("當前頁"), Category("分頁設置")]
        public int CurrentPage
        {
            get { return currentPage; }
            set { currentPage = value; }
        }
        int pageSize = 10;//每頁顯示條數
        /// <summary>
        /// 每頁顯示條數
        /// </summary>
        [Description("每頁顯示條數"), Category("分頁設置")] 
        public int PageSize
        {
            get { return pageSize; }
            set { pageSize = value; }
        }
        int pageTotal = 0;//總共多少頁 
        /// <summary>
        /// 總共多少頁 
        /// </summary>
        [Description("總共多少頁"), Category("分頁設置")] 
        public int PageTotal
        {
            get { return pageTotal; }
            set { pageTotal = value; }
        }
        int currentGroup = 1;//當前組
        /// <summary>
        /// 當前組
        /// </summary>
        [Description("當前組"), Category("分頁設置")] 
        public int CurrentGroup
        {
            get { return currentGroup; }
            set { currentGroup = value; }
        }
        int groupSize = 10;//每組顯示頁數
        /// <summary>
        /// 每組顯示頁數
        /// </summary>
        [Description("每組顯示頁數"), Category("分頁設置")] 
        public int GroupSize
        {
            get { return groupSize; }
            set { groupSize = value; }
        }
        int groupTotal = 0;//總共多少組
        /// <summary>
        /// 總共多少組
        /// </summary>
        [Description("總共多少組"), Category("分頁設置")]  
        public int GroupTotal
        {
            get { return groupTotal; }
            set { groupTotal = value; }
        }
        /// <summary>
        /// 總的記錄數
        /// </summary>
        private int recordCount;//總的記錄數
        [Description("總的記錄數"), Category("分頁設置")] 
        public int RecordCount
        {
            get { return recordCount; }
            set 
            {
                recordCount = value;
                InitData();// 初始化數據
                PageChanged();//當前頁改變事件
            }
        }
        private int buttonWidth = 20;//按鈕寬度
        /// <summary>
        /// 按鈕寬度
        /// </summary>
        [Description("按鈕寬度"), Category("分頁設置")] 
        public int ButtonWidth
        {
            get { return buttonWidth; }
            set { buttonWidth = value; }
        }
        private int buttonHeight = 23;//按鈕高度
        /// <summary>
        /// 按鈕高度
        /// </summary>
        [Description("按鈕高度"), Category("分頁設置")] 
        public int ButtonHeight
        {
            get { return buttonHeight; }
            set { buttonHeight = value; }
        }
        private int buttonDistance = 0;//按鈕間距離
        /// <summary>
        /// 按鈕間距離
        /// </summary>
        [Description("按鈕間距離"), Category("分頁設置")] 
        public int ButtonDistance
        {
            get { return buttonDistance; }
            set { buttonDistance = value; }
        }
        List<Control> listControl = new List<Control>();//分頁的按鈕集合

 

        public delegate void PageChangeDelegate();
        /// <summary>
        /// 當前頁改變時發生的事件
        /// </summary>
        [Description("當前頁改變時發生的事件"), Category("分頁設置")]
        public event PageChangeDelegate PageChanged;
        public WinFormPager()
        {
            InitializeComponent();
            PageChanged = SetBtnPrePageAndBtnNextPage;
            PageChanged();
        }
        /// <summary>
        /// 初始化數據
        /// </summary>
        private void InitData() 
        {
            PageTotal = RecordCount / PageSize;//總共多少頁            
            if (RecordCount % PageSize != 0)
            {
                PageTotal++;
            }
            GroupTotal = PageTotal / GroupSize;//總共多少組
            if (PageTotal % GroupSize != 0)
            {
                GroupTotal++;
            }
            for (int i = 0; i < PageTotal; i++)
            {
                cmbPage.Items.Add((i + 1).ToString());//添加下拉框值
            }
            BuildPageControl();//創建分頁數字按鈕       
        }
        /// <summary>
        /// 創建分頁數字按鈕
        /// </summary>
        private void BuildPageControl()
        {
            int x = 0;//按鈕橫坐標
            int y = 0;//按鈕縱坐標
            int num = 0;//按鈕數
            for (int i = GroupSize * (CurrentGroup - 1); i < GroupSize * CurrentGroup; i++)
            {
                if (i + 1 > PageTotal)
                {
                    break;
                }
                num++;
            }
            int xBtnPreGroup = x + (ButtonWidth + ButtonDistance) * num;//btnPerGroup橫坐標
            //指定上一組 下一組 上一頁 下一頁 坐標 
            btnPreGroup.Location = new Point(xBtnPreGroup, y);
            btnNextGroup.Location = new Point(btnPreGroup.Location.X + btnPreGroup.Width + ButtonDistance, y);
            btnPrePage.Location = new Point(btnNextGroup.Location.X + btnNextGroup.Width + ButtonDistance, y);
            btnNextPage.Location = new Point(btnPrePage.Location.X + btnPrePage.Width + ButtonDistance, y);
            cmbPage.Location = new Point(btnNextPage.Location.X + btnNextPage.Width + ButtonDistance, y+(ButtonHeight-cmbPage.Height)/2);
            btnGo.Location = new Point(cmbPage.Location.X + cmbPage.Width + ButtonDistance, y);
            //設置整個控件的寬度、高度
            this.Width = btnGo.Location.X + btnGo.Width;
            this.Height = ButtonHeight;
            btnPreGroup.Height = ButtonHeight;
            btnNextGroup.Height = ButtonHeight;
            btnPrePage.Height = ButtonHeight;
            btnNextPage.Height = ButtonHeight;
            cmbPage.Height = ButtonHeight;
            btnGo.Height = ButtonHeight;
            //循環遍歷移除控件
            foreach (Control c in listControl)
            {
                this.Controls.Remove(c);
            }
            listControl = new List<Control>();
            ButtonX button = null;
            //循環創建控件
            for (int i = GroupSize * (currentGroup - 1); i < GroupSize * CurrentGroup; i++)
            {
                if (i + 1 > PageTotal)
                {
                    break;
                }
                button = new ButtonX();
                button.Text = (i + 1).ToString();
                button.Width = ButtonWidth;
                button.Height = ButtonHeight;
                button.ColorTable = DevComponents.DotNetBar.eButtonColor.OrangeWithBackground;
                button.Location = new Point(x, y);
                button.Click += new EventHandler(button_Click);
                this.Controls.Add(button);
                button.BringToFront();
                listControl.Add(button);//添加進分頁按鈕的集合
                x += ButtonWidth + ButtonDistance;
            }
            //上一組是否可用
            if (CurrentGroup == 1)
            {
                btnPreGroup.Enabled = false;
            }
            else
            {
                btnPreGroup.Enabled = true;
            }
            //下一組是否可用
            if (CurrentGroup == GroupTotal)
            {
                btnNextGroup.Enabled = false;
            }
            else
            {
                btnNextGroup.Enabled = true;
            }
        }
        /// <summary>
        /// 數字按鈕分頁
        /// </summary>
        private void button_Click(object sender, EventArgs e)
        {
            CurrentPage = int.Parse((sender as ButtonX).Text);
            PageChanged();
        }
        /// <summary>
        /// 設置上一頁、下一頁是否可用以及當前頁按鈕字體顏色
        /// </summary>
        private void SetBtnPrePageAndBtnNextPage() 
        {
            //上一頁是否可用
            if (CurrentPage == 1)
            {
                btnPrePage.Enabled = false;
            }
            else
            {
                btnPrePage.Enabled = true;
            }
            //下一頁是否可用
            if (CurrentPage == PageTotal)
            {
                btnNextPage.Enabled = false;
            }
            else
            {
                btnNextPage.Enabled = true;
            }
            //設置數字分頁按鈕文本顏色
            foreach (Control c in this.Controls)
            {
                //當前頁字體為紅色
                if (c.Text == CurrentPage.ToString() && c is ButtonX)
                {
                    c.ForeColor = Color.Red;
                }
                else
                {
                    c.ForeColor = Color.Blue;
                }
            }
        }
        /// <summary>
        /// 上一組
        /// </summary>
        private void btnPreGroup_Click(object sender, EventArgs e)
        {
            CurrentGroup--;
            BuildPageControl();
            CurrentPage = GroupSize * (CurrentGroup - 1) + 1; ;
            PageChanged();
        }
        /// <summary>
        /// 下一組
        /// </summary>
        private void btnNextGroup_Click(object sender, EventArgs e)
        {
            CurrentGroup++;
            BuildPageControl();
            CurrentPage = GroupSize * (CurrentGroup - 1) + 1; ;
            PageChanged();
        }
        /// <summary>
        /// 上一頁
        /// </summary>
        private void btnPrePage_Click(object sender, EventArgs e)
        {
            //如果是當前組的第一頁,直接上一組
            if (CurrentPage == GroupSize * (CurrentGroup - 1) + 1)
            {
                CurrentGroup--;
                BuildPageControl();
                CurrentPage --; ;
                PageChanged();
                return;
            }
            CurrentPage--;
            PageChanged();
        }
        /// <summary>
        /// 下一頁
        /// </summary>
        private void btnNextPage_Click(object sender, EventArgs e)
        {
            //如果是當前組的最后一頁,直接下一組
            if (CurrentPage == GroupSize * (CurrentGroup - 1) + GroupSize)
            {
                btnNextGroup_Click(null, null);
                return;
            }
            CurrentPage++;
            PageChanged();
        }
        /// <summary>
        /// 轉到第幾頁
        /// </summary>
        private void btnGo_Click(object sender, EventArgs e)
        {
            try
            {
                CurrentPage = int.Parse(cmbPage.Text);
                PageChanged();
            }
            catch
            {
                MessageBox.Show("請輸入數字");
            }
        }
    }
}

===============================================================================

http://liyaguang20111105.blog.163.com/blog/static/19929420220146283255809/ 

在winform的設計中,要實現對DataGridView控件的分頁功能,需要兩個控件:BindingSource、BindingNavigator,根據需求可對BindingNavigator進行自由的擴展,下圖的示例則是根據一般需求對分頁功能的實現。紅色區域是對BindingNavigator控件擴展后的效果。

 
winform中DataGridView實現分頁功能 - 李亞光 - 李亞光 廊坊師范學院九期信息技術提高班
 
具體實現過程 :

//窗體構造方法中定義分頁所需變量:

int pageSize = 0;     //每頁顯示行數

int nMax = 0;         //總記錄數

int pageCount = 0;    //頁數=總記錄數/每頁顯示行數

int pageCurrent = 0;   //當前頁號

int nCurrent = 0;      //當前記錄行

DataTable dtInfo = new DataTable();  //存取查詢數據結果

 

//分頁功能實現

public void InitDataSet()

{

    //判斷每頁顯示記錄數是否為空,在初始話窗體時為真

    if (txtRecordNumOfPage.Text.Trim() == "")

    {

        try

        {

            //pageSize = Convert.ToInt16(ConfigurationManager.AppSettings["PageSize"]);      //設置頁面行數

 

            //讀取配置文件中設置的每頁顯示條數

            string szConfigFileName = Application.ExecutablePath + ".config";

            XmlDocument doc = new XmlDocument();

            doc.Load(szConfigFileName);

            XmlNode root = doc.SelectSingleNode("configuration");

            XmlNode node = root.SelectSingleNode("appSettings/add[@key='PageSize']");

            XmlElement el = node as XmlElement;

            pageSize = Convert.ToUInt16(el.GetAttribute("value"));

        }

        catch

        {

        }

        if (pageSize == 0)

        {

            pageSize = 20;        //如果讀取配置文件失敗,則默認將每頁顯示條數設置為20

        }

        txtRecordNumOfPage.Text = pageSize.ToString();    //界面顯示的“每頁記錄數”賦值

    }

    else

    {

        //讀取界面設置的每頁顯示條數

        pageSize = Convert.ToUInt16(txtRecordNumOfPage.Text.Trim());

    }

        //總記錄數賦值

        nMax = dtInfo.Rows.Count;

        pageCount = (nMax / pageSize);    //采用整除計算頁數

        //判斷整除后是否有余數,有則對頁數進行+1

        if ((nMax % pageSize) > 0) pageCount++;

        pageCurrent = 1;    //當前頁數從1開始

        nCurrent = 0;       //當前記錄數從0開始

        //調用顯示數據方法

        LoadData();

}

 

//顯示數據方法

private void LoadData()

{

    int nStartPos = 0;   //當前頁面開始記錄行

    int nEndPos = 0;     //當前頁面結束記錄行

    //判斷查詢結果是否為空

    if (dtInfo.Rows.Count == 0)

    {

        dgvExperInfo.DataSource = null;

        return;

    }

    else

    {

        DataTable dtTemp = dtInfo.Clone();   //克隆DataTable結構,即將字段名稱進行復制

 

        if (pageCurrent == 1)

        {

            bindingNavigatorMoveFirstPage.Enabled = false;

            bindingNavigatorMovePreviousPage.Enabled = false;

        }

        else

        {

            bindingNavigatorMoveFirstPage.Enabled = true;

            bindingNavigatorMovePreviousPage.Enabled = true;

        }

 

        if (pageCurrent == pageCount)

        {

            nEndPos = nMax;

            bindingNavigatorMoveLastPage.Enabled = false;

            bindingNavigatorMoveNextPage.Enabled = false;

        }

        else

        {

            bindingNavigatorMoveLastPage.Enabled = true;

            bindingNavigatorMoveNextPage.Enabled = true;

            nEndPos = pageSize * pageCurrent;

        }

 

        nStartPos = nCurrent;

 

        lblPageCount.Text = pageCount.ToString();             //界面顯示總頁數

        lblCurrentPage.Text = Convert.ToString(pageCurrent);//當前頁數

        txtCurrentPage.Text = Convert.ToString(pageCurrent);//跳轉到頁數的顯示

 

        //從元數據源復制記錄行

        for (int i = nStartPos; i < nEndPos; i++)

        {

            dtTemp.ImportRow(dtInfo.Rows[i]);

            nCurrent++;

        }

        bdsInfo.DataSource = dtTemp;

        bdnInfo.BindingSource = bdsInfo;

        dgvExperInfo.DataSource = bdsInfo;

        dgvExperInfo.ClearSelection();

    }

}

 

//BindingNavigator控件上的項目點擊事件,通過配置各個ItemText值進行判斷執行

private void bdnInfo_ItemClicked(object sender, ToolStripItemClickedEventArgs e)

{

    if (e.ClickedItem.Text == "上一頁")

    {

        pageCurrent--;

        if (pageCurrent <= 0)

        {

           MessageBox.Show("已經是第一頁,請點擊“下一頁”查看!");

           pageCurrent++;

           return;

        }

        else

        {

           nCurrent = pageSize * (pageCurrent - 1);

        }

        LoadData();

     }

    if (e.ClickedItem.Text == "下一頁")

    {

        pageCurrent++;

        if (pageCurrent > pageCount)

        {

            MessageBox.Show("已經是最后一頁,請點擊“上一頁”查看!");

            pageCurrent--;

            return;

         }

       else

       {

           nCurrent=pageSize*(pageCurrent-1);

       }

       LoadData();

    }

    if (e.ClickedItem.Text == "首頁")

    {

        pageCurrent = 1;

        nCurrent = 0;

        LoadData();

    }

    if (e.ClickedItem.Text == "尾頁")

    {

        pageCurrent = pageCount;

        nCurrent = pageSize * (pageCurrent - 1);

        LoadData();

    }

}

//跳轉頁實現

private void btnPage_Click(object sender, EventArgs e)

{

    if (txtCurrentPage.Text.Trim() != "")

    {

        pageCurrent = Convert.ToInt16(txtCurrentPage.Text.Trim());

        //若輸入頁號大於最大顯示頁號,則跳轉至最大頁

        if (pageCurrent > pageCount)

        {

            pageCurrent = pageCount;

            nCurrent = pageSize * (pageCurrent - 1);

        }

        //若輸入頁號小於1,則跳轉至第一頁

        else if (pageCurrent < 1)

        {

            pageCurrent = 1;

            nCurrent = 0;

            LoadData();

        }

        //跳轉至輸入頁號

        else

        {

            nCurrent = pageSize * (pageCurrent - 1);            //當前行數定位

        }

        //調用加載數據方法

        LoadData();

    }

}

//當前頁輸入字符限制

private void txtCurrentPage_TextChanged(object sender, EventArgs e)

{

    bool IsNum = true;

    foreach (char c in txtCurrentPage.Text.Trim())

    {

        if (!char.IsNumber(c)) { IsNum = false; break; }

    }

    if (IsNum == false)

    {

        txtCurrentPage.Text = pageCurrent.ToString();

    }

}

//當前頁回車事件調用跳轉頁的操作

private void txtCurrentPage_KeyPress(object sender, KeyPressEventArgs e)

{

    if (e.KeyChar == 13)

    {

        btnPage_Click(sender,e);

    }

}

 

//每頁顯示記錄數變更事件

private void txtRecordNumOfPage_TextChanged(object sender, EventArgs e)

{

    bool IsNum = true;

    //輸入字符限制

    foreach (char c in txtRecordNumOfPage.Text.Trim())

    {

        if (!char.IsNumber(c)) { IsNum = false; break; }

    }

    if (IsNum == false)

    {

        txtRecordNumOfPage.Text = pageSize.ToString();

    }

    //判斷輸入的每頁顯示條數是否為空或是否為0,輸入長度是否大於4位等情況

    if (txtRecordNumOfPage.Text.Trim() == "" || Convert.ToUInt32(txtRecordNumOfPage.Text.Trim()) == 0 || txtRecordNumOfPage.Text.Trim().Length > 4)

    {

        txtRecordNumOfPage.Text = pageSize.ToString();

    }

    //規避了特殊情況后直接調用顯示數據方法

    LoadDocInfoToDGV();

}

        至此,winform中對DataGridView控件的分頁功能已經實現,該方法是在網上查了相關資料后參照一些常用的分頁效果進行了一些擴展,也在組長的要求下,完善了一些細節上的工作:由於屏幕分辨率的不同,用戶可自行對每頁顯示條數進行設置,設置結果可以在關閉窗體的事件中保存至配置文件,下次進行默認讀取;對分頁控件中按鈕操作的優化,判斷是否能夠使用的功能,代碼中已經進行了體現;另外由於顯示器分辨率不盡相同,需要在窗體加載時,設置控件顯示的位置,也同樣需要代碼進行控制。
        需要注意的一點是該分頁效果達到的是真分頁的功能,要想實現假分頁的效果還要進行一些改動。可見實現分頁的效果還是要考慮很多方面的,但真正實現后的效果還是很實用的。
 
====================================================================
 C# Code 
 
C# WinForm中DataGirdView簡單分頁功能
1.定義變量
  
int pageSize = 0//每頁顯示行數
int nMax = 0//總記錄數
int pageCount = 0//頁數=總記錄數/每頁顯示行數
int pageCurrent = 0//當前頁號
int nCurrent = 0//當前記錄行
PS (在bdnInfo中添加上一頁, 下一頁, lblPageCountText, txtCurrentPage.Text)
2.在窗體內分別添加BindingNavigator (bdnInfo), BindingSource (bdsInfo), DataGirdView1 (dgvInfo)
3.綁定dgvInfo數據
DataSet ds = new DataSet();
ds = userBLL.GetModel();
DaTaTable dt = new DaTaTable ();
dt = ds.Tables[0];
this.dgvInfo.DataSource = dt;
InitDataSet();

4.初始化dgvInfo
private void InitDataSet()
{
    pageSize = 10//設置頁面行數
    nMax = dt.Rows.Count;
    pageCount = (nMax / pageSize); //計算出總頁數
    if ( (nMax % pageSize) > 0)
    {
        pageCount++;
    }
    pageCurrent = 1//當前頁數從1開始
    nCurrent = 0//當前記錄數從0開始
    LoadData();
}

5.加載數據
private void LoadData()
{
    int nStartPos = 0//當前頁面開始記錄行
    int nEndPos = 0//當前頁面結束記錄行
    System.Data.DataTable dtTemp = dt.Clone(); //克隆DataTable結構框架
    if (dtTemp != null || dtTemp.Rows.Count > 0)
    {
        if (pageCurrent == pageCount)
        {
            nEndPos = nMax;
        }
        else
        {
            nEndPos = pageSize * pageCurrent;
        }
        nStartPos = nCurrent;
        lblPageCount.Text = pageCount.ToString();//在bdnInfo中添加lable記錄總頁數
        txtCurrentPage.Text = Convert.ToString (pageCurrent); //在bdnInfo中添加Textbox記錄當前頁數
        //從元數據源復制記錄行
        for (int i = nStartPos; i < nEndPos; i++)
        {
            if (i < dt.Rows.Count)
            {
                dtTemp.ImportRow (dt.Rows[i]);
                nCurrent++;
            }
        }
        bdsInfo.DataSource = dtTemp;
        bdnInfo.BindingSource = bdsInfo;
        dgvInfo.DataSource = bdsInfo;
    }
    else
    {
        return;
    }
}

6.在bdnInfo的ItemClicked事件中添加代碼
private void bdnInfo_ItemClicked (object sender, ToolStripItemClickedEventArgs e)
{
    if (e.ClickedItem.Text == "上一頁")
    {
        pageCurrent--;
        if (pageCurrent <= 0)
        {
            MessageBox.Show ("已經是第一頁,請點擊“下一頁”查看!");
            return;
        }
        else
        {
            if (pageCurrent > pageSize)
            {
                pageCurrent = Convert.ToInt32 (lblPageCount.Text);
            }
            else if (pageCurrent > Convert.ToInt32 (lblPageCount.Text) )
            {
                pageCurrent = Convert.ToInt32 (lblPageCount.Text);
            }
            nCurrent = pageSize * (pageCurrent - 1);
        }
        LoadData();
    }
    if (e.ClickedItem.Text == "下一頁")
    {
        if (pageCurrent <= 0)
        {
            pageCurrent = 1;
        }
        pageCurrent++;
        if (pageCurrent > pageCount)
        {
            MessageBox.Show ("已經是最后一頁,請點擊“上一頁”查看!");
            return;
        }
        else
        {
            nCurrent = pageSize * (pageCurrent - 1);
            if (nCurrent <= 0)
            {
                return;
            }
        }
        LoadData();
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM