前段时间,项目((C#)winfrom)中有用到treeview控件,一开始,想到的就是使用XML加载数据源了,看了几天MSDN(以前不太用treeview控件和XML),然后开始写代码,但XML很是复杂,但基本的增删改查还是学的差不多了。
好了,现在把我写的代码先一步一步贴出来。
我先写了一个函数,是实现对Xmldocument文档的调用,便于其他诸如增、删、改、查的对xmldocument文档的调用。
/// <summary>
/// 创建XML函数
/// </summary>
/// <returns></returns>
private XmlDocument GetPath()
{
XmlDocument Xmldoc = new XmlDocument();
string path = AppDomain.CurrentDomain.BaseDirectory + "AreaName.xml";
Xmldoc.Load(path);
return Xmldoc;
}
初始化打开winfrom窗体的时候,加载下面的函数。——查询函数,把XML文档的数据绑定到treeview,生成一颗节点树。
/// <summary>
/// 绑定XML到treeview
/// </summary>
private void AddTreeView()
{
try
{
XmlDocument xmlDoc = GetPath();
//禁止重绘
tree_Area.BeginUpdate();
XmlElement xe = (XmlElement)xmlDoc.SelectSingleNode("root");
//绑定属性节点到treeview
TreeNode root = new TreeNode();
root.Name = xe.GetAttribute("name");
root.Text = xe.GetAttribute("value");
root = GetChildNodes(xe, root);
tree_Area.Nodes.Add(root);
tree_Area.EndUpdate();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
/// <summary>
/// 递归遍历节点
/// </summary>
/// <param name="xe"></param>
/// <param name="upNode"></param>
/// <returns></returns>
private TreeNode GetChildNodes(XmlElement xe, TreeNode upNode)
{
//递归遍历节点
if (xe.HasChildNodes)
{
foreach (XmlNode node in xe.ChildNodes)
{
XmlElement xlt = (XmlElement)node;
TreeNode tn = new TreeNode();
tn.Text = xlt.GetAttribute("name");
tn.Name = xlt.GetAttribute("value");
GetChildNodes(xlt, tn);
upNode.Nodes.Add(tn);
}
}
return upNode;
}
然后是在winfrom界面上添加了2个textbox控件,用于接收来自用户需要添加到treeview控件的数据。
Add——向treeview控件添加数据。
private void InsertNode()
{
TreeNode SelectNode = null;
TreeNode node = null;
XmlDocument Xmldoc = GetPath();
SelectNode = this.tree_Area.SelectedNode;
node = new TreeNode();
node.Text = txt_Nub.Text.Trim();
node.Name = txt_AreaName.Text.Trim();
if (txt_AreaName.Text != "" && txt_Nub.Text != "")
{
if (txt_AreaName.Text == "" && txt_Nub.Text == "")
{
tree_Area.Nodes.Add(node);
}
else
{
TreeNode ttn = new TreeNode();
ttn.Name = txt_Nub.Text;
ttn.Text = txt_Nub.Text;
tree_Area.Nodes.Add(ttn);
}
}
else
{
MessageBox.Show("请选择节点或文本框不能为空!");
}
}
Remove——删除treeview控件的某个Node。
private void DeleteNode()
{
XmlDocument xmlDoc = GetPath();
if (txt_AreaName.Text.Trim() != "" && txt_Nub.Text.Trim() != "")
{
TreeNode selectNode = tree_Area.SelectedNode;
if (selectNode != null)
{
TreeNode parentNode = selectNode.Parent;
if (parentNode == null)
{
//从treeview 的节点集合中删除当前选中的节点
tree_Area.Nodes.Remove(selectNode);
txt_AreaName.Text = "";
txt_Nub.Text = "";
}
else
{
//从父节点的集合中删除当前选中的节点
tree_Area.Nodes.Remove(selectNode);
txt_Nub.Text = "";
txt_AreaName.Text = "";
XmlNode root = xmlDoc.SelectSingleNode("root");
XmlNodeList xnl = xmlDoc.SelectSingleNode("root").ChildNodes;
for (int i = 0; i < xnl.Count; i++)
{
XmlElement xe = (XmlElement)xnl.Item(i);
if (xe.GetAttribute("name") == selectNode.Name)
{
root.RemoveChild(xe);
if (i < xnl.Count)
{
i = i - 1;
}
}
}
}
}
else
{
MessageBox.Show("未选中节点或无法删除父节点!", "提示");
}
}
}
Alter——对treeview控件的数据进行编辑。
private void UpdateNode()
{
if (txt_AreaName.Text.Trim() != "" && txt_Nub.Text.Trim() != "")
{
TreeNode SelectNode = tree_Area.SelectedNode;
SelectNode.Text = txt_AreaName.Text.Trim();
SelectNode.Name = txt_Nub.Text.Trim();
txt_AreaName.Text = SelectNode.Text;
txt_Nub.Text = SelectNode.Name;
txt_AreaName.Text = "";
txt_Nub.Text = "";
}
else
{
MessageBox.Show("请选择节点或文本框不能为空!");
}
}
上面的函数实现了在winfrom窗体上对treeview控件的增、删、改、查,但是还不够,因为做到这一步,也只是实现了在treeview控件上的增删改查,但是前面说过,还需把改动之后的treeview数据保存到XML文档里。
下面的函数就能实现把treeview控件的数据写入XML文档。
首先得定义好XML文档的版本、格式等。
XmlTextWriter tw = null;
/// <summary>
/// 把treeview的节点写入XML文档
/// </summary>
private void AddXml()
{
string fileName = AppDomain.CurrentDomain.BaseDirectory + "AreaName.xml";
tw = new XmlTextWriter(fileName, null);
//设置写入的XML文档格式为缩进
tw.Formatting = Formatting.Indented;
//声明默认版本 1.0
tw.WriteStartDocument();
//当前获取到节点
WriteXML(tree_Area.Nodes);
//关闭打开的元素
tw.WriteEndDocument();
//刷新基础流
tw.Flush();
tw.Close();
}
/// <summary>
/// 递归当前treeview节点写入XML文档
/// </summary>
/// <param name="tc"></param>
public void WriteXML(TreeNodeCollection tc)
{
foreach (TreeNode Node in tc)
{
WriteOneXML(Node);
WriteXML(Node.Nodes);
//关闭使用过的节点
tw.WriteEndElement();
}
}
/// <summary>
/// 布局元素节点和属性节点
/// </summary>
/// <param name="Node">treeview节点</param>
private void WriteOneXML(TreeNode Node)
{
string value = Node.Name;
string name = Node.Text;
//根据treeview的节点来写元素节点
switch (Node.Level)
{
case 0:
tw.WriteStartElement("root");
break;
case 1:
tw.WriteStartElement("province");
break;
case 2:
tw.WriteStartElement("City");
break;
case 3:
tw.WriteStartElement("Piecearea");
break;
case 4:
tw.WriteStartElement("Town");
break;
case 5:
tw.WriteStartElement("Equipmentn");
break;
}
//写属性节点
tw.WriteAttributeString("value", value);
tw.WriteAttributeString("name", name);
//...剩余的属性节点
}
运行后,
写在结尾:以上我是根据自己的项目来写的,但是总体还是实现了:1.读取XML文档,绑定到treeview控件;2.在窗体上对treeview控件的数据进行编辑,然后回传XML文档。
但是,我当前的项目中使用XML作为数据源,在编辑treeview节点之后,回传到XML文档的时候,还有些问题,因为我的XML文档的格式比较复杂点。还有就是有多个地方都使用这个源,所以,当某个地方添加了数据之后,这边还得需要同步,虽然可以使用类的继承方式来实现,但现在的时间不允许了。所以还得使用其他的方法。目前使用的数据源是sqlite,这是一款轻型的数据库。在官方网找了资料看了之后用起来很是方便,如果存储的数据量在10W以内的话,用起来还是不错的,最重要的是,当前一些主流数据库的语法在sqlite上大部分是可以使用的。
我后续还会写一篇关于使用sqlite来作为treeview控件的数据源的文章。欢迎大家留言/发email一起讨论。谢谢! Via cnblogs.com/aehoo/ 2012.02.25