实现功能有
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) ); }