winform中DataGridView实现分页功能
转载至http://xuzhihong1987.blog.163.com/blog/static/267315872011315114240140/
以前都是做web开发,最近接触了下WinForm,发现WinForm分页控件好像都没有,网上搜索了一下,发现有很多网友写的分页控件,分页效果应该都能实现吧,只是其风格都不是很符合我想要的。做web的时候,我习惯了Extjs的Grid分页效果,所以也想在WinForm中做个类似的效果,所以咬咬牙,做个山寨版本的吧,虽然自己写费时费力,在项目进度考虑中不是很可取,但是还是特别想山寨一回,做自己喜欢的风格。
按照惯例,还是先看看实现效果图吧(有图有真像,才好继续下文呀)
应用效果:(效果有点难看,因为我是刚装的
xp系统,还是经典主题,如果换成Win7系统或其他主题,效果还是会很不错的)
我们要做的就是上图显示的一个自定义控件,这个效果参考自我做
web开发使用的Extjs之Grid的分页效果(如下图)
Extjs的动画效果我们暂时就不实现了,这里只做个外观看起来想像即可,完全一样就脱离“山寨”概念了,总要比人家差点吧,谁让咱是模仿呢!
言归正传,我们现在就看看具体怎么实现吧:
第一步:先布局
注:我们创建的是用户自定义控件,而不是WinForm窗体
就是先做出个显示效果,这个布局很简单,在这就不多说,重点就是“首页、前一页、后一页、末页”图标,每个图标分两种,一是能点击的高亮效果,一个是灰色不不能点击。以下是套图:(大家如果不喜欢,可以去做成自己喜欢的风格图片)
第二步:编写分页代码
布局好了,那么第二步我们就要代码实现正确显示文字信息,分页事件,每页条数选择事件,公开属性和事件。以下是完整代码:
/// <summary>
/// 声明委托
/// </summary>
/// <param name="e"></param>
public delegate void EventPagingHandler (EventArgs e);
public partial class Paging : UserControl
{
public Paging()
{
InitializeComponent();
}
public event EventPagingHandler EventPaging;
#region 公开属性
private int _pageSize = ;
/// <summary>
/// 每页显示记录数(默认50)
/// </summary>
public int PageSize
{
get
{
return _pageSize;
}
set
{
if (value > )
{
_pageSize = value;
}
else
{
_pageSize = ;
}
this.comboPageSize.Text = _pageSize.ToString();
}
}
private int _currentPage = ;
/// <summary>
/// 当前页
/// </summary>
public int CurrentPage
{
get
{
return _currentPage;
}
set
{
if (value > )
{
_currentPage = value;
}
else
{
_currentPage = ;
} }
}
private int _totalCount = ;
/// <summary>
/// 总记录数
/// </summary>
public int TotalCount
{
get
{
return _totalCount;
}
set
{
if (value >= )
{
_totalCount = value;
}
else
{
_totalCount = ;
}
this.lblTotalCount.Text = this._totalCount.ToString();
CalculatePageCount();
this.lblRecordRegion.Text = GetRecordRegion();
}
} private int _pageCount = ;
/// <summary>
/// 页数
/// </summary>
public int PageCount
{
get
{
return _pageCount;
}
set
{
if (value >= )
{
_pageCount = value;
}
else
{
_pageCount = ;
}
this.lblPageCount.Text = _pageCount + "";
}
}
#endregion /// <summary>
/// 计算页数
/// </summary>
private void CalculatePageCount()
{
if (this.TotalCount > )
{
this.PageCount = Convert.ToInt32 (Math.Ceiling (Convert.ToDouble (this.TotalCount) / Convert.ToDouble (this.PageSize) ) );
}
else
{
this.PageCount = ;
}
} /// <summary>
/// 获取显示记录区间(格式如:1-50)
/// </summary>
/// <returns></returns>
private string GetRecordRegion()
{
if (this.PageCount == ) //只有一页
{
return "1-" + this.TotalCount.ToString();
}
else //有多页
{
if (this.CurrentPage == ) //当前显示为第一页
{
return "1-" + this.PageSize;
}
else if (this.CurrentPage == this.PageCount) //当前显示为最后一页
{
return ( (this.CurrentPage - ) * this.PageSize + ) + "-" + this.TotalCount;
}
else //中间页
{
return ( (this.CurrentPage - ) * this.PageSize + ) + "-" + this.CurrentPage * this.PageSize;
}
}
} /// <summary>
/// 数据绑定
/// </summary>
public void Bind()
{
if (this.EventPaging != null)
{
this.EventPaging (new EventArgs() );
}
if (this.CurrentPage > this.PageCount)
{
this.CurrentPage = this.PageCount;
}
this.txtBoxCurPage.Text = this.CurrentPage + "";
this.lblTotalCount.Text = this.TotalCount + "";
this.lblPageCount.Text = this.PageCount + "";
this.lblRecordRegion.Text = GetRecordRegion();
if (this.CurrentPage == )
{
this.btnFirst.Enabled = false;
this.btnPrev.Enabled = false;
this.btnFirst.Image = global::CHVM.Properties.Resources.page_first_disabled;
this.btnPrev.Image = global::CHVM.Properties.Resources.page_prev_disabled;
}
else
{
this.btnFirst.Enabled = true;
this.btnPrev.Enabled = true;
this.btnFirst.Image = global::CHVM.Properties.Resources.page_first;
this.btnPrev.Image = global::CHVM.Properties.Resources.page_prev;
}
if (this.CurrentPage == this.PageCount)
{
this.btnNext.Enabled = false;
this.btnLast.Enabled = false;
this.btnNext.Image = global::CHVM.Properties.Resources.page_next_disabled;
this.btnLast.Image = global::CHVM.Properties.Resources.page_last_disabled;
}
else
{
this.btnNext.Enabled = true;
this.btnLast.Enabled = true;
this.btnNext.Image = global::CHVM.Properties.Resources.page_next;
this.btnLast.Image = global::CHVM.Properties.Resources.page_last;
}
if (this.TotalCount == )
{
this.btnFirst.Enabled = false;
this.btnPrev.Enabled = false;
this.btnNext.Enabled = false;
this.btnLast.Enabled = false;
this.btnFirst.Image = global::CHVM.Properties.Resources.page_first_disabled;
this.btnPrev.Image = global::CHVM.Properties.Resources.page_prev_disabled;
this.btnNext.Image = global::CHVM.Properties.Resources.page_next_disabled;
this.btnLast.Image = global::CHVM.Properties.Resources.page_last_disabled;
}
} private void btnFirst_Click (object sender, EventArgs e)
{
this.CurrentPage = ;
this.Bind();
} private void btnPrev_Click (object sender, EventArgs e)
{
this.CurrentPage -= ;
this.Bind();
} private void btnNext_Click (object sender, EventArgs e)
{
this.CurrentPage += ;
this.Bind();
} private void btnLast_Click (object sender, EventArgs e)
{
this.CurrentPage = this.PageCount;
this.Bind();
} /// <summary>
/// 改变每页条数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void comboPageSize_SelectedIndexChanged (object sender, EventArgs e)
{
this.PageSize = Convert.ToInt32 (comboPageSize.Text);
this.Bind();
}
} 这里重点提两点:一是图片切换:
this.btnFirst.Image = global::CHVM.Properties.Resources.page_first_disabled;
Image对象是在Properties.Resource.resx中自动生成的,代码如下:
internal static System.Drawing.Bitmap page_first
{
get {
object obj = ResourceManager.GetObject ("page-first", resourceCulture);
return ( (System.Drawing.Bitmap) (obj) );
}
} internal static System.Drawing.Bitmap page_first_disabled
{
get {
object obj = ResourceManager.GetObject ("page_first_disabled", resourceCulture);
return ( (System.Drawing.Bitmap) (obj) );
}
}
二是应用了委托事件:我们在这定义了一个分页事件
public event EventPagingHandler EventPaging;
在数据绑定方法中实现它:
/// <summary>
/// 数据绑定
/// </summary>
public void Bind()
{
if (this.EventPaging != null)
{
this.EventPaging (new EventArgs() );
}
//… 以下省略
}
这里需要大家对C#的委托和事件有一定的了解,不清楚的可以直接使用,或者先去查阅相关参考资料,这里我们就不谈委托机制了。 第三步:应用
值得一提的是,WinForm并不能直接把用户自定控件往Windows窗体中拖拽,而自动生成实例(ASP.NET是可以直接拖拽的)。那么如果我们需要在应用中使用,只能自己修改Desginer.cs代码了。
先声明:
private CHVM.PagingControl.Paging paging1;
然后在InitializeComponent() 方法中实例化:
this.paging1 = new CHVM.PagingControl.Paging();
//
// paging1
//
this.paging1.CurrentPage = ;
this.paging1.Location = new System.Drawing.Point (, );
this.paging1.Name = "paging1";
this.paging1.PageCount = ;
this.paging1.PageSize = ;
this.paging1.Size = new System.Drawing.Size (, );
this.paging1.TabIndex = ;
this.paging1.TotalCount = ;
//在这里注册事件
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/
其他:
1 /// <summary>
2
3 /// gv显示列设置
4
5 /// </summary>
6
7 /// <returns></returns>
8
9 public Dictionary<string, string> GetGvColumnsDict()
10
11 {
12
13 Dictionary<string, string> dict = new Dictionary<string, string>();
14
15 dict.Add("FTYPE", "操作类型");
16
17 dict.Add("FOPTOBJECT", "操作对象");
18
19 dict.Add("FCONTENT", "操作内容");
20
21 dict.Add("FOperator", "操作人员");
22
23 return dict;
24
25 }
26
27
28
29 DataGridViewHelp.DisplayColList是一个静态方法,为一个辅助类:
30
31 /// <summary>
32
33 /// 替换列表
34
35 /// </summary>
36
37 /// <param name="dgv">类表名称</param>
38
39 /// <param name="dic">数据</param>
40
41 /// <param name="isRM">是否显示序列号</param>
42
43 public static void DisplayColList(DataGridView dgv, Dictionary<string, string> dic)//, bool isRM
44
45 {
46
47 _dgv = dgv;
48
49 dgv.RowsDefaultCellStyle.BackColor = Color.FromArgb(255, 255, 255);//第一行
50
51 dgv.AlternatingRowsDefaultCellStyle.BackColor = Color.FromArgb(231, 232, 239);//第二行
52
53 dgv.GridColor = Color.FromArgb(207, 208, 216);//
54
55 dgv.RowTemplate.Height = 25;//列宽
56
57 dgv.AllowUserToAddRows=false;//无空行
58
59 dgv.CellBorderStyle = DataGridViewCellBorderStyle.SingleVertical;
60
61 dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
62
63 dgv.AllowUserToOrderColumns = true;
64
65 dgv.RowPostPaint += new DataGridViewRowPostPaintEventHandler(dgv_RowPostPaint);
66
67 dgv.CellPainting += new DataGridViewCellPaintingEventHandler(dgv_CellPainting);//列头样式
68
69 dgv.CellFormatting += new DataGridViewCellFormattingEventHandler(dgv_CellFormatting);//选中行样式
70
71
72
73 foreach (KeyValuePair<string, string> cl in dic)
74
75 {
76
77 dgv.AutoGenerateColumns = false;
78
79 DataGridViewTextBoxColumn obj = new DataGridViewTextBoxColumn();
80
81 obj.DataPropertyName = cl.Key;
82
83 obj.HeaderText = cl.Value;
84
85 obj.Name = cl.Key;
86
87 obj.Width = 100;
88
89 //obj.DefaultCellStyle.Padding.All = 10;
90
91 obj.Resizable = DataGridViewTriState.True;
92
93 dgv.Columns.AddRange(new DataGridViewColumn[] { obj });
94
95 }
96
97 }
98
99
到此实现就全部完成了,运行效果后就是前面所示的效果!也可以动态修改每页条数。
说在最后,改功能简单是简单,但是涉及到很多知识点,委托、事件、
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控件扩展后的效果。
具体实现过程 :
//窗体构造方法中定义分页所需变量:
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控件上的项目点击事件,通过配置各个Item的Text值进行判断执行
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();
}
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 5.加载数据 6.在bdnInfo的ItemClicked事件中添加代码 |
winform中DataGridView实现分页功能的更多相关文章
- 【接上一篇】winform中dataGridView高度和宽度自适应填充完数据的高度和宽度,即dataGridView根据数据自适应大小
上一篇:winform中dataGridView高度自适应填充完数据的高度 winform中dataGridView高度自适应填充完数据的高度,就是dataGridView自身不产生滚动条,自己的高度 ...
- winform中dataGridView单元格根据值设置新值,彻底解决绑定后数据类型转换的困难
// winform中dataGridView单元格在数据绑定后,数据类型更改困难,只能迂回实现.有时候需要将数字变换为不同的文字描述,就会出现int32到string类型转换的异常,借助CellFo ...
- winform中dataGridView隔行显示不同的背景色,鼠标移动上显示不同颜色,离开后变回原色
winform中dataGridView隔行显示不同的背景色,鼠标移动上显示不同颜色,离开后变回原色 先设置奇数行颜色,这个有个自带的属性AlternatingRowsDefaultCellStyle ...
- winform中dataGridView高度自适应填充完数据的高度
// winform中dataGridView高度自适应填充完数据的高度,就是dataGridView自身不产生滚动条,自己的高度是根据数据的多少而变动. 在load的时候,数据绑定后,加上如下代码: ...
- C# Winform中DataGridView的DataGridViewCheckBoxColumn使用方法
下面介绍Winform中DataGridView的DataGridViewCheckBoxColumn使用方法: DataGridViewCheckBoxColumn CheckBox是否选中 在判断 ...
- sf中标准的分页功能介绍
世上本无事,庸人自扰之.我喜欢一个相对比较安静的环境去学习和工作,希望在一个掉一根针的声音都能够听到的环境中,但是有时候往往相反,一片嘈杂,我改变不了周围的环境,只能改变自己,其实这些都没有什么,也许 ...
- 项目中的一个分页功能pagination
项目中的一个分页功能pagination <script> //总页数 ; ; //分页总数量 $(function () { // $("#pagination"). ...
- WinForm中DataGridView复制选中单元格内容解决方案
WinForm中DataGridView鼠标选中单元格内容复制方案 1.CTR+C快捷键复制 前提:该控件ClipboardCopyMode属性设置值非Disable: 2.鼠标框选,自定义代码实现复 ...
- django中如何实现分页功能
1.在html页面中导入js文件和css文件 <link rel="stylesheet" href="../../../static/css/jquery.pag ...
随机推荐
- hive on spark配置
1.安装java.maven.scala.hadoop.mysql.hive 略 2.编译spark ./make-distribution.sh --name "hadoop2-witho ...
- Django配置相关及其它
配置 模板 TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [ os.pat ...
- Oracle 11g R2创建数据库之DBCA静默方式
通常创建Oracle数据库都是通过DBCA(Database Configuration Assistant)工具完成的,DBCA工具可以通过两种方式完成建库任务,即图形界面方式和静默命令行方式.既然 ...
- cocos creator 背景音乐音量和音效音量百分比设置
把音效的音量大小百分比保存在本地,播放音效的时候,带上音量大小,就像这样 你播放背景音乐时候,保存背景音乐的id,通过改变音量大小来调节背景音乐,就像这样 cc.audioEngine.setVolu ...
- BN多卡同步进行
为什么不进行多卡同步? BatchNorm的实现都是只考虑了single gpu.也就是说BN使用的均值和标准差是单个gpu算的,相当于缩小了mini-batch size.至于为什么这样实现,1)因 ...
- 52.JQ---向上滚动显示,向下滚动隐藏
js: var windowTop = 0;$(window).scroll(function() { var scrolls = $(this).scrollTop(); if(scrolls &l ...
- How do you explain Machine Learning and Data Mining to non Computer Science people?
How do you explain Machine Learning and Data Mining to non Computer Science people? Pararth Shah, ...
- [转载]Oracle Golden Gate - 概念和机制 (ogg)
出处:https://www.cnblogs.com/qiumingcheng/p/5435907.html Golden Gate(简称OGG)提供异构环境下交易数据的实时捕捉.变换.投递. OGG ...
- HTTP请求中POST与GET的区别
本文章已收录于: 一.原理区别 一般我们在浏览器输入一个网址访问网站都是GET请求;再FORM表单中,可以通过设置Method指定提交方式为GET或者POST提交方式,默认为GET提交方式. ...
- 笔记02 linux的一些命令sed
#!/bin/bash # dataformat=`date +%Y-%m-%d-%H-%M` #进行文件件cp并重命名 nginx_home=/opt/modules/nginx-1.12/ cp ...