ASP.NET 2.0 TreeView 控制項在回傳後無法自動維持捲軸位置,導致使用者需重新捲動。本文分析 SmartNavigation 與 MaintainScrollPositionOnPostback 缺失,並提供通用 JavaScript 解法。
SmartNavigation:舊版屬性,利用 iframe 減少閃爍並嘗試保持位置,但相容性差、已標記過時。MaintainScrollPositionOnPostback:ASP.NET 2.0 新增,僅記錄頁面捲軸位置。若 TreeView 置於 UserControl 或 Panel 內,回傳後會定位到容器而非樹節點。核心原理:TreeView 會產生隱藏欄位 TreeView1_SelectedNode 記錄目前選取節點的 ClientID。回傳後,透過 scrollIntoView() 將該節點捲動至可視區域。
Partial Class _Default
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
InjectLoadEvent()
If IsPostBack Then Return
' 建立測試樹節點
TreeView1.Nodes.Clear()
Dim categories() As String = {"Chicken", "Beef", "Pork", "Fish"}
For Each cat In categories
Dim parent As New TreeNode(cat)
TreeView1.Nodes.Add(parent)
For i = 1 To 50
parent.ChildNodes.Add(New TreeNode("Placeholder " & i))
Next
Next
TreeView1.CollapseAll()
End Sub
Public Sub InjectLoadEvent()
Dim script As String = _
"function LoadEvent() {" & _
" try {" & _
" var elem = document.getElementById('{0}_SelectedNode');" & _
" if (elem != null) {" & _
" var node = document.getElementById(elem.value);" & _
" if (node != null) {" & _
" node.scrollIntoView(true);" & _
" {1}.scrollLeft = 0;" & _
" }" & _
" }" & _
" } catch(e) {}" & _
"}"
Page.ClientScript.RegisterClientScriptBlock(Me.GetType(), "LoadEvent", _
String.Format(script, TreeView1.ClientID, Panel1.ClientID), True)
End Sub
End Class
RegisterClientScriptBlock 在頁面輸出 <script> 區塊,確保 LoadEvent 函數可用。body onload="LoadEvent()" 或 Page.ClientScript.RegisterStartupScript 呼叫該函數。Panel1 為包裹 TreeView 的容器,重設 scrollLeft 避免水平捲動異常。若 TreeView 在 UpdatePanel 內,需在 PageRequestManager 的 endRequest 事件中呼叫 LoadEvent(),確保部分更新後同步捲動。