在Web中,以前写过相关的分页控件的实例教程,如: 分页控件 实战 Post篇 (包源码的)
在Winform中,分页有时候也是必不可少的一项,因此, 新手Mark一下有时候是必要的。
下面开始简单介绍一下:
既然是分页控件,说明它是个控件,因此,继承控件继承自用户控件如下:
public
partial
class PagerControl : UserControl
{
#region 构造函数
public PagerControl()
{
InitializeComponent();
}
{
#region 构造函数
public PagerControl()
{
InitializeComponent();
}
}
然后就是对界面拉一些控件了,如下图:
![](http://images.cnblogs.com/cnblogs_com/cyq1162/201206/win_pager_1.jpg?x-oss-process=image/resize,w_1400/format,webp)
各个控件的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;
}
}
#endregion
{
#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;
}
}
上面顺带多了一个计算页总数的代码。
接着定义一个事件,用于在引发分页时,方便外部重新获取数据绑定:
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);
{
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( this, null); // 当前分页数字改变时,触发委托事件
}
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;
/// 外部调用
/// </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( this, null); // 当前分页数字改变时,触发委托事件
}
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( 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)
{
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( null, null);
}
}
/// 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)
{
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( null, null);
}
}
到这里,分页的源码就写完了,各位自己有空也多写写,就那么几个事件和步骤。
控件出来了,接下就是弄个简单的界面示例意思意思一下,然后提供下源码了。
新建winform项目、往里拖一个DataGridView+刚才的分页控件,如下图:
![](http://images.cnblogs.com/cnblogs_com/cyq1162/201206/win_pager_2.jpg?x-oss-process=image/resize,w_1400/format,webp)
接下来是winform的测试代码,这里引用CYQ.Data操作文本数据库进行简单示例:
private
void StartForm_Load(
object sender, EventArgs e)
{
// 创建文件数据库表。
MDataTable.CreateSchema( " Users.txt ", false, new 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);
}
}
{
// 创建文件数据库表。
MDataTable.CreateSchema( " Users.txt ", false, new 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来绑定数据,重绘分布控件时调用
于是数据出来了,效果如下图:
![](http://images.cnblogs.com/cnblogs_com/cyq1162/201206/win_pager_3.jpg?x-oss-process=image/resize,w_1400/format,webp)
源码打包下载:
winform 分页控件源码
本文转自cyq1162 51CTO博客,原文链接:http://blog.51cto.com/cyq1162/896084
,如需转载请自行联系原作者