c#TreeList与Xml操作结合

更新时间:2023-04-24 07:10:01 阅读量: 实用文档 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

Visual C#2005中的TreeView控件的使用

分类: Visual C# 20052007-08-09 17:253085人阅读评论(9)收藏举报

目录(?)[+]

最近在一个项目中遇到处理树状层次关系的数据,于是就暂时使用了TreeView来实现,我把其中的主要功能提了出来做成了一个Demo程序,在这里和大家分享,希望各位多多指教。下面就是实现的主要功能以及源码下载。

读取XML文件中的树状结构数据,并用TreeView控件呈现 在相同层级中前后/上下移动节点

删除指定值的节点

把TreeView的节点存储到XML文件中 开发环境:Windows XP SP2, Visual Studio 2005 with SP1

XML数据的组织结构

我的XML数据结构如下所示: <?xml version="1.0" encoding="utf-8"?> <TestTreeView>

<TestNode nodeText="Test1" nodeValue="a" />

<TestNode nodeText="Test2" nodeValue="b">

<TestNode nodeText="Test3" nodeValue="c">

<TestNode nodeText="Test4" nodeValue="d" />

<TestNode nodeText="Test5" nodeValue="e" />

</TestNode>

<TestNode nodeText="Test6" nodeValue="f" />

</TestNode>

<TestNode nodeText="Test7" nodeValue="c" />

</TestTreeView>

其中"nodeText"为在

TreeView中显示的节点文本,"nodeValue"为该节

点实际存储的值,而" a,b,c,d,e,f "为预定义的6个测试值 用TreeView控件呈现XML数据 把上述的XML文件的数据呈现到TreeView控件中主要使用了如下的递归处理:

#region 变量

private bool enabled = false;

private string strXmlPath = null;

private XmlDocument xmlDoc = null;

#endregion

#region 方法

/// <summary>

/// 根据XML文件加载树节点

/// </summary>

/// <param name="xmlPath">要加载的XML文件路径</param>

private void LoadTreeNodes(string xmlPath)

{

this.xmlDoc = new XmlDocument();

try

{

this.xmlDoc.Load(xmlPath);

XmlNodeList nodes = this.xmlDoc.SelectNodes("TestTreeView/TestNode");

this.treeMain.BeginUpdate();

this.treeMain.Nodes.Clear();

this.ConvertXmlNodeToTreeNode(nodes, this.treeMain.Nodes);

this.treeMain.EndUpdate();

}

catch (Exception ex)

{ MessageBox.Show("程序发生错误:" + ex.Message,

"异常", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void ConvertXmlNodeToTreeNode(XmlNodeList

xmlNodes, TreeNodeCollection treeNodes) { foreach (XmlNode xmlNode in xmlNodes)

{

string nodeText = xmlNode.Attributes["nodeText"].Value;

string nodeValue = xmlNode.Attributes["nodeValue"].Value;

TreeNode newTreeNode = new TreeNode(nodeText);

newTreeNode.Tag = nodeValue;

if (xmlNode.HasChildNodes)

{

this.ConvertXmlNodeToTreeNode(xmlNode.ChildNodes, newTreeNode.Nodes);

}

treeNodes.Add(newTreeNode);

}

}

#endregion

在相同层级中前后/上下移动节点

这里的移动节点没有使用常见的定义一个Temp变量来存储临时数据,然后把要移动的2个数据交换位置。以“上移”为例,先把要移动的节点删除,再在该节点的前一个节点的位置插入该节点,在删除前把该节点存储在一个临时变量中,而“下移”则类似,下面是主要的代码:

// 在同级中上移当前节点

private void btnMoveUp_Click(object sender, EventArgs e)

{

TreeNode current = this.treeMain.SelectedNode;

TreeNode temp = null;

if (current != null)

{

temp = current;

TreeNode prev

= current.PrevNode; if (current.Parent != null) { TreeNode parent = current.Parent; parent.Nodes.Remove(current); parent.Nodes.Insert(prev.Index, temp); } else { this.treeMain.Nodes.Remove(current); this.treeMain.Nodes.Insert(prev.Index, temp); } this.treeMain.SelectedNode = temp; } }

// 在同级中下移当前节点

private void btnMoveDown_Click(object sender, EventArgs e)

{

TreeNode current = this.treeMain.SelectedNode;

if (current != null)

{

TreeNode next = current.NextNode;

if (next != null)

{

TreeNode temp = next;

if (current.Parent != null)

{

TreeNode parent = current.Parent;

parent.Nodes.Remove(next);

parent.Nodes.Insert(current.Index, temp);

}

else

{

this.treeMain.Nodes.Remove(next);

this.treeMain.Nodes.Insert(current.Index, temp);

}

this.treeMain.SelectedNode = temp;

this.treeMain.SelectedNode = current;

}

}

} 删除指定值的节点 TreeView节点实际存储的值保存在TreeNode.Tag中,选择要删除的值,然后搜索定位所有节点,最后删除这些节点,重点是遍历所有TreeView的节点搜索具有该值的节点,下面是主要代码:

// 定位指定值的节点,其中listNodesLocated是一个ListBox控件 // 列出所有定位到的节点的名称 private void LocateNodeWithValue(TreeNodeCollection nodes, string nodeValue) { foreach (TreeNode node in nodes)

{

if (node.Tag.ToString() == nodeValue)

{

this.listNodesLocated.Items.Add(node.Text);

}

if (node.Nodes.Count > 0)

{

this.LocateNodeWithValue(node.Nodes, nodeValue);

}

}

}

// 删除上述方法定位到的节点

private void DeleteNode(TreeNodeCollection nodes, string valueToDelete)

{

foreach (TreeNode node in nodes)

{

if (node.Tag.ToString() == valueToDelete)

{

nodes.Remove(node);

this.listNodesLocated.Items.Remove(node.Text);

}

else if (node.Nodes.Count > 0)

{

this.DeleteNode(node.Nodes, valueToDelete);

} } } 保存TreeView的节点到XML文件中 把编辑后的TreeView

中的TreeNode类型的节点转换成XmlNode类型节点保存到XML文件中,该XML文件就是最初选择加载的XML文件,在保存之前要先删除XML

中TestTreeView根节点下的所有子节点,主要方法如下:

// 保存主方法

private void SaveTreeNodes(string filePath)

{

if (this.xmlDoc != null)

{

XmlNode root = this.xmlDoc.SelectSingleNode("TestTreeView");

// 删除根节点下的所有原有节点

root.RemoveAll();

this.ConvertTreeNodesToXmlNodes(this.treeMain.Nodes, root);

this.xmlDoc.Save(this.strXmlPath);

MessageBox.Show("保存成功!", "信息", MessageBoxButtons.OK, rmation); }

}

// 把TreeNode转换成对应的XmlNode

private void ConvertTreeNodesToXmlNodes(TreeNodeCollection treeNodes, XmlNode xmlNode) {

XmlDocument doc = xmlNode.OwnerDocument;

foreach (TreeNode treeNode in treeNodes)

{

XmlNode newElement = null;

XmlAttribute attrValue = null;

newElement = doc.CreateNode(XmlNodeType.Element, "TestNode", "");

// Set "nodeText"

attrValue = doc.CreateAttribute("nodeText");

attrValue.Value = treeNode.Text;

newElement.Attributes.Append(attrValue); // Set "nodeValue" attrValue = doc.CreateAttribute("nodeValue"); attrValue.Value = treeNode.Tag.ToString(); newElement.Attributes.Append(attrValue);

xmlNode.AppendChild(newElement);

if (treeNode.Nodes.Count > 0)

{

this.ConvertTreeNodesToXmlNodes(treeNode.Nodes, newElement);

}

}

}

这个Demo中的有些方法还有待改善,希望大家多给意见!

这是本人的第一篇Blog文章,从今天起我要坚持写一些东西,把在工作中用到的方法以及问题整理出来,和大家分享,借此机会来巩固自己的所学的知识,也希望能交到很多志同道合的朋友!谢谢

本文来源:https://www.bwwdw.com/article/0kxq.html

Top