實現功能有
1.根據Xml生成TreeView
2.雙擊修改節點
3.右鍵添加子節點或添加要節點
4.右鍵刪除當前選擇的節點
5.將修改后的TreeView重新生成Xml文檔
其實這個主要是實現 了Xml生成TreeView,然后再根據TreeView生成Xml的過程
對我們操作這方面實現有很大的幫助
下面一起來看看我的界面吧
下面咱們一步一步來實現一下吧,
先來看看我的Xml文檔結構
<?xml version="1.0" encoding="UTF-8"?> <Tree> <Node Name="1" Text="去查網" > <Node Name="2" Text="技術部" ></Node> <Node Name="" Text="新建子節點" ></Node> </Node> <Node Name="3" Text="cckan" > <Node Name="4" Text="開發部" ></Node> </Node> <Node Name="5" Text="51.la" > <Node Name="7" Text="銷售部fdf" > <Node Name="" Text="新建子節點" ></Node> <Node Name="" Text="新建子節點" > <Node Name="" Text="新建子節點" ></Node> <Node Name="" Text="新建子節點fdf" ></Node> <Node Name="" Text="新建子節點fdfd" ></Node> </Node> </Node> <Node Name="8" Text="操作部fdf" > <Node Name="" Text="新建子節點" ></Node> </Node> <Node Name="9" Text="客服部fdf" ></Node> <Node Name="10" Text="財務部" ></Node> </Node> <Node Name="" Text="新建根節點" > <Node Name="" Text="新建子節點" ></Node> <Node Name="" Text="新建子節點" ></Node> <Node Name="" Text="新建子節點" ></Node> <Node Name="" Text="新建子節點" ></Node> </Node> <Node Name="" Text="新建根節點" > <Node Name="" Text="新建子節點" ></Node> </Node> <Node Name="" Text="新建根節點" ></Node> </Tree>
很簡單吧,
下面來看看是怎么生成TreeView的
XmlDocument doc = new XmlDocument(); StringBuilder sb = new StringBuilder(); //XML每行的內容 private string xmlLine = ""; //加載 private void Form1_Load(object sender, EventArgs e) { doc.Load("TreeXml.xml"); //我是把xml放到debug里面了.你的路徑就隨便啦.不過這樣方便一些. RecursionTreeControl(doc.DocumentElement, treeView1.Nodes);//將加載完成的XML文件顯示在TreeView控件中 treeView1.ExpandAll();//展開TreeView控件中的所有項 } /// <summary> /// RecursionTreeControl:表示將XML文件的內容顯示在TreeView控件中 /// </summary> /// <param name="xmlNode">將要加載的XML文件中的節點元素</param> /// <param name="nodes">將要加載的XML文件中的節點集合</param> private void RecursionTreeControl(XmlNode xmlNode, TreeNodeCollection nodes) { foreach (XmlNode node in xmlNode.ChildNodes)//循環遍歷當前元素的子元素集合 { TreeNode new_child = new TreeNode();//定義一個TreeNode節點對象 new_child.Name = node.Attributes["Name"].Value; new_child.Text = node.Attributes["Text"].Value; nodes.Add(new_child);//向當前TreeNodeCollection集合中添加當前節點 RecursionTreeControl(node, new_child.Nodes);//調用本方法進行遞歸 } }
用的是一個遞歸的方式生成的,
大家看看就明白了
下面是刪除,修改和添加節點的代碼
//雙擊時修改 private void treeView1_MouseDoubleClick(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { Point ClickPoint = new Point(e.X, e.Y); TreeNode CurrentNode = treeView1.GetNodeAt(ClickPoint); if (CurrentNode != null)//判斷你點的是不是一個節點 { treeView1.SelectedNode = CurrentNode;//選中這個節點 treeView1.LabelEdit = true; treeView1.SelectedNode.BeginEdit(); } } } //添加節點 private void addTreeNode_Click(object sender, EventArgs e) { try { treeView1.SelectedNode.Nodes.Add("新建子節點"); toolStripStatusLabel1.Text = "新建子節點"; } catch (Exception ex) { toolStripStatusLabel1.Text = ex.Message; } } //刪除節點 private void deleteTreeNode_Click(object sender, EventArgs e) { try { treeView1.SelectedNode.Remove(); } catch (Exception ex) { toolStripStatusLabel1.Text = ex.Message; } } //新建根節點 private void addRootTreeNode_Click(object sender, EventArgs e) { try { treeView1.Nodes.Add("新建根節點"); toolStripStatusLabel1.Text = "新建根節點成功"; } catch (Exception ex) { toolStripStatusLabel1.Text = ex.Message; } }
下面就是把修改和刪除之后的TreeView重新保存成Xml文檔了
一起來看看代碼吧
//保存 private void SaveXml_Click(object sender, EventArgs e) { try { //寫文件頭部內容 //下面是生成RSS的OPML文件 sb.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); sb.Append("<Tree>"); //遍歷根節點 foreach (TreeNode node in treeView1.Nodes) { xmlLine = GetRSSText(node); sb.Append(xmlLine); //遞歸遍歷節點 parseNode(node, sb); sb.Append("</Node>"); } sb.Append("</Tree>"); StreamWriter sr = new StreamWriter("TreeXml.xml", false, System.Text.Encoding.UTF8); sr.Write(sb.ToString()); sr.Close(); toolStripStatusLabel1.Text = "保存成功"; } catch (Exception ex) { toolStripStatusLabel1.Text = ex.Message; } } //遞歸遍歷節點內容,最關鍵的函數 private void parseNode(TreeNode tn, StringBuilder sb) { IEnumerator ie = tn.Nodes.GetEnumerator(); while (ie.MoveNext()) { TreeNode ctn = (TreeNode)ie.Current; xmlLine = GetRSSText(ctn); sb.Append(xmlLine); //如果還有子節點則繼續遍歷 if (ctn.Nodes.Count > 0) { parseNode(ctn, sb); } sb.Append("</Node>"); } } //成生RSS節點的XML文本行 private string GetRSSText(TreeNode node) { //根據Node屬性生成XML文本 string rssText = "<Node Name=\"" + node.Name + "\" Text=\"" + node.Text + "\" >"; return rssText; }
好了全部代碼貼一下大家看看吧
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Xml; using System.Collections; using System.IO; namespace TreeLoadXml { public partial class Form1 : Form { public Form1() { InitializeComponent(); } XmlDocument doc = new XmlDocument(); StringBuilder sb = new StringBuilder(); //XML每行的內容 private string xmlLine = ""; //加載 private void Form1_Load(object sender, EventArgs e) { doc.Load("TreeXml.xml"); //我是把xml放到debug里面了.你的路徑就隨便啦.不過這樣方便一些. RecursionTreeControl(doc.DocumentElement, treeView1.Nodes);//將加載完成的XML文件顯示在TreeView控件中 treeView1.ExpandAll();//展開TreeView控件中的所有項 } /// <summary> /// RecursionTreeControl:表示將XML文件的內容顯示在TreeView控件中 /// </summary> /// <param name="xmlNode">將要加載的XML文件中的節點元素</param> /// <param name="nodes">將要加載的XML文件中的節點集合</param> private void RecursionTreeControl(XmlNode xmlNode, TreeNodeCollection nodes) { foreach (XmlNode node in xmlNode.ChildNodes)//循環遍歷當前元素的子元素集合 { TreeNode new_child = new TreeNode();//定義一個TreeNode節點對象 new_child.Name = node.Attributes["Name"].Value; new_child.Text = node.Attributes["Text"].Value; nodes.Add(new_child);//向當前TreeNodeCollection集合中添加當前節點 RecursionTreeControl(node, new_child.Nodes);//調用本方法進行遞歸 } } //雙擊時修改 private void treeView1_MouseDoubleClick(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { Point ClickPoint = new Point(e.X, e.Y); TreeNode CurrentNode = treeView1.GetNodeAt(ClickPoint); if (CurrentNode != null)//判斷你點的是不是一個節點 { treeView1.SelectedNode = CurrentNode;//選中這個節點 treeView1.LabelEdit = true; treeView1.SelectedNode.BeginEdit(); } } } //遞歸遍歷節點內容,最關鍵的函數 private void parseNode(TreeNode tn, StringBuilder sb) { IEnumerator ie = tn.Nodes.GetEnumerator(); while (ie.MoveNext()) { TreeNode ctn = (TreeNode)ie.Current; xmlLine = GetRSSText(ctn); sb.Append(xmlLine); //如果還有子節點則繼續遍歷 if (ctn.Nodes.Count > 0) { parseNode(ctn, sb); } sb.Append("</Node>"); } } //成生RSS節點的XML文本行 private string GetRSSText(TreeNode node) { //根據Node屬性生成XML文本 string rssText = "<Node Name=\"" + node.Name + "\" Text=\"" + node.Text + "\" >"; return rssText; } //添加節點 private void addTreeNode_Click(object sender, EventArgs e) { try { treeView1.SelectedNode.Nodes.Add("新建子節點"); toolStripStatusLabel1.Text = "新建子節點"; } catch (Exception ex) { toolStripStatusLabel1.Text = ex.Message; } } //刪除節點 private void deleteTreeNode_Click(object sender, EventArgs e) { try { treeView1.SelectedNode.Remove(); } catch (Exception ex) { toolStripStatusLabel1.Text = ex.Message; } } private void addRootTreeNode_Click(object sender, EventArgs e) { try { treeView1.Nodes.Add("新建根節點"); toolStripStatusLabel1.Text = "新建根節點成功"; } catch (Exception ex) { toolStripStatusLabel1.Text = ex.Message; } } //保存 private void SaveXml_Click(object sender, EventArgs e) { try { //寫文件頭部內容 //下面是生成RSS的OPML文件 sb.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); sb.Append("<Tree>"); //遍歷根節點 foreach (TreeNode node in treeView1.Nodes) { xmlLine = GetRSSText(node); sb.Append(xmlLine); //遞歸遍歷節點 parseNode(node, sb); sb.Append("</Node>"); } sb.Append("</Tree>"); StreamWriter sr = new StreamWriter("TreeXml.xml", false, System.Text.Encoding.UTF8); sr.Write(sb.ToString()); sr.Close(); toolStripStatusLabel1.Text = "保存成功"; } catch (Exception ex) { toolStripStatusLabel1.Text = ex.Message; } } } }
對於生成樹的部分其實還有一種Linq的實現方式如下
private void SaveToXml() { XDeclaration dec = new XDeclaration("1.0", "utf-8", "yes"); XDocument xml = new XDocument(dec); XElement root = new XElement("Tree"); foreach (TreeNode node in treeView1.Nodes) { XElement e = CreateElements(node); root.Add(e); } xml.Add(root); xml.Save("TreeXml.xml"); } private XElement CreateElements(TreeNode node) { XElement root = CreateElement(node); foreach (TreeNode n in node.Nodes) { XElement e = CreateElements(n); root.Add(e); } return root; } private XElement CreateElement(TreeNode node) { return new XElement("Node", new XAttribute("Name", node.Name), new XAttribute("Text", node.Text) ); }
