Winform 通用分頁控制元件實戰篇(提供原始碼下載)
阿新 • • 發佈:2019-01-25
在Web中,以前寫過相關的分頁控制元件的例項教程,如:
{
#region 建構函式
public PagerControl()
{
InitializeComponent();
}
{
#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
{
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> 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> 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);
}
}
{
//建立檔案資料庫表。 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);
}
}
在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
///<summary>/// 當前頁面
///</summary> public virtual int PageIndex
{
get { return pageIndex; }
set { pageIndex = value; }
}
private int pageSize = 100;
///<summary>/// 每頁記錄數
///</summary> public
{
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(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);
}
}
到這裡,分頁的原始碼就寫完了,各位自己有空也多寫寫,就那麼幾個事件和步驟。
控制元件出來了,接下就是弄個簡單的介面示例意思意思一下,然後提供下原始碼了。
新建winform專案、往裡拖一個DataGridView+剛才的分頁控制元件,如下圖:
接下來是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);
}
}
程式碼很簡單,重點在
pagerControl1.OnPageChanged事件裡呼叫LoadData來繫結資料,重繪分佈控制元件時呼叫 pagerControl1.DrawControl(傳進記錄總數);於是資料出來了,效果如下圖: