OnPreRender 是頁面生命周期中「渲染前」的最後一個事件,此時所有控件已創建、數據已綁定、ViewState 即將保存。掌握此節點可完成腳本注冊、標題設置、客戶端事件綁定、控件狀態微調、動態腳本塊生成等關鍵任務。本文通過五個實戰場景演示最佳實踐。
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
// 注冊啟動腳本(頁面加載時執行)
this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "InitScript", RenderScript(), true);
// 注冊提交前執行語句(表單提交前驗證/處理)
this.Page.ClientScript.RegisterOnSubmitStatement(this.GetType(), "StoreBody", "StorePostBody();");
}
private string RenderScript()
{
return @"
function StorePostBody() { /* 保存編輯器內容 */ }
function InitEditor() { /* 初始化富文本編輯器 */ }
";
}
要點:RegisterClientScriptBlock 放在 <form> 開頭,RegisterOnSubmitStatement 放在提交事件前,確保執行順序正確。
protected override void OnPreRender(EventArgs e)
{
if (_mainTitle != null)
_mainTitle.Text = ResourceManager.GetString("PageTitle");
if (_subTitle != null)
_subTitle.Text = ResourceManager.GetString("SubTitle");
base.OnPreRender(e); // 必須最後調用,確保控件屬性生效
}
此時資源文件已加載,控件樹已建立,設置 Text 屬性最安全,避免被後續綁定覆蓋。
protected override void OnPreRender(EventArgs e)
{
Submit.Attributes.Add("onclick",
"return SubmitSendToFriend('" + From.ClientID + "', '" + To.ClientID + "');");
base.OnPreRender(e);
}
使用 ClientID 確保腳本能精確找到控件,return 讓驗證失敗時阻止回發。
protected override void OnPreRender(EventArgs e)
{
if (!replyButton.Visible) ((Literal)FindControl("Sep1")).Visible = false;
if (!threadSubButton.Visible) ((Literal)FindControl("Sep3")).Visible = false;
if (!rateButton.Visible) ((Literal)FindControl("Sep2")).Visible = false;
base.OnPreRender(e);
}
在 PreRender 階段調整可見性,保證 ViewState 記錄最終狀態,避免頁面閃爍。
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
var sb = new StringBuilder();
sb.AppendLine("function ToggleRateMenu() {");
sb.AppendLine(" var menu = document.getElementById('RateMenu');");
sb.AppendLine(" var btn = document.getElementById('RateButton');");
sb.AppendLine(" menu.style.left = getPosOffset(btn, 'left') + 'px';");
sb.AppendLine(" menu.style.top = getPosOffset(btn, 'top') + btn.offsetHeight + 'px';");
sb.AppendLine(" menu.style.visibility = menu.style.visibility === 'hidden' ? 'visible' : 'hidden';");
sb.AppendLine(" menu.style.display = menu.style.display === 'none' ? 'block' : 'none';");
sb.AppendLine("}");
sb.AppendLine("function getPosOffset(el, type) {");
sb.AppendLine(" var offset = type === 'left' ? el.offsetLeft : el.offsetTop;");
sb.AppendLine(" while (el = el.offsetParent) offset += type === 'left' ? el.offsetLeft : el.offsetTop;");
sb.AppendLine(" return offset;");
sb.AppendLine("}");
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "RateMenuScript", sb.ToString(), true);
}
優勢:C# 構建字符串享受智能提示、重構支持,避免字符串拼接錯誤;RegisterClientScriptBlock 自動添加 <script> 標簽並防止重複注冊。
| 場景 | 關鍵 API | 注意事項 |
|---|---|---|
| 啟動腳本 | RegisterClientScriptBlock | Key 唯一、最後參數 true 自動包裹 script 標簽 |
| 提交前驗證 | RegisterOnSubmitStatement | 返回 false 可取消提交 |
| 控件屬性微調 | 控件屬性直接賦值 | 必須在 base.OnPreRender(e) 之前 |
| 客戶端事件綁定 | Attributes.Add("onclick", ...) | 使用 ClientID、return 阻止回發 |
| 複雜腳本塊 | StringBuilder + RegisterClientScriptBlock | 統一註冊、避免內聯腳本分散 |
OnPreRender 是服務端控制客戶端行為的「最後防線」。合理利用此事件,能將腳本注冊、UI 微調、多語言標題等邏輯集中管理,避免分散在 Page_Load、控件事件中造成維護困難。記住:讀取控件值在 Load,修改控件狀態在 PreRender。