目录
最近要做一个配置文件,需要根据xml文件动态生成树控件,看到网上有个大神给出了源代码,自己尝试着实现了一下,基本复现了大神的逻辑,现将复现过程给大家分享一下。
1 控件准备
控件类型 | 控件Name | 操作 |
树控件 | treeView1 | ContextMenuStrip属性设置为:contextMenuStrip1 MouseDoubleClick事件设置为:treeView1_MouseDoubleClick |
右键菜单 | contextMenuStrip1 | 添加子节点:addTreeNode 添加根节点:addRootTreeNode 删除:deleteTreeNode 保存:SaveXml |
状态栏 | StripStatus | 状态提示控件:toolStripStatusLabel1 |
程序运行界面如下:
2 实现源码
2.1 窗体相关
主窗体加载函数
private void Form1_Load(object sender, EventArgs e)
{
doc.Load("TreeXml.xml"); //我是把xml放到debug里面了.你的路径就随便啦.不过这样方便一些.
RecursionTreeControl(doc.DocumentElement, treeView1.Nodes);//将加载完成的XML文件显示在TreeView控件中
treeView1.ExpandAll();//展开TreeView控件中的所有项
}
全局成员变量
XmlDocument doc = new XmlDocument();
StringBuilder sb = new StringBuilder();
//XML每行的内容
private string xmlLine = "";
2.2 xml相关函数
2.2.1 将xml内容显示到树控件上
/// <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);//调用本方法进行递归
}
}
2.2.2 解析函数
这两个函数主要服务于保存xml
//递归遍历节点内容,最关键的函数
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>\n");
}
}
//成生RSS节点的XML文本行
private string GetRSSText(TreeNode node)
{
//根据Node属性生成XML文本
string rssText = "<Node Name=\"" + node.Name + "\" Text=\"" + node.Text + "\" >";
return rssText;
}
2.3 树控件双击编辑事件
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();
}
}
}
2.4 右键菜单相关函数
//添加节点
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\"?>\n");
sb.Append("<Tree>\n");
//遍历根节点
foreach (TreeNode node in treeView1.Nodes)
{
xmlLine = GetRSSText(node);
sb.Append(xmlLine);
//递归遍历节点
parseNode(node, sb);
sb.Append("</Node>\n");
}
sb.Append("</Tree>\n");
StreamWriter sr = new StreamWriter("TreeXmlOut.xml", false, System.Text.Encoding.UTF8);
sr.Write(sb.ToString());
sr.Close();
toolStripStatusLabel1.Text = "保存成功";
}
catch (Exception ex)
{
toolStripStatusLabel1.Text = ex.Message;
}
}
3 软件效果
操作:
- 双击修改项目值
- 右键弹出,右键菜单
- 添加根节点
- 添加子节点
- 删除
- 保存:exe目录下的TreeXmlOut.xml
源码:https://download.csdn.net/download/m1m2m3mmm/12843799
本文也将在下面公众号,同步刊发,欢迎关注: