ASP.NET 自訂控件分為使用者控件、複合控件、自訂控件三類。本文以「通用分頁器」為例,示範如何用複合控件 實作不依賴特定資料顯示控件的分頁元件。
Control,重寫 CreateChildControls() 動態建構子控件 (LinkButton、Literal 等)。DataBinding 事件:所有衍生自 Control 的控件皆有此事件,分頁器以此取得資料來源狀態,達到與顯示控件解耦。DataBinding 事件觸發。CurrentPageIndex → 重新繫結資料來源控件。[ToolboxData("<{0}:Pager runat=server>{0}:Pager>")]
public class Pager : CompositeControl
{
private LinkButton lnkFirst, lnkPrev, lnkNext, lnkLast;
private Panel pnlPageNumbers;
protected override void CreateChildControls()
{
Controls.Clear();
// 建立導航按鈕
lnkFirst = new LinkButton { Text = "首頁", CommandName = "First" };
lnkPrev = new LinkButton { Text = "上頁", CommandName = "Prev" };
lnkNext = new LinkButton { Text = "下頁", CommandName = "Next" };
lnkLast = new LinkButton { Text = "末頁", CommandName = "Last" };
Controls.AddRange(new Control[] { lnkFirst, lnkPrev, pnlPageNumbers, lnkNext, lnkLast });
// 動態產生頁碼連結
for (int i = 1; i <= TotalPages; i++)
{
LinkButton lb = new LinkButton { Text = i.ToString(), CommandName = "Page", CommandArgument = i.ToString() };
pnlPageNumbers.Controls.Add(lb);
}
}
// 處理子控件命令
protected override bool OnBubbleEvent(object source, EventArgs e)
{
if (e is CommandEventArgs ce)
{
switch (ce.CommandName)
{
case "First": CurrentPageIndex = 1; break;
case "Prev": if (CurrentPageIndex > 1) CurrentPageIndex--; break;
case "Next": if (CurrentPageIndex < TotalPages) CurrentPageIndex++; break;
case "Last": CurrentPageIndex = TotalPages; break;
case "Page": CurrentPageIndex = int.Parse((string)ce.CommandArgument); break;
}
RaiseDataBinding(); // 觸發資料重繫
return true;
}
return base.OnBubbleEvent(source, e);
}
}
<cc1:Pager ID="Pager1" runat="server" PageSize="20"
DataSourceID="ObjectDataSource1" />
<asp:GridView ID="GridView1" runat="server" DataSourceID="ObjectDataSource1" />
分頁器透過 DataSourceID 找到資料源,無需知道 GridView 存在。
UpdatePanel 或實作 ICallbackEventHandler)。CssClass、PageButtonCssClass、CurrentPageCssClass。ROW_NUMBER / OFFSET FETCH)。複合控件 + DataBinding 事件 = 高度解耦的通用分頁器。掌握此模式,可快速建構各類可重用的資料導向伺服器控件。