摘要:[C#]樹狀圖於小視窗傳值的應用
還記得之前有寫過樹狀圖的用法,
想不到過沒幾天又有另一個狀況要用到了,
這次是要在頁面上以開啟小視窗的方式來選擇部門,
點選完畢之後會將選取的部門名稱帶回母視窗,
並且子視窗自動關閉。
先來看一下假想中的組織圖,
相信大家應該都不陌生,
反正就是大的樹狀架構,越往上代表層級越高:
那在資料庫中要怎麼呈現這樣的關係呢?
其實也很簡單,
先用一個欄位紀錄每個階級的代號,(也可以看作是部門代號)
再用另一個欄位去記錄上一層(父層)的代號就好了:
在這個範例中,
將用到兩個頁面,分別是母視窗;以及用來選擇的子視窗:
母視窗:index.aspx
子視窗:tree.aspx
在母視窗中,
先放置一個用來接收訊息的文字方塊,
和用來呼叫子視窗的按鈕:
<input type="text" id="treeMsg" /> 2
<input type="button" value="選擇" onclick="JavaScript:openTree();" />
然後是用來開啟小視窗的JS碼:
function openTree() 2
{ 3
window.open('tree.aspx', 'tree', 'toolbar=no, menubar=no, status=no, scrollbars=no, width=300px, height=400px, resizable=no'); 4
} 5
</script>
讀者可以自行設定子視窗大小、是否顯示狀態列等選項,
在此就不贅述。
以上是母視窗要準備的東西,
接下來重點要放在子視窗tree.aspx裡面。
C#程式碼部分:
初始化SQL連接指令:
SqlConnection SqlConn = new SqlConnection("輸入你的伺服器設定"); 2
SqlCommand SqlCmd; 3
SqlDataReader MyReader;
然後設定在Page Load時去啟動樹狀圖:
void Page_Load(object sender, EventArgs e) 2
{ 3
if (!Page.IsPostBack) 4
{ 5
addService(); 6
} 7
}
樹狀圖部分,先建立父節點:
void addService() 02
{ 03
string nodeName = string.Empty; //節點名稱=部門名稱 04
string nodeValue = string.Empty; //節點值=部門代號 05
// 06
string QryString = "SELECT DeptNo, DeptCName FROM Department WHERE DeptParent IS NULL"; 07
SqlConn.Open(); 08
SqlCmd = new SqlCommand(QryString, SqlConn); 09
MyReader = SqlCmd.ExecuteReader(); 10
while (MyReader.Read()) 11
{ //先找出最上層的階級(大老闆) 12
nodeName = MyReader ["DeptCName "].ToString(); 13
nodeValue = MyReader ["DeptNo "].ToString(); 14
} 15
MyReader.Close(); 16
SqlConn.Close(); 17
// 18
TreeView1.Nodes.Clear(); 19
TreeNode MyNode = new TreeNode(); 20
MyNode.Expanded = false; //節點是否展開 21
MyNode.Text = nodeName; //節點文字=部門名稱 22
MyNode.Value = nodeValue; //節點值=部門代號 23
MyNode.NavigateUrl = "JavaScript:sendMsg('" + nodeValue + "');"; //目標連結 24
MyNode.Target = ""; //連結開啟方式 25
// 26
MyNode.PopulateOnDemand = true; 27
TreeView1.Nodes.Add(MyNode); 28
}上面這段程式碼是用來建立最上層階級,(根目錄)
通常也就是董事長、總經理之類的,
其他底下的部門或是副董事長則依附在此階級之下,
形成樹狀圖。
另一個重點就是在於如何把JS的程式放入樹狀圖,並且加上onclick屬性
在一開始時,我很直覺的用TreeView1.Attributes.Add的方式來做,
跑出來的結果卻是無論點哪邊都失敗,
後來才注意到必須將要觸發的JS程式寫在節點的NavigateUrl屬性裡,
這個屬性原本是用來設定點擊節點時要前往的網址,
不過在這邊卻變成了啟動JS程式的onclick屬性,
算是比較特殊的地方。
建立完父節點之後,接下來就要用遞迴的方式去跑出其他子節點,
做法其實跟我之前寫這篇一樣,
[C#]樹狀圖(TreeView)的用法
所以在這邊就只用註解提示,
詳細的運作流程請看之前的文章囉。
//產生子節點 Part1 2
void PopulateNode(Object sender, TreeNodeEventArgs e) 3
{ 4
e.Node.ChildNodes.Clear(); 5
PopulateProducts(e.Node); 6
}
//產生子節點 Part2 02
void PopulateProducts(TreeNode node) 03
{ 04
DataSet ResultSet = RunQuery("SELECT DeptNo, DeptCName FROM Department WHERE DeptParent='"+node.Value+"'"); 05
// 06
if (ResultSet.Tables.Count > 0) 07
{ 08
foreach (DataRow row in ResultSet.Tables[0].Rows) 09
{ 10
// 建立新節點 11
//節點參數:(文字, 值, 節點圖片URL, 目標連結URL, 連結開啟方式) 12
TreeNode NewNode = new TreeNode(row["DeptCName"].ToString(), row["DeptNo"].ToString(), "", "JavaScript:sendMsg('" + Convert.ToString(row["DeptNo"]) + "')", ""); 13
// 14
// 動態設定 PopulateOnDemand 值, 15
// 在此節點底下仍有子節點時,才會產生展開符號 16
if (chkChildNodes(NewNode)) 17
{ 18
NewNode.PopulateOnDemand = true; 19
} 20
else 21
{ 22
NewNode.PopulateOnDemand = false; 23
} 24
// 25
NewNode.SelectAction = TreeNodeSelectAction.Expand; // 設定點選節點時展開 26
node.ChildNodes.Add(NewNode); 27
} 28
} 29
}
最後,是傳值的JS碼以及HTML code。
<script type="text/javascript"> 2
3
function sendMsg(msgInput) 4
{ 5
opener.document.form1.treeMsg.value=msgInput; 6
window.close(); 7
} 8
</script>
2 OnTreeNodePopulate="PopulateNode"
3 runat="server" /> </asp:TreeView>
做完感想是這樣做還蠻炫的,
不過馬上被潑了冷水…
「還要跳視窗出來太不人性化了~~~」
「要做在同一個頁面上才方便啊~~~」
…
算了…反正我也不是第一次被打槍…
做這途的真的要有健康的心理啊。
