這個功能,說真的我不知道用在哪裡好,
不過老闆想要這樣的頁面,所以我就做了,
上網搜尋了一下,關於在網頁製作這個功能的資訊實在不多(可能是太簡單了,所以沒人分享),
大部分都是WindowForm上操作TreeView的文章,
所以我就分享一下在網頁上操作TreeView的程式碼吧!
有需要用的人,可以參考看看。
由於原本是想用Javascript做,所以ASP.NET的語言部份,也就選用跟Javascript相似的C#,
不過製作過程中發現,直接用C#就夠了,還不到Javascript出場的時候。
呵呵~Javascript可是我的壓箱寶阿!
這個功能所用到的TreeView操作:
//TreeView變數,這樣宣告會是ref宣告,會把該object帶過去的 TreeView tv = (TreeView)sender; TreeView tv = (TreeView)TreeView1; //TreeNode變數,這樣宣告會是ref宣告,會把該object帶過去的 TreeNode tnode = TreeView1.Nodes[TreeView1.Nodes.Count - 1]; //root node TreeNode tnode = tnode.ChildNodes[tnode.ChildNodes.Count - 1]; //child node //刪除所有TreeNode TreeView1.Nodes.Clear(); //新增TreeNode TreeView1.Nodes.Add(new TreeNode("Text", "Value")); //root node parent.ChildNodes.Add(new TreeNode("Text", "Value")); //child node //設定滑鼠按下去沒有動作 tnode.SelectAction = TreeNodeSelectAction.None; //取得目前選取的結點 TreeNode tnode = ((TreeView)sender).SelectedNode; TreeNode tnode = ((TreeView)TreeView1).SelectedNode; //TreeNode的Text跟Value tnode.Text = ""; tnode.Value = ""; string Text = tnode.Text; string Value = tonde.Value; //取得 root node count if (((TreeView)TreeView1).Nodes.Count <= 0) return; //沒有選取TreeNode的判斷 if(((TreeView)TreeView1).SelectedNode == null) return; //刪除TreeNode //必須指回parent之後,才能刪除parent的root node、child node,不能node自我刪除,例如:tnode.remove(); TreeNode tnode = ((TreeView)TreeView1).SelectedNode; //先取得TreeNode ((TreeView)TreeView1).Nodes.Remove(tnode); //如果該TreeNode在root,要刪除root node tnode.Parent.ChildNodes.Remove(tnode); //如果該TreeNode在child,要刪除child node //選取TreeNode tnode.Selected = true; //展開TreeView所有TreeNode ((TreeView)sender).ExpandAll(); TreeView1.ExpandAll(); //取得TreeNode的深度 int nd = tnode.Depth; if (tnode.Depth == 0) //root node else //child node //巡覽所有TreeNode //需要兩道手續...還沒想到更好的辦法 //有人說這是遞迴,但我覺得一點都不是遞迴,還不到遞迴的程度 TreeView tv = (TreeView)TreeView1; //如果只有一個root node,只要丟index=0的那個進去就好 NavTreeNode(tv.Nodes[0]); //但如果是好幾個,就要用for跑一下迴圈了 for (int i = 0; i < tv.Nodes.Count; i++) NavTreeNode(tv.Nodes[i]); public void NavTreeNode(TreeNode tnode) { Response.Write(tnode.Text); for (int i = 0; i < tnode.ChildNodes.Count; i++) NavTreeNode(tnode.ChildNodes[i]); }
完整原始碼部分.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; public partial class ProjectTreeView : System.Web.UI.Page { DBmssql db1 = new DBmssql(); string url = "ProjectTreeView.aspx"; protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { TreeView1.Nodes.Clear(); } } public string getNodesId(TreeNode tnode) { string tvValue = tnode.Value; string[] words = tvValue.Split(','); string iid; if (words.Length == 2) iid = words[0]; else iid = "new"; return iid; } public string getNodesParentId(TreeNode tnode) { string tvValue = tnode.Value; string[] words = tvValue.Split(','); string parentID; if (words.Length == 2) parentID = words[1]; else parentID = tvValue; return parentID; } public void buildChildNode(ref TreeNode parent, string nodeText, string nodeValue) { parent.ChildNodes.Add(new TreeNode(nodeText, nodeValue)); } public void BuildMainTree() { TreeView1.Nodes.Clear(); string ProjetId = drpProject.SelectedItem.Value; string ProjetName = drpProject.SelectedItem.Text; txtProjectName.Text = ProjetName; System.Data.DataTable dt1 = new System.Data.DataTable(); TreeView1.Nodes.Add(new TreeNode(ProjetName, ProjetId)); TreeNode parent = TreeView1.Nodes[TreeView1.Nodes.Count - 1]; parent.SelectAction = TreeNodeSelectAction.None; dt1 = db1.GetDataTable("SELECT iid,item FROM 範例項目列表 WHERE id='" + ProjetId + "' AND parentId='0' ORDER BY iid"); for (int i = 0; i < dt1.Rows.Count; i++) { string iid = dt1.Rows[i]["iid"].ToString(); string name = dt1.Rows[i]["item"].ToString(); RevTreeView(iid, name, "0", ProjetId, parent); } } public void RevTreeView(string iid, string name, string parentId, string ProjetId, TreeNode parent) { parent.ChildNodes.Add(new TreeNode(name, iid + "," + parentId)); parent = parent.ChildNodes[parent.ChildNodes.Count - 1]; //add child node System.Data.DataTable dt1 = new System.Data.DataTable(); dt1 = db1.GetDataTable("SELECT iid,item FROM 範例項目列表 WHERE id='" + ProjetId + "' AND parentId='" + iid + "' ORDER BY iid"); for (int i = 0; i < dt1.Rows.Count; i++) { parentId = iid; iid = dt1.Rows[i]["iid"].ToString(); name = dt1.Rows[i]["item"].ToString(); RevTreeView(iid, name, parentId, ProjetId, parent); } } protected void TreeView1_SelectedNodeChanged(object sender, EventArgs e) { TreeNode tnode = ((TreeView)sender).SelectedNode; txtID.Text = getNodesId(tnode); txtParent.Text = getNodesParentId(tnode); txtName.Text = tnode.Text; } protected void btnEdit_Click(object sender, EventArgs e) { if (((TreeView)TreeView1).Nodes.Count <= 0) return; if (((TreeView)TreeView1).SelectedNode == null) return; string iid, parent, name; iid = txtID.Text; parent = txtParent.Text; name = txtName.Text; ((TreeView)TreeView1).SelectedNode.Text = name; ((TreeView)TreeView1).SelectedNode.Value = iid + "," + parent; } protected void btnDelete_Click(object sender, EventArgs e) { if (((TreeView)TreeView1).Nodes.Count <= 0) return; if(((TreeView)TreeView1).SelectedNode == null) return; TreeNode tnode = ((TreeView)TreeView1).SelectedNode; string parentID = getNodesParentId(tnode); tnode.Parent.ChildNodes.Remove(tnode); //child txtID.Text = ""; txtParent.Text = ""; txtName.Text = ""; } protected void _btnDelete_Click(object sender, EventArgs e) { if (((TreeView)TreeView1).Nodes.Count <= 0) return; if (((TreeView)TreeView1).SelectedNode == null) return; TreeNode tnode = ((TreeView)TreeView1).SelectedNode; string parentID = getNodesParentId(tnode); if (parentID == "0") ((TreeView)TreeView1).Nodes.Remove(tnode); //root else tnode.Parent.ChildNodes.Remove(tnode); //child txtID.Text = ""; txtParent.Text = ""; txtName.Text = ""; } protected void btnCreate_Click(object sender, EventArgs e) { string iid, parentID, tnText, tnValue; tnText = "新結點"; TreeView tv = (TreeView)TreeView1; TreeNode parent; if (tv.Nodes.Count <= 0) return; if (tv.SelectedNode == null) { //add root node parent = tv.Nodes[tv.Nodes.Count - 1]; parentID = "0"; iid = "new" + parent.ChildNodes.Count.ToString(); tnValue = iid + "," + parentID; parent.ChildNodes.Add(new TreeNode(tnText, tnValue)); parent.ChildNodes[parent.ChildNodes.Count - 1].Selected = true; } else { //add child node parent = tv.SelectedNode; parentID = getNodesParentId(parent); iid = "new" + parent.Parent.ChildNodes.Count.ToString(); tnValue = iid + "," + parentID; parent.Parent.ChildNodes.Add(new TreeNode(tnText, tnValue)); parent.Parent.ChildNodes[parent.Parent.ChildNodes.Count - 1].Selected = true; } TreeView1_SelectedNodeChanged(tv, e); TreeView1.ExpandAll(); } protected void _btnCreate_Click(object sender, EventArgs e) { string iid, parentID, tnText, tnValue; tnText = "新結點"; TreeView tv = (TreeView)TreeView1; TreeNode parent; if (tv.Nodes.Count <= 0 || tv.SelectedNode == null) { //add root node iid = "new" + tv.Nodes.Count.ToString(); parentID = "0"; tnValue = iid + "," + parentID; tv.Nodes.Add(new TreeNode(tnText, tnValue)); tv.Nodes[tv.Nodes.Count - 1].Selected = true; TreeView1_SelectedNodeChanged(tv, e); TreeView1.ExpandAll(); return; } parent = ((TreeView)TreeView1).SelectedNode; parentID = getNodesParentId(parent); if (parentID == "0") { //add root node iid = "new" + tv.Nodes.Count.ToString(); tnValue = iid + "," + parentID; tv.Nodes.Add(new TreeNode(tnText, tnValue)); tv.Nodes[tv.Nodes.Count - 1].Selected = true; } else { //add child node parentID = getNodesId(parent); iid = "new" + parent.Parent.ChildNodes.Count.ToString(); tnValue = iid + "," + parentID; parent.Parent.ChildNodes.Add(new TreeNode(tnText, tnValue)); parent.Parent.ChildNodes[parent.Parent.ChildNodes.Count - 1].Selected = true; } TreeView1_SelectedNodeChanged(tv, e); TreeView1.ExpandAll(); } protected void btnAddNode_Click(object sender, EventArgs e) { TreeView tv = (TreeView)TreeView1; if (tv.Nodes.Count <= 0) return; if (tv.SelectedNode == null) return; TreeNode parent = tv.SelectedNode; string iid = "new" + parent.ChildNodes.Count.ToString(); string parentID = getNodesId(parent); string tnText = "新結點"; string tnValue = iid + "," + parentID; parent.ChildNodes.Add(new TreeNode(tnText, tnValue)); parent.ChildNodes[parent.ChildNodes.Count - 1].Selected = true; TreeView1_SelectedNodeChanged(tv, e); TreeView1.ExpandAll(); } protected void btnPNEdit_Click(object sender, EventArgs e) { TreeView tv = (TreeView)TreeView1; tv.Nodes[tv.Nodes.Count - 1].Text = txtProjectName.Text; } protected void drpProject_Init(object sender, EventArgs e) { System.Data.DataTable dt1 = new System.Data.DataTable(); string drpValue = null; string drpText = null; ((DropDownList)sender).Items.Clear(); ((DropDownList)sender).Items.Add(new ListItem("(請選擇範例)", "")); ((DropDownList)sender).Items.Add(new ListItem("(空範例)", "new")); dt1 = db1.GetDataTable("SELECT id,cname FROM 範例專案列表 ORDER BY cname"); for (int i = 0; i <= dt1.Rows.Count - 1; i++) { drpValue = dt1.Rows[i]["id"].ToString().Trim(); drpText = dt1.Rows[i]["cname"].ToString().Trim(); ((DropDownList)sender).Items.Add(new ListItem(drpText, drpValue)); } } protected void btnLoad_Click(object sender, EventArgs e) { if (((DropDownList)drpProject).SelectedIndex <= 0) return; if (((DropDownList)drpProject).SelectedIndex == 1) { TreeView1.Nodes.Clear(); TreeView1.Nodes.Add(new TreeNode("新範例-專案名稱","new")); txtProjectName.Text = "新範例-專案名稱"; TreeNode parent = TreeView1.Nodes[TreeView1.Nodes.Count - 1]; parent.SelectAction = TreeNodeSelectAction.None; } else BuildMainTree(); TreeView1.ExpandAll(); } protected void SaveNewTreeViewProject() { try { string sqlstr = string.Empty; string ProjectName = txtProjectName.Text; string ProjectId = string.Empty; System.Data.DataTable dt1 = new System.Data.DataTable(); TreeView tv = (TreeView)TreeView1; if (tv.Nodes.Count <= 0) return; TreeNode tnode = tv.Nodes[tv.Nodes.Count - 1]; ProjectName = tnode.Text; //check project name dt1 = db1.GetDataTable("SELECT id FROM 範例專案列表 WHERE cname = '" + ProjectName + "'"); if (dt1.Rows.Count >= 1) { ScriptManager.RegisterClientScriptBlock(UpdatePanel1, typeof(UpdatePanel), "error", "alert('工程專案名稱重複。');", true); return; } //insert project sqlstr = "INSERT INTO 範例專案列表(cname) VALUES('" + ProjectName + "')"; db1.ExecuteCmd(sqlstr); //get project id dt1 = db1.GetDataTable("SELECT id FROM 範例專案列表 WHERE cname = '" + ProjectName + "'"); if (dt1.Rows.Count == 1) ProjectId = dt1.Rows[0][0].ToString(); else { ScriptManager.RegisterClientScriptBlock(UpdatePanel1, typeof(UpdatePanel), "error", "alert('讀取工程專案編號失敗。');", true); return; } for (int i = 0; i < tnode.ChildNodes.Count; i++) RevSaveNewTreeViewProject(tnode.ChildNodes[i], ProjectId, "0"); ScriptManager.RegisterClientScriptBlock(UpdatePanel1, typeof(UpdatePanel), "OK", "alert('新增成功。');//location.href='" + url + "';", true); } catch (Exception ex) { lt.Text = "操作失敗。 " + ex.Message.ToString(); } } public void RevSaveNewTreeViewProject(TreeNode tnode, string ProjectId, string parentID) { string iid = getNodesId(tnode); string name = tnode.Text; string sqlstr = string.Empty; string strDateTime = string.Format("{0:yyyy/MM/dd HH:mm:ss}", DateTime.Now); try { //insert sqlstr = " INSERT INTO 範例項目列表(id, date, item, parentId) "; sqlstr += " VALUES('" + ProjectId + "','" + strDateTime + "','" + name + "','" + parentID + "')"; db1.ExecuteCmd(sqlstr); //get item id System.Data.DataTable dt1 = new System.Data.DataTable(); sqlstr = "SELECT iid FROM 範例項目列表 WHERE date='" + strDateTime + "' AND id='" + ProjectId + "' ORDER BY date,iid DESC"; dt1 = db1.GetDataTable(sqlstr); if (dt1.Rows.Count >= 1) parentID = dt1.Rows[0][0].ToString(); else { ScriptManager.RegisterClientScriptBlock(UpdatePanel1, typeof(UpdatePanel), "error", "alert('讀取parentID失敗。');", true); return; } for (int i = 0; i < tnode.ChildNodes.Count; i++) RevSaveNewTreeViewProject(tnode.ChildNodes[i], ProjectId, parentID); } catch (Exception ex) { lt.Text = "操作失敗。 " + ex.Message.ToString() + " " + sqlstr; } } protected void SaveTreeViewProject() { string sqlstr = string.Empty; try { string ProjectName = txtProjectName.Text; string ProjectId = string.Empty; System.Data.DataTable dt1 = new System.Data.DataTable(); TreeView tv = (TreeView)TreeView1; if (tv.Nodes.Count <= 0) return; TreeNode tnode = tv.Nodes[tv.Nodes.Count - 1]; ProjectName = tnode.Text; ProjectId = tnode.Value; if (ProjectId == "new") SaveNewTreeViewProject(); //check project name sqlstr = "SELECT * FROM 範例專案列表 WHERE cname = '" + ProjectName + "' AND id <> '" + ProjectId + "'"; dt1 = db1.GetDataTable(sqlstr); if (dt1.Rows.Count >= 1) { ScriptManager.RegisterClientScriptBlock(UpdatePanel1, typeof(UpdatePanel), "error", "alert('工程專案名稱重複。');", true); return; } //check project id sqlstr = "SELECT * FROM 範例專案列表 WHERE id = '" + ProjectId + "'"; dt1 = db1.GetDataTable(sqlstr); if (dt1.Rows.Count != 1) { ScriptManager.RegisterClientScriptBlock(UpdatePanel1, typeof(UpdatePanel), "error", "alert('工程專案id錯誤。');", true); return; } //delete removed node sqlstr = "SELECT iid FROM 範例項目列表 WHERE id = '" + ProjectId + "'"; dt1 = db1.GetDataTable(sqlstr); for (int i = 0; i < dt1.Rows.Count; i++) { //if false, delete if (!RevFindTreeNodeId(dt1.Rows[i][0].ToString(), tnode)) { sqlstr = "DELETE FROM 範例項目列表 WHERE iid = '" + dt1.Rows[i][0].ToString() + "'"; db1.GetDataTable(sqlstr); } } //insert project sqlstr = "UPDATE 範例專案列表 SET cname='" + ProjectName + "' WHERE id='" + ProjectId + "'"; db1.ExecuteCmd(sqlstr); for (int i = 0; i < tnode.ChildNodes.Count; i++) RevSaveTreeViewProject(tnode.ChildNodes[i], ProjectId, "0"); ScriptManager.RegisterClientScriptBlock(UpdatePanel1, typeof(UpdatePanel), "error", "alert('儲存成功。');//location.href='" + url + "';", true); } catch (Exception ex) { lt.Text = "操作失敗。 " + ex.Message.ToString() + " " + sqlstr; } } public Boolean RevFindTreeNodeId(string iid, TreeNode tnode) { Boolean rv = false; for (int i = 0; i < tnode.ChildNodes.Count; i++) { if (iid == getNodesId(tnode.ChildNodes[i])) rv = true; else rv = RevFindTreeNodeId(iid, tnode.ChildNodes[i]); if (rv) break; } return rv; } public void RevSaveTreeViewProject(TreeNode tnode, string ProjectId, string parentID) { string iid = getNodesId(tnode); string name = tnode.Text; string sqlstr = string.Empty; string strDateTime = string.Format("{0:yyyy/MM/dd HH:mm:ss}", DateTime.Now); try { if (iid.IndexOf("new") >= 0) { //insert sqlstr = " INSERT INTO 範例項目列表(id, date, item, parentId) "; sqlstr += " VALUES('" + ProjectId + "','" + strDateTime + "','" + name + "','" + parentID + "')"; db1.ExecuteCmd(sqlstr); //get item id System.Data.DataTable dt1 = new System.Data.DataTable(); sqlstr = "SELECT iid FROM 範例項目列表 WHERE date='" + strDateTime + "' AND id='" + ProjectId + "' ORDER BY date,iid DESC"; dt1 = db1.GetDataTable(sqlstr); if (dt1.Rows.Count >= 1) parentID = dt1.Rows[0][0].ToString(); else { ScriptManager.RegisterClientScriptBlock(UpdatePanel1, typeof(UpdatePanel), "error", "alert('讀取parentID失敗。');", true); return; } } else { //update sqlstr = " UPDATE 範例項目列表 SET "; sqlstr += " id='" + ProjectId + "'"; sqlstr += ",item='" + name + "'"; sqlstr += " WHERE iid='" + iid + "'"; db1.ExecuteCmd(sqlstr); //get item id parentID = iid; } for (int i = 0; i < tnode.ChildNodes.Count; i++) RevSaveTreeViewProject(tnode.ChildNodes[i], ProjectId, parentID); } catch (Exception ex) { lt.Text = "操作失敗。 " + ex.Message.ToString() + " " + sqlstr; } } protected void btnSave_Click(object sender, EventArgs e) { SaveTreeViewProject(); drpProject_Init(drpProject, e); } protected void btnSaveNew_Click(object sender, EventArgs e) { SaveNewTreeViewProject(); drpProject_Init(drpProject, e); } }
網頁代碼的部分,因為有隱藏元件,所以還是PO出來給大家參考一下。
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager> <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <table style="width: auto;"> <tr> <td style="width:auto; text-align:center; vertical-align:top; white-space:nowrap; background-color:#CCFFFF;padding:20px;"> <asp:Label ID="Label8" runat="server" Text="Step1. 載入已存範例或空範例"></asp:Label> <br /> <br /> <asp:Label ID="Label7" runat="server" Text="載入已存範例:"></asp:Label> <asp:DropDownList ID="drpProject" runat="server" oninit="drpProject_Init"> </asp:DropDownList> <asp:Button ID="btnLoad0" runat="server" CausesValidation="False" onclick="btnLoad_Click" Text="載入" /> </td> <td style="width:auto; text-align:center; vertical-align:top; white-space:nowrap; background-color:#FFCCCC;padding:20px;"> <asp:Label ID="Label10" runat="server" Text="Step3. 儲存"></asp:Label> <br /> <br /> <asp:Button ID="btnSave" runat="server" CausesValidation="False" onclick="btnSave_Click" Text="儲存範例" /> <asp:Button ID="btnSaveNew" runat="server" Text="存為新範例" onclick="btnSaveNew_Click" CausesValidation="False" /> </td> </tr> <tr style="background-color:#FFFF99"> <td style="text-align:center; vertical-align:top; white-space:nowrap;padding:20px;" colspan="2"> <asp:Label ID="Label9" runat="server" Text="Step2. 編輯樹狀結構"></asp:Label> </td> </tr> <tr style="background-color:#FFFF99"> <td style="width:auto; text-align:center; vertical-align:top; white-space:nowrap;"> <asp:Button ID="btnCreate" runat="server" CausesValidation="False" onclick="btnCreate_Click" Text="新增結點" /> <asp:Button ID="btnDelete" runat="server" CausesValidation="False" onclick="btnDelete_Click" onclientclick="return confirm('確定要刪除嗎?(刪除後無法還原)');" Text="刪除結點" /> <asp:Button ID="btnAddNode" runat="server" CausesValidation="False" onclick="btnAddNode_Click" Text="新增子結點" /> </td> <td style="width:auto; text-align:center; vertical-align:top; white-space:nowrap;"> <asp:Panel ID="Panel2" runat="server" DefaultButton="btnPNEdit"> <asp:Label ID="Label5" runat="server" Text="工程專案名稱:"></asp:Label> <asp:TextBox ID="txtProjectName" runat="server"></asp:TextBox> <asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ControlToValidate="txtProjectName" Display="Dynamic" ErrorMessage="RequiredFieldValidator" ValidationGroup="PNSave">*</asp:RequiredFieldValidator> <asp:Button ID="btnPNEdit" runat="server" onclick="btnPNEdit_Click" Text="修改" ValidationGroup="PNSave" /> </asp:Panel> </td> </tr> <tr style="background-color:#FFFF99"> <td style="width:50%; text-align:center; vertical-align:top; white-space:nowrap;padding:20px;"> <asp:TreeView ID="TreeView1" runat="server" onselectednodechanged="TreeView1_SelectedNodeChanged" ShowLines="True"> <SelectedNodeStyle BackColor="#FF9999" /> </asp:TreeView> </td> <td style="width:50%; text-align:left; vertical-align:top; white-space:nowrap;padding:20px;"> <asp:Panel ID="Panel1" runat="server" DefaultButton="btnEdit"> <fieldset style=" width:300px; text-align:center;"> <legend><img alt="" src="images/comments.png" /> 編輯結點</legend> <br /> <asp:Label ID="Label3" runat="server" Text="父結點" Visible="False"></asp:Label> <asp:TextBox ID="txtParent" runat="server" Width="50px" Visible="False"></asp:TextBox> <asp:TextBox ID="txtID" runat="server" Width="50px" Visible="False"></asp:TextBox> <br /> <br /> <asp:Label ID="Label4" runat="server" Text="結點名稱:"></asp:Label> <asp:TextBox ID="txtName" runat="server"></asp:TextBox> <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="txtName" Display="Dynamic" ErrorMessage="RequiredFieldValidator">*</asp:RequiredFieldValidator> <br /> <br /> <asp:Button ID="btnEdit" runat="server" onclick="btnEdit_Click" Text="修改" /> <br /> <br /> </fieldset></asp:Panel> </td> </tr> </table> <asp:Literal ID="lt" runat="server"></asp:Literal> </ContentTemplate> </asp:UpdatePanel>
網頁長這樣:
文章標籤
全站熱搜
留言列表