預設 asp:TreeView 點選節點會觸發 PostBack,導致頁面閃爍。若需「點選節點 → 即時將 Text 填入 TextBox、Value 存入 HiddenField → 無 PostBack」,可透過 JavaScript 攔截節點點擊事件達成。
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="TreeViewDemo.aspx.cs" Inherits="TreeViewDemo" %>
<!DOCTYPE html>
<html xmlns="https://www.w3.org/1999/xhtml">
<head runat="server">
<title>TreeView 無回傳取值示範</title>
<style>
#overlay { position:fixed; top:0; left:0; width:100%; height:100%; background:#fff; opacity:0.6; display:none; z-index:999; }
#treePanel { position:fixed; width:300px; height:250px; border:1px solid #ccc; background:#fff; display:none; z-index:1000; overflow:auto; }
</style>
</head>
<body>
<form id="form1" runat="server">
<asp:HiddenField ID="hfValue" runat="server" />
<asp:TextBox ID="txtDisplay" runat="server" ReadOnly="true" Style="width:200px;" />
<asp:Button ID="btnShow" runat="server" Text="選擇分類" OnClientClick="showTree(); return false;" />
<br /><br />
Value: <asp:TextBox ID="txtValue" runat="server" ReadOnly="true" />
<div id="overlay" onclick="hideTree()"></div>
<div id="treePanel">
<button type="button" onclick="hideTree()">關閉</button>
<asp:TreeView ID="tvCategory" runat="server">
<Nodes>
<asp:TreeNode Text="產品類別" Value="0" NavigateUrl="#0">
<asp:TreeNode Text="電子產品" Value="00" NavigateUrl="#00">
<asp:TreeNode Text="手機" Value="000" NavigateUrl="#000" />
<asp:TreeNode Text="筆電" Value="001" NavigateUrl="#001" />
</asp:TreeNode>
<asp:TreeNode Text="家電" Value="01" NavigateUrl="#01" />
</asp:TreeNode>
<asp:TreeNode Text="服務類別" Value="1" NavigateUrl="#1">
<asp:TreeNode Text="維修" Value="10" NavigateUrl="#10" />
<asp:TreeNode Text="安裝" Value="11" NavigateUrl="#11" />
</asp:TreeNode>
</Nodes>
</asp:TreeView>
</div>
</form>
<script>
// 顯示/隱藏面板
function showTree() {
var txt = document.getElementById('<%= txtDisplay.ClientID %>');
var panel = document.getElementById('treePanel');
var overlay = document.getElementById('overlay');
panel.style.left = txt.offsetLeft + 'px';
panel.style.top = (txt.offsetTop + txt.offsetHeight) + 'px';
overlay.style.display = 'block';
panel.style.display = 'block';
}
function hideTree() {
document.getElementById('overlay').style.display = 'none';
document.getElementById('treePanel').style.display = 'none';
}
// 節點點擊處理
function treeNodeClick() {
var el = event.srcElement || event.target;
// TreeView 渲染的節點連結帶有 id 與 href="#Value"
if (!el.id || !el.href) return true;
var href = el.href;
var hashIndex = href.indexOf('#');
if (hashIndex === -1) return true;
var value = href.substring(hashIndex + 1); // 取得 Value
var text = el.innerText || el.textContent; // 取得 Text
if (text) {
document.getElementById('<%= txtDisplay.ClientID %>').value = text;
document.getElementById('<%= txtValue.ClientID %>').value = value;
document.getElementById('<%= hfValue.ClientID %>').value = value;
hideTree();
}
return false; // 取消預設連結行為 (避免跳轉)
}
</script>
</body>
</html>
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// 關鍵:將 onclick 事件導向前端 JS 函式,阻止 PostBack
tvCategory.Attributes.Add("onclick", "return treeNodeClick();");
}
}
| 步驟 | 說明 |
|---|---|
| NavigateUrl="#Value" | TreeView 會將節點渲染為 `Text`,Value 寫在 hash 部分。 |
| JS 解析 hash | `href.substring(href.indexOf('#')+1)` 即可取得 Value,無需 PostBack 回伺服器。 |
| return false | 阻止瀏覽器預設錨點跳轉行為,同時取消 PostBack。 |
| Attributes.Add | 在伺服端為 TreeView 整體掛上 onclick,利用事件冒泡捕捉所有節點點擊。 |
若樹狀結構龐大,可採用「展開時才用 AJAX 取得子節點」模式:
或改用成熟的前端樹狀元件 (jsTree、zTree、Vue/React Tree Component) 配合 Web API,體驗更佳。
利用 TreeView 產生的 `` 特性,搭配 JavaScript 解析 hash、回填控制項、阻止預設行為,即可實現零 PostBack 的節點選取體驗,適合簡單下拉選單替代方案。