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

ASP.NET 2.0 伺服器控制項回傳資料處理:IPostBackDataHandler 完整實作指南

     編輯:關於ASP.NET

為什麼需要 IPostBackDataHandler?

當自訂控制項為輸入型控制項(如 TextBox、DropDownList、自訂編輯器)時,使用者輸入的值會隨表單回傳至伺服器。控制項必須實作 IPostBackDataHandler 介面,才能:

  1. 從回傳集合 (NameValueCollection) 讀取自己的值。
  2. 比較新舊值,判斷資料是否變更。
  3. 引發 TextChanged 等資料變更事件。

介面定義與核心方法

public interface IPostBackDataHandler
{
    // 從回傳資料載入控制項值
    // 回傳 true 表示資料已變更,需引發 RaisePostDataChangedEvent
    bool LoadPostData(string postDataKey, NameValueCollection postCollection);

    // 資料確認變更後引發,通常在此觸發 TextChanged 等事件
    void RaisePostDataChangedEvent();
}

實作關鍵兩要件

1. 渲染時輸出正確的 name 屬性

頁面框架依 UniqueID 在回傳集合中尋找對應值。控制項必須在渲染時將 name 設為 UniqueID:

protected override void Render(HtmlTextWriter writer)
{
    writer.AddAttribute(HtmlTextWriterAttribute.Name, UniqueID);
    writer.AddAttribute(HtmlTextWriterAttribute.Id, ClientID);
    writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");
    writer.AddAttribute(HtmlTextWriterAttribute.Value, Text); // 目前值
    writer.RenderBeginTag(HtmlTextWriterTag.Input);
    writer.RenderEndTag();
}

2. 實作 LoadPostData 比較新舊值

public virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection)
{
    string postedValue = postCollection[postDataKey]; // 使用者輸入的新值
    string currentValue = Text; // 目前控制項值 (ViewState 還原後)

    if (currentValue != postedValue)
    {
        Text = postedValue; // 更新控制項值
        return true; // 標記資料已變更
    }
    return false; // 資料未變更
}

3. 實作 RaisePostDataChangedEvent 引發事件

public event EventHandler TextChanged;

public virtual void RaisePostDataChangedEvent()
{
    OnTextChanged(EventArgs.Empty);
}

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

完整範例:自訂文字方塊控制項

[ToolboxData("<{0}:CustomTextBox runat=server></{0}:CustomTextBox>")]
public class CustomTextBox : WebControl, IPostBackDataHandler
{
    public string Text
    {
        get { object o = ViewState["Text"]; return o == null ? string.Empty : (string)o; }
        set { ViewState["Text"] = value; }
    }

    public event EventHandler TextChanged;

    protected override void Render(HtmlTextWriter writer)
    {
        writer.AddAttribute(HtmlTextWriterAttribute.Name, UniqueID);
        writer.AddAttribute(HtmlTextWriterAttribute.Id, ClientID);
        writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");
        writer.AddAttribute(HtmlTextWriterAttribute.Value, Text);
        // 可加入 style、class、maxlength 等
        writer.RenderBeginTag(HtmlTextWriterTag.Input);
        writer.RenderEndTag();
    }

    public virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection)
    {
        string posted = postCollection[postDataKey];
        if (Text != posted)
        {
            Text = posted;
            return true;
        }
        return false;
    }

    public virtual void RaisePostDataChangedEvent()
    {
        OnTextChanged(EventArgs.Empty);
    }

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

頁面框架處理流程

  1. 回傳發生,頁面框架建立 NameValueCollection 包含所有 name=value。
  2. 遍歷控制項樹,尋找實作 IPostBackDataHandler 的控制項。
  3. 呼叫 LoadPostData(UniqueID, postCollection)。
  4. 若回傳 true,將控制項加入變更清單。
  5. Load 階段結束後,依序呼叫變更清單中控制項的 RaisePostDataChangedEvent()。
  6. 引發 TextChanged 等事件,開發者在事件處理常式中回應資料變更。

進階:支援驗證與強制回傳

  • 實作 IPostBackDataHandler 同時實作 IValidator 或搭配 ValidationPropertyAttribute,整合驗證架構。
  • 設定 AutoPostBack="true" 並在 LoadPostData 偵測變更時呼叫 Page.ClientScript.GetPostBackEventReference(this, "") 觸發回傳(需渲染對應 __doPostBack 腳本)。

常見錯誤與除錯

錯誤原因修正
LoadPostData 從未被呼叫渲染的 name 屬性不是 UniqueID確保 Render 寫入 writer.AddAttribute("name", UniqueID)
TextChanged 事件不觸發LoadPostData 未回傳 true、或未實作 RaisePostDataChangedEvent比較邏輯正確、回傳 true、呼叫 OnTextChanged
值在回傳後消失未將 postedValue 指派給 Text 屬性 (ViewState)LoadPostData 內 Text = postedValue
多個同類控制項值混淆UniqueID 衝突 (未實作 INamingContainer)父控制項實作 INamingContainer 或繼承 CompositeControl

總結

IPostBackDataHandler 是 ASP.NET 伺服器控制項處理回傳輸入資料的標準協定。掌握「正確 name 屬性 → LoadPostData 比較新舊值 → RaisePostDataChangedEvent 引發事件」三步驟,即可打造功能完整、整合驗證架構、支援自動回傳的專業輸入型控制項。

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