asp.net中使用自訂控制項的方式實現一個分頁控制項的代碼

來源:互聯網
上載者:User

一、概述

在web開發中,常常需要顯示一些資料,而為了方便排版及瀏覽,我們只需要顯示所有記錄中的一部分。一般情況下,我們採用分頁來實現這個需求。實現分頁的方法多種多樣,在本文中,我們採用了一個分頁空間來記錄記錄總數、當前頁、總頁數及頁面大小等。為了有一個直觀上的印象,先展示該控制項運行後的效果,效果如所示:

二、實現方案

為了實現該,在asp.net中,可以使用Custom Controls and User Controls兩種方式,User Controls的實現方式及其簡單,而且使用起來和平時使用Controls的方式差別極大,所以我們採用Custom Controls實現。
參考資料:Professional ASP.NET 2.0 Server Control and Component Development

三、分頁控制項的實現

1)、建立一個ASP.NET Server Control項目,
2)、在該項目中添加一個ASP.NET Server Control的Item,並設定其Name為PageOn,
3)、修改該類繼承於CompositeControl類,並修改其Attribute為如下所示:

複製代碼 代碼如下:[DefaultProperty("PageSize")]
[ToolboxData("<{0}:PageOn runat=server Width=100%></{0}:PageOn>")]
public class PageOn : CompositeControl

註:自訂控制項必須繼承自Control或者其子類。
4)、 定義需要被組合的控制項 複製代碼 代碼如下:Label lblMessage;
LinkButton btnFirst;
LinkButton btnPrev;
LinkButton btnNext;
LinkButton btnLast;
TextBox txtGoPage;
Button btnGo;

5)、定義分頁控制項需要用到的Proptery
分頁控制項主要包括頁面大小、當前頁、總記錄數及總頁數等屬性,並需要儲存在ViewState中,詳細代碼如下所示: 複製代碼 代碼如下:public int RowCount
{
get
{
if (ViewState["m_rowCount"] == null || int.Parse(ViewState["m_rowCount"].ToString()) < 0)
{
ViewState["m_rowCount"] = 0;
}
return int.Parse(ViewState["m_rowCount"].ToString());
}
set
{
if (value < 0)
{
ViewState["m_rowCount"] = 0;
}
else
{
ViewState["m_rowCount"] = value;
}
this.RecreateChildControls();
}
}
public int CurPage
{
get
{
if (ViewState["m_curPage"] ==null || int.Parse(ViewState["m_curPage"].ToString()) < 1)
{
ViewState["m_curPage"] = 1;
}
return int.Parse(ViewState["m_curPage"].ToString());
}
set
{
if (value < 1)
{
ViewState["m_curPage"] = 1;
}
else if (value > PageCount)
{
ViewState["m_curPage"] = PageCount;
}
else
{
ViewState["m_curPage"] = value;
}
}
}
public int PageCount
{
get
{
return RowCount / PageSize + 1;
}
}
public int PageSize
{
get
{
if (ViewState["m_pageSize"] ==null || int.Parse(ViewState["m_pageSize"].ToString()) < 1)
{
ViewState["m_pageSize"] = 15;
}
return int.Parse(ViewState["m_pageSize"].ToString());
}
set
{
if (value > 0)
{
ViewState["m_pageSize"] = value;
this.RecreateChildControls();
}
}
}

6)、產生自訂控制項的子空間
產生自訂空間的子空間需要override基類Control中的CreateChildControls()方法,詳細代碼如下所示: 複製代碼 代碼如下:protected override void CreateChildControls()
{
Controls.Clear();
lblMessage = new Label();
lblMessage.Text = "當前第" + CurPage + "頁 共" + PageCount + "頁 共" + RowCount + "條記錄";
lblMessage.ID = "lblMessage";
Controls.Add(lblMessage);
btnFirst = new LinkButton();
btnFirst.Text = "首頁";
btnFirst.CommandName = "first";
btnFirst.ID = "btnFirst";
if (CurPage <= 1)
{
btnFirst.Enabled = false;
}
Controls.Add(btnFirst);
btnPrev = new LinkButton();
btnPrev.Text = "上一頁";
btnPrev.CommandName = "prev";
btnPrev.ID = "btnPrev";
if (CurPage <= 1)
{
btnPrev.Enabled = false;
}
Controls.Add(btnPrev);
btnNext = new LinkButton();
btnNext.Text = "下一頁";
btnNext.CommandName = "next";
btnNext.ID = "btnNext";
if (CurPage >= PageCount)
{
btnNext.Enabled = false;
}
Controls.Add(btnNext);
btnLast = new LinkButton();
btnLast.Text = "末頁";
btnLast.CommandName = "last";
btnLast.ID = "btnLast";
if (CurPage >= PageCount)
{
btnLast.Enabled = false;
}
Controls.Add(btnLast);
txtGoPage = new TextBox();
txtGoPage.TabIndex = 1;
txtGoPage.ID = "txtGoPage";
txtGoPage.Attributes.Add("onkeyup", @"this.value=this.value.replace(/\D/g,'')");
txtGoPage.Attributes.Add("onafterpaste", @"this.value=this.value.replace(/\D/g,'')");
Controls.Add(txtGoPage);
btnGo = new Button();
btnGo.TabIndex = 2;
btnGo.CommandName = "go";
btnGo.Text = "GO";
btnGo.ID="btnGO";
Controls.Add(btnGo);
Debug.WriteLine("ffffffffffffffffffffffffffffffffffffffffffffffffff");
base.CreateChildControls();
}

7)、定義自訂控制項的布局
第6步完成後,所有定義的控制項都會順序顯示到頁面上了,但是這樣的效果不友好,如果對於多行的空間更是如此,所有我們需要定義控制項的布局,自訂控制項的布局需要重寫RenderContents()方法及TagKey屬性,此樣本中的代碼如下所示: 複製代碼 代碼如下:protected override void RenderContents(HtmlTextWriter output)
{
output.RenderBeginTag(HtmlTextWriterTag.Tr);
output.AddStyleAttribute("text-align", "left");
output.RenderBeginTag(HtmlTextWriterTag.Td);
output.Write(" ");
lblMessage.RenderControl(output);
output.RenderEndTag();
output.AddStyleAttribute("text-align", "right");
output.RenderBeginTag(HtmlTextWriterTag.Td);
btnFirst.RenderControl(output);
output.Write(" ");
btnPrev.RenderControl(output);
output.Write(" ");
btnNext.RenderControl(output);
output.Write(" ");
btnLast.RenderControl(output);
output.Write("到");
output.AddStyleAttribute(HtmlTextWriterStyle.Width, "30px");
txtGoPage.RenderControl(output);
output.Write("頁");
btnGo.RenderControl(output);
output.Write(" ");
output.RenderEndTag();
output.RenderEndTag();
}
protected override HtmlTextWriterTag TagKey
{
get
{
return HtmlTextWriterTag.Table;
}
}

上面的代碼中,我們使用Table來布局,也可以使用其它的布局方式,比如DIV+CSS。
8)、捕捉並處理控制項的事件
到此以後,這些代碼已經可以產生文章開頭圖所顯示的效果,但是什麼事情也做不了,不能響應該控制項上的事件,所有還需要繼續實現該控制項上的事件代碼,實現這些事件採用冒泡所有子控制項的事件來實現。
首先,定義一個委託: 複製代碼 代碼如下:public delegate void PageOnEventHandler(object sender, EventArgs args);

其次,定義基於該委託的事件: 複製代碼 代碼如下:public event PageOnEventHandler RecPageChanged;

最後,重寫冒泡事件,並根據參數特徵,捕獲需要處理的事件,使其調用需要的方法。 複製代碼 代碼如下:protected override bool OnBubbleEvent(object source, EventArgs args)
{
bool handled = false;
CommandEventArgs cea = args as CommandEventArgs;
if(cea == null)
{
return handled;
}
switch (cea.CommandName)
{
case "first":
handled = true;
CurPage = 1;
break;
case "prev":
handled = true;
if (CurPage > 1)
{
CurPage--;
}
else
{
CurPage = 1;
}
break;
case "next":
handled = true;
if (CurPage < PageCount)
{
CurPage ++ ;
}
else
{
CurPage = PageCount;
}
break;
case "last":
handled = true;
CurPage = PageCount;
break;
case "go":
string strGo = txtGoPage.Text.Trim();
int iGo;
if (!string.IsNullOrEmpty(strGo) && int.TryParse(strGo, out iGo))
{
handled = true;
CurPage = iGo;
}
break;
}
if (handled)
{
if (this.RecPageChanged != null)
{
RecPageChanged(this, args);
this.RecreateChildControls();
}
return handled;
}
else
{
return base.OnBubbleEvent(source, args);
}
}

到此就完成了分頁控制項的開發。
注:可以定製該控制項的樣式,或者使用屬性暴露子控制項的屬性來控制樣式等.
四、使用分頁控制項
完成自訂控制項的開發後,在Toolbox中Choose Items或者直接在需要使用該自訂控制項的項目中引用該項目或者DLL,即可在Toolbox中顯示自訂控制項了。然後用拖拽的方式即可把分頁控制項放到需要的地方,就像使用button控制項一樣簡單。
然後再該頁面的後台代碼的OnLoad事件中,註冊需要被調用的方法到該控制項的RecPageChanged事件中,如下所示: 複製代碼 代碼如下:PageOn1.RecPageChanged += new CustomControl.PageOnEventHandler(PageOn1_RecPageChanged);

最後,只需要在方法PageOn1_RecPageChanged中編寫自己的代碼即可。 複製代碼 代碼如下:void PageOn1_RecPageChanged(object sender, EventArgs args)
{
//To do something
}

控制項的詳細代碼如下: 複製代碼 代碼如下:namespace CustomControl
{
public delegate void PageOnEventHandler(object sender, EventArgs args);
[DefaultProperty("PageSize")]
[ToolboxData("<{0}:PageOn runat=server Width=100%></{0}:PageOn>")]
public class PageOn :CompositeControl
{
#region
Label lblMessage;
LinkButton btnFirst;
LinkButton btnPrev;
LinkButton btnNext;
LinkButton btnLast;
TextBox txtGoPage;
Button btnGo;
#endregion
protected override void CreateChildControls()
{
Controls.Clear();
lblMessage = new Label();
lblMessage.Text = "當前第" + CurPage + "頁 共" + PageCount + "頁 共" + RowCount + "條記錄";
lblMessage.ID = "lblMessage";
Controls.Add(lblMessage);
btnFirst = new LinkButton();
btnFirst.Text = "首頁";
btnFirst.CommandName = "first";
btnFirst.ID = "btnFirst";
if (CurPage <= 1)
{
btnFirst.Enabled = false;
}
Controls.Add(btnFirst);
btnPrev = new LinkButton();
btnPrev.Text = "上一頁";
btnPrev.CommandName = "prev";
btnPrev.ID = "btnPrev";
if (CurPage <= 1)
{
btnPrev.Enabled = false;
}
Controls.Add(btnPrev);
btnNext = new LinkButton();
btnNext.Text = "下一頁";
btnNext.CommandName = "next";
btnNext.ID = "btnNext";
if (CurPage >= PageCount)
{
btnNext.Enabled = false;
}
Controls.Add(btnNext);
btnLast = new LinkButton();
btnLast.Text = "末頁";
btnLast.CommandName = "last";
btnLast.ID = "btnLast";
if (CurPage >= PageCount)
{
btnLast.Enabled = false;
}
Controls.Add(btnLast);
txtGoPage = new TextBox();
txtGoPage.TabIndex = 1;
txtGoPage.ID = "txtGoPage";
txtGoPage.Attributes.Add("onkeyup", @"this.value=this.value.replace(/\D/g,'')");
txtGoPage.Attributes.Add("onafterpaste", @"this.value=this.value.replace(/\D/g,'')");
Controls.Add(txtGoPage);
btnGo = new Button();
btnGo.TabIndex = 2;
btnGo.CommandName = "go";
btnGo.Text = "GO";
btnGo.ID="btnGO";
Controls.Add(btnGo);
Debug.WriteLine("ffffffffffffffffffffffffffffffffffffffffffffffffff");
base.CreateChildControls();
}
public int RowCount
{
get
{
if (ViewState["m_rowCount"] == null || int.Parse(ViewState["m_rowCount"].ToString()) < 0)
{
ViewState["m_rowCount"] = 0;
}
return int.Parse(ViewState["m_rowCount"].ToString());
}
set
{
if (value < 0)
{
ViewState["m_rowCount"] = 0;
}
else
{
ViewState["m_rowCount"] = value;
}
this.RecreateChildControls();
}
}
public int CurPage
{
get
{
if (ViewState["m_curPage"] ==null || int.Parse(ViewState["m_curPage"].ToString()) < 1)
{
ViewState["m_curPage"] = 1;
}
return int.Parse(ViewState["m_curPage"].ToString());
}
set
{
if (value < 1)
{
ViewState["m_curPage"] = 1;
}
else if (value > PageCount)
{
ViewState["m_curPage"] = PageCount;
}
else
{
ViewState["m_curPage"] = value;
}
}
}
public int PageCount
{
get
{
return RowCount / PageSize + 1;
}
}
public int PageSize
{
get
{
if (ViewState["m_pageSize"] ==null || int.Parse(ViewState["m_pageSize"].ToString()) < 1)
{
ViewState["m_pageSize"] = 15;
}
return int.Parse(ViewState["m_pageSize"].ToString());
}
set
{
if (value > 0)
{
ViewState["m_pageSize"] = value;
this.RecreateChildControls();
}
}
}
protected override void RenderContents(HtmlTextWriter output)
{
output.RenderBeginTag(HtmlTextWriterTag.Tr);
output.AddStyleAttribute("text-align", "left");
output.RenderBeginTag(HtmlTextWriterTag.Td);
output.Write(" ");
lblMessage.RenderControl(output);
output.RenderEndTag();
output.AddStyleAttribute("text-align", "right");
output.RenderBeginTag(HtmlTextWriterTag.Td);
btnFirst.RenderControl(output);
output.Write(" ");
btnPrev.RenderControl(output);
output.Write(" ");
btnNext.RenderControl(output);
output.Write(" ");
btnLast.RenderControl(output);
output.Write("到");
output.AddStyleAttribute(HtmlTextWriterStyle.Width, "30px");
txtGoPage.RenderControl(output);
output.Write("頁");
btnGo.RenderControl(output);
output.Write(" ");
output.RenderEndTag();
output.RenderEndTag();
}
protected override HtmlTextWriterTag TagKey
{
get
{
return HtmlTextWriterTag.Table;
}
}
public event PageOnEventHandler RecPageChanged;
protected override bool OnBubbleEvent(object source, EventArgs args)
{
bool handled = false;
CommandEventArgs cea = args as CommandEventArgs;
if(cea == null)
{
return handled;
}
switch (cea.CommandName)
{
case "first":
handled = true;
CurPage = 1;
break;
case "prev":
handled = true;
if (CurPage > 1)
{
CurPage--;
}
else
{
CurPage = 1;
}
break;
case "next":
handled = true;
if (CurPage < PageCount)
{
CurPage ++ ;
}
else
{
CurPage = PageCount;
}
break;
case "last":
handled = true;
CurPage = PageCount;
break;
case "go":
string strGo = txtGoPage.Text.Trim();
int iGo;
if (!string.IsNullOrEmpty(strGo) && int.TryParse(strGo, out iGo))
{
handled = true;
CurPage = iGo;
}
break;
}
if (handled)
{
if (this.RecPageChanged != null)
{
RecPageChanged(this, args);
this.RecreateChildControls();
}
return handled;
}
else
{
return base.OnBubbleEvent(source, args);
}
}
}
}

OK,完成

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.