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

ASP.NET 2.0 伺服器控制項捕獲回傳事件:IPostBackEventHandler 完整實作與事件屬性結構

     編輯:關於ASP.NET

回傳事件捕獲核心:IPostBackEventHandler

當控制項需響應使用者動作(按鈕點擊、連結點選、自訂命令)觸發回傳,並提供伺服器端事件給頁面開發者訂閱,必須實作 IPostBackEventHandler 介面:

public interface IPostBackEventHandler
{
    void RaisePostBackEvent(string eventArgument);
}

實作三大關鍵要件

1. 實作介面與 RaisePostBackEvent

public class CustomButton : WebControl, IPostBackEventHandler
{
    public event EventHandler Click;

    public void RaisePostBackEvent(string eventArgument)
    {
        OnClick(EventArgs.Empty);
    }

    protected virtual void OnClick(EventArgs e)
    {
        if (Click != null) Click(this, e);
    }
}

2. 渲染輸出正確的回傳腳本與 name 屬性

頁面框架依 name=UniqueID 識別觸發回傳的控制項。渲染時必須輸出:

  • name="UniqueID":識別碼。
  • onclick="__doPostBack('UniqueID', '')":觸發回傳的用戶端腳本(或 href="javascript:__doPostBack(...)")。
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, string.Empty);
    writer.AddAttribute(HtmlTextWriterAttribute.Onclick, postBackRef);
    writer.RenderBeginTag(HtmlTextWriterTag.Input);
    writer.RenderEndTag();
}

3. 事件屬性結構:優化記憶體與序列化

直接宣告 public event EventHandler Click; 會為每個控制項實例配置委派欄位,大量控制項時浪費記憶體。事件屬性結構 使用 EventHandlerList (鍵/值儲存) 集中管理:

public class CustomButton : WebControl, IPostBackEventHandler
{
    private static readonly object EventClick = new object();
    private EventHandlerList _events = new EventHandlerList();

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

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

    public void RaisePostBackEvent(string eventArgument)
    {
        OnClick(EventArgs.Empty);
    }
}
  • EventHandlerList 來自 System.ComponentModel,Component 基類已內建 Events 屬性,自訂控制項可繼承 Component 或自行建立欄位。
  • 優點:未訂閱事件零記憶體、序列化友善、統一管理所有事件。

完整範例:可攜帶命令引數的命令按鈕

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

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

    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)
    {
        OnCommand(new CommandEventArgs(CommandName, eventArgument));
    }

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

使用:<cc:CommandButton CommandName="Delete" CommandArgument='<%# Eval("ID") %>' Text="刪除" OnCommand="btn_Command" runat="server" />

事件引數傳遞機制

  • GetPostBackEventReference(control, argument) 產生 __doPostBack('UniqueID', 'argument')。
  • 回傳時 eventArgument 參數即為第二個引數。
  • 支援多重引數:自行編碼為 JSON 或管線符號分隔,RaisePostBackEvent 解析。

設計時支援

  • [DefaultEvent("Click")] 或 [DefaultEvent("Command")] 指定預設事件,雙擊控制項自動產生事件處理常式。
  • 事件加上 [Category("Action")]、[Description("按鈕點擊時引發")]。

常見問題與解決

問題原因修正
RaisePostBackEvent 未被呼叫渲染缺少 name=UniqueID、或缺少 __doPostBack 腳本檢查 Render 方法、確認 Page.Form 不為 null (需在 form runat=server 內)
事件引數為空GetPostBackEventReference 第二參數未傳遞、或 CommandArgument 未設定確認渲染邏輯正確傳遞引數
事件處理常式未觸發事件屬性結構鍵值不一致、或 Events 集合未正確初始化使用 static readonly object 作為鍵、確保 _events 實例化

總結

實作 IPostBackEventHandler 讓自訂控制項具備「觸發回傳 → 伺服器識別 → 引發事件」完整能力。掌握「正確渲染回傳腳本 → 事件屬性結構優化 → CommandEventArgs 傳遞引數」三大核心,即可打造專業級、記憶體高效、設計時友善的互動型伺服器控制項。

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