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

来源:互联网 发布:电脑背四级单词软件 编辑:程序博客网 时间:2024/06/12 22:31

最近在一个项目中遇到处理树状层次关系的数据,于是就暂时使用了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控件中主要使用了如下的递归处理:

变量

方法

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

这里的移动节点没有使用常见的定义一个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, MessageBoxIcon.Information);
            }

        }


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

原创粉丝点击