通過簡單 Demo 觀察 TextBox TextChanged 事件觸發條件:
結論: TextChanged 僅在「文本值真正改變」時觸發。
public class TextBox : WebControl, IPostBackDataHandler, IEditableTextControl, ITextControl
public interface IPostBackDataHandler {
bool LoadPostData(string postDataKey, NameValueCollection postCollection);
void RaisePostDataChangedEvent();
}
protected virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection) {
base.ValidateEvent(postDataKey);
string oldText = this.Text; // 視圖狀態中的舊值
string newText = postCollection[postDataKey]; // 表單提交的新值
if (!this.ReadOnly && !oldText.Equals(newText, StringComparison.Ordinal)) {
this.Text = newText; // 更新為新值
return true; // 標記數據已變更
}
return false; // 數據未變更
}
關鍵邏輯: 僅當控件非唯讀且新舊值不同時,更新 Text 屬性並返回 true,通知運行時稍後觸發 Changed 事件。
protected virtual void RaisePostDataChangedEvent() {
// 處理 AutoPostBack 邏輯
if (this.AutoPostBack && !this.Page.IsPostBackEventControlRegistered) {
this.Page.AutoPostBackControl = this;
if (this.CausesValidation) this.Page.Validate(this.ValidationGroup);
}
// 核心:觸發 TextChanged 事件
this.OnTextChanged(EventArgs.Empty);
}
this.LoadAllState(); // 載入 ViewState/ControlState
this.ProcessPostData(...); // 處理回發數據
IPostBackDataHandler,呼叫 LoadPostData_changedPostDataConsumers 集合_leftoverPostData 待第二次處理this.ProcessPostData(_leftoverPostData, false); // 第二次嘗試處理動態控件
this.RaiseChangedEvents(); // 觸發所有 Changed 事件
this.RaisePostBackEvent(...); // 觸發按鈕點擊等 PostBack 事件
internal void RaiseChangedEvents() {
if (this._changedPostDataConsumers != null) {
foreach (Control control in this._changedPostDataConsumers) {
var handler = control.PostBackDataHandler;
if (handler != null) handler.RaisePostDataChangedEvent();
}
}
}
這裡遍歷所有標記為「數據已變更」的控件,呼叫其 RaisePostDataChangedEvent,最終觸發 TextChanged。
動態控件在 Page_Load 中添加時,因 _controlState >= ControlState.ViewStateLoaded 條件成立,會自動加載 ViewState/ControlState。但首次請求時無回發數據,第二次請求時才能正常觸發事件。
ProcessPostData 階段呼叫 LoadPostData_changedPostDataConsumersRaiseChangedEvents 階段呼叫 RaisePostDataChangedEventOnTextChanged → 用戶代碼執行核心原則: 數據變更檢測發生在 LoadPostData,事件觸發延遲到 RaiseChangedEvents,確保所有控件狀態同步更新後再統一觸發事件。