首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> 關於ASP.NET

ASP.NET 2.0 伺服器控制項事件開發:基類事件重寫與自訂事件完整實作指南

     編輯:關於ASP.NET

控制項事件兩大來源

  • 繼承自基類:Control 基類定義 Init、Load、PreRender、Unload、DataBinding、Disposed 等生命週期事件。
  • 自訂事件:依業務需求定義 (如 Click、Command、Search、FileUploaded)。

重寫基類事件:標準模式

public class CustomControl : WebControl
{
    protected override void OnInit(EventArgs e)
    {
        // 1. 自訂邏輯 (註冊腳本、初始化狀態)
        RegisterClientScript();
        // 2. 必須呼叫基類實作,確保事件委派被引發
        base.OnInit(e);
    }

    protected override void OnLoad(EventArgs e)
    {
        // 恢復 ViewState 後、回傳事件前
        if (!Page.IsPostBack) InitializeDefaults();
        base.OnLoad(e);
    }

    protected override void OnPreRender(EventArgs e)
    {
        // 渲染前最後調整
        EnsureChildControls();
        SyncVisualState();
        base.OnPreRender(e);
    }

    protected override void OnUnload(EventArgs e)
    {
        // 釋放非受控資源
        ReleaseResources();
        base.OnUnload(e);
    }
}

鐵律:覆寫 OnEventName 時一定要呼叫 base.OnEventName(e),否則訂閱該事件的委派不會被執行。

自訂事件實作三步驟

1. 定義事件與委派

// 簡單事件
public event EventHandler Click;

// 攜帶資料事件
public event EventHandler Search;

public class SearchEventArgs : EventArgs
{
    public string Keyword { get; private set; }
    public SearchEventArgs(string keyword) { Keyword = keyword; }
}

2. 定義受保護引發方法

protected virtual void OnClick(EventArgs e)
{
    EventHandler handler = (EventHandler)Events[EventClick];
    if (handler != null) handler(this, e);
}

protected virtual void OnSearch(SearchEventArgs e)
{
    EventHandler handler = (EventHandler)Events[EventSearch];
    if (handler != null) handler(this, e);
}

使用 Events 屬性 (EventHandlerList) 統一管理,節省記憶體。

3. 在適當時機呼叫引發方法

  • 回傳事件:實作 IPostBackEventHandler.RaisePostBackEvent → 呼叫 OnClick。
  • 資料變更:實作 IPostBackDataHandler.RaisePostDataChangedEvent → 呼叫 OnTextChanged。
  • 內部邏輯觸發:btn_Click 處理常式中呼叫 OnSearch(new SearchEventArgs(txt.Text))。

事件屬性結構完整範例

[DefaultEvent("Click")]
[ToolboxData("<{0}:CustomButton runat=server></{0}:CustomButton>")]
public class CustomButton : WebControl, IPostBackEventHandler
{
    private static readonly object EventClick = new object();
    private static readonly object EventCommand = new object();

    public string CommandName { get; set; }
    public string CommandArgument { get; set; }

    public event EventHandler Click
    {
        add { Events.AddHandler(EventClick, value); }
        remove { Events.RemoveHandler(EventClick, value); }
    }

    public event CommandEventHandler Command
    {
        add { Events.AddHandler(EventCommand, value); }
        remove { Events.RemoveHandler(EventCommand, value); }
    }

    protected override void Render(HtmlTextWriter writer)
    {
        writer.AddAttribute(HtmlTextWriterAttribute.Name, UniqueID);
        writer.AddAttribute(HtmlTextWriterAttribute.Id, ClientID);
        writer.AddAttribute(HtmlTextWriterAttribute.Type, "submit");
        writer.AddAttribute(HtmlTextWriterAttribute.Value, Text);
        string postBackRef = Page.ClientScript.GetPostBackEventReference(this, CommandArgument);
        writer.AddAttribute(HtmlTextWriterAttribute.Onclick, postBackRef);
        writer.RenderBeginTag(HtmlTextWriterTag.Input);
        writer.RenderEndTag();
    }

    public void RaisePostBackEvent(string eventArgument)
    {
        OnClick(EventArgs.Empty);
        OnCommand(new CommandEventArgs(CommandName, eventArgument));
    }

    protected virtual void OnClick(EventArgs e)
    {
        EventHandler handler = (EventHandler)Events[EventClick];
        if (handler != null) handler(this, e);
    }

    protected virtual void OnCommand(CommandEventArgs e)
    {
        CommandEventHandler handler = (CommandEventHandler)Events[EventCommand];
        if (handler != null) handler(this, e);
    }
}

設計時支援屬性

  • [DefaultEvent("Click")]:雙擊控制項自動產生 Click 事件處理常式。
  • [Category("Action")]、[Description("按鈕被點擊時引發")]:屬性視窗分類與說明。
  • [Browsable(true)]:確保事件顯示於屬性視窗 (預設即為 true)。

進階:事件路由與冒泡

  • 復合控制項子控制項事件向上冒泡:覆寫 OnBubbleEvent 攔截 CommandEventArgs 轉發為頂層事件。
  • 頁面框架自動路由 Command 事件至 ItemCommand (Repeater/DataList/GridView)。

常見錯誤與除錯

錯誤原因修正
事件處理常式未執行未呼叫 base.OnEventName、或 Events 鍵值不一致檢查 base.OnEventName(e)、static readonly object 鍵值唯一
事件在設計時不顯示缺少 DefaultEvent、或事件非 public加上 [DefaultEvent("EventName")]、確保 public event
回傳事件引發兩次同時實作 IPostBackEventHandler 且子控制項也引發回傳確保唯一觸發點、或使用事件屬性結構避免重複訂閱

總結

ASP.NET 伺服器控制項事件系統建立在委派、EventHandlerList、生命週期虛擬方法、回傳介面四大支柱。掌握「重寫基類事件必呼叫 base、自訂事件三步驟、事件屬性結構優化、設計時屬性、冒泡路由」,即可打造功能完整、效能優異、設計時友善的專業控制項事件模型。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved