none
winfrom中Treeview节点查找? RRS feed

  • 问题

  • 我想在WINFORM程序中查找treeview中的节点,可以实现“查找下一处”的功能,这个怎么实现?谢谢
    努力+方法=成功
    2009年8月14日 9:52

答案

  • 补充一下,查找节点可以这样:
    private  TreeNode FindNode( TreeNode parent,  string value )

        {

            
    if ( parent  ==   null  )  return   null ;

            
    if ( parent.Text  == value )  return parent;

     

            TreeNode result
    =   null ;

            
    foreach ( TreeNode tn  in parent.Nodes )

            {

                result
    =  FindNode( tn, value );

                
    if ( result !=   null  )  break ;

            }

            
    return result;

        }


    周雪峰
    2009年8月14日 10:30
    版主
  • 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.Text.RegularExpressions;
    
    namespace WindowsFormsApplication5
    {
        /// <summary>
        /// 标题:TreeView 递归查找节点
        /// 作者:X.X.Y
        /// 日期:2009-06-17
        /// </summary>
        public partial class Form2 : Form
        {
            public Form2()
            {
                InitializeComponent();
            }
    
            private void Form2_Load(object sender, EventArgs e)
            {
                this.InitTreeView();
            }
    
            private void InitTreeView()
            {
                this.treeView1.Nodes.Add("Node1");
                this.treeView1.Nodes.Add("Node2");
                this.treeView1.Nodes.Add("Node3");
    
                this.treeView1.Nodes[0].Nodes.Add("Node1");
                this.treeView1.Nodes[0].Nodes.Add("Node2");
                this.treeView1.Nodes[0].Nodes.Add("Node1");
    
                this.treeView1.Nodes[1].Nodes.Add("Node1");
                this.treeView1.Nodes[1].Nodes.Add("Node2");
                this.treeView1.Nodes[1].Nodes.Add("Node3");
    
                this.treeView1.Nodes[2].Nodes.Add("Node1");
                this.treeView1.Nodes[2].Nodes.Add("Node2");
                this.treeView1.Nodes[2].Nodes.Add("Node3");
    
                this.treeView1.ExpandAll();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                if (this.textBox1.Text == "") return;
    
                // 条件改变从第一个节点开始查
                if (fCurQuery != this.textBox1.Text)
                {
                    fCurQuery = this.textBox1.Text;
                    fFindList.Clear();
                }
    
                // 查找与 TextBox1.Text 文本相近的节点
                // 第一点击查询第一个,第一次点击查找第二个...
                TreeNode fReturnValue = null;
                foreach (TreeNode fCurNode in treeView1.Nodes)
                {
                    fReturnValue = this.FindNode(fCurNode, textBox1.Text);
                    if (fReturnValue != null) break;
                }
    
                this.treeView1.SelectedNode = fReturnValue;
    
                // 如果已查到最后或未找到合适的节点,下次点击从第一个节点开始查找
                if (fReturnValue == null)
                    this.fFindList.Clear();
            }
    
            private String fCurQuery = "";
            private List<TreeNode> fFindList = new List<TreeNode>();
    
            private TreeNode FindNode(TreeNode fParent, string fFindText)
            {
                if (fParent == null) return null;
    
                if (Regex.IsMatch(fParent.Text, fFindText, RegexOptions.IgnoreCase) &&
                    !this.fFindList.Contains(fParent))
                {
                    // 匹配 Text 相近的的节点,并且不是已查过的节点
                    this.fFindList.Add(fParent);
                    return fParent;
                }
    
                if (fParent.Text == fFindText) return fParent;
    
                TreeNode fReturnNode = null;
                foreach (TreeNode fCurNode in fParent.Nodes)
                {
                    fReturnNode = FindNode(fCurNode, fFindText);
                    if (fReturnNode != null) break;
                }
    
                return fReturnNode;
            }
        }
    }
    

    知识改变命运,奋斗成就人生!
    2009年8月17日 4:27
    版主

全部回复

    • 第一次查找, 遍历节点,匹配满足条件的节点,选中这个节点,并把这个节点记录到一个数组中,停止查找
    • 第二次查找, 遍历节点,匹配满足条件的节点并且判断是否在数组中是否存在这个节点,如果不存在选中这个节点,并把这个节点记录到一个数组中,停止查找
    • 以此类推 ...

    知识改变命运,奋斗成就人生!
    2009年8月14日 10:02
    版主
  • 补充一下,查找节点可以这样:
    private  TreeNode FindNode( TreeNode parent,  string value )

        {

            
    if ( parent  ==   null  )  return   null ;

            
    if ( parent.Text  == value )  return parent;

     

            TreeNode result
    =   null ;

            
    foreach ( TreeNode tn  in parent.Nodes )

            {

                result
    =  FindNode( tn, value );

                
    if ( result !=   null  )  break ;

            }

            
    return result;

        }


    周雪峰
    2009年8月14日 10:30
    版主
  • 补充一下,查找节点可以这样
    private  TreeNode FindNode( TreeNode parent,  string value )

        {

            
    if ( parent  ==   null  )  return   null ;

            
    if ( parent.Text  == value )  return parent;

     

            TreeNode result
    =   null ;

            
    foreach ( TreeNode tn  in parent.Nodes )

            {

                result
    =  FindNode( tn, value );

                
    if ( result !=   null  )  break ;

            }

            
    return result;

        }


    周雪峰
    2009年8月14日 10:31
    版主
  • 上面这个每次只能找大到第一个满足条件的节点,不能实现"查找下一处"的效果,有没有别的办法呀?
    努力+方法=成功
    2009年8月17日 0:44
  • 你可以改造一下,不要返回找到的节点,直接把这个节点保存在数组中,这样第一次查找的时候就可以获取所有的符合条件的节点了,以后每点击一次“下一个”按钮,就选中数组中的一个节点:

    private TreeNode[] foundNodes=new TreeNode[treeView1.Nodes.Count];
    private int index=0;
    private  void FindNodes( TreeNode parent,  string value )
    
        {
    
            
    
             if ( parent.Text  == value )  
                    fountdNodes[index++]=parent;
    
            
    
             foreach ( TreeNode tn  in parent.Nodes )
            {
                 FindNodes( tn, value );           
            }
           
        } 




    周雪峰
    2009年8月17日 4:17
    版主
  • 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.Text.RegularExpressions;
    
    namespace WindowsFormsApplication5
    {
        /// <summary>
        /// 标题:TreeView 递归查找节点
        /// 作者:X.X.Y
        /// 日期:2009-06-17
        /// </summary>
        public partial class Form2 : Form
        {
            public Form2()
            {
                InitializeComponent();
            }
    
            private void Form2_Load(object sender, EventArgs e)
            {
                this.InitTreeView();
            }
    
            private void InitTreeView()
            {
                this.treeView1.Nodes.Add("Node1");
                this.treeView1.Nodes.Add("Node2");
                this.treeView1.Nodes.Add("Node3");
    
                this.treeView1.Nodes[0].Nodes.Add("Node1");
                this.treeView1.Nodes[0].Nodes.Add("Node2");
                this.treeView1.Nodes[0].Nodes.Add("Node1");
    
                this.treeView1.Nodes[1].Nodes.Add("Node1");
                this.treeView1.Nodes[1].Nodes.Add("Node2");
                this.treeView1.Nodes[1].Nodes.Add("Node3");
    
                this.treeView1.Nodes[2].Nodes.Add("Node1");
                this.treeView1.Nodes[2].Nodes.Add("Node2");
                this.treeView1.Nodes[2].Nodes.Add("Node3");
    
                this.treeView1.ExpandAll();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                if (this.textBox1.Text == "") return;
    
                // 条件改变从第一个节点开始查
                if (fCurQuery != this.textBox1.Text)
                {
                    fCurQuery = this.textBox1.Text;
                    fFindList.Clear();
                }
    
                // 查找与 TextBox1.Text 文本相近的节点
                // 第一点击查询第一个,第一次点击查找第二个...
                TreeNode fReturnValue = null;
                foreach (TreeNode fCurNode in treeView1.Nodes)
                {
                    fReturnValue = this.FindNode(fCurNode, textBox1.Text);
                    if (fReturnValue != null) break;
                }
    
                this.treeView1.SelectedNode = fReturnValue;
    
                // 如果已查到最后或未找到合适的节点,下次点击从第一个节点开始查找
                if (fReturnValue == null)
                    this.fFindList.Clear();
            }
    
            private String fCurQuery = "";
            private List<TreeNode> fFindList = new List<TreeNode>();
    
            private TreeNode FindNode(TreeNode fParent, string fFindText)
            {
                if (fParent == null) return null;
    
                if (Regex.IsMatch(fParent.Text, fFindText, RegexOptions.IgnoreCase) &&
                    !this.fFindList.Contains(fParent))
                {
                    // 匹配 Text 相近的的节点,并且不是已查过的节点
                    this.fFindList.Add(fParent);
                    return fParent;
                }
    
                if (fParent.Text == fFindText) return fParent;
    
                TreeNode fReturnNode = null;
                foreach (TreeNode fCurNode in fParent.Nodes)
                {
                    fReturnNode = FindNode(fCurNode, fFindText);
                    if (fReturnNode != null) break;
                }
    
                return fReturnNode;
            }
        }
    }
    

    知识改变命运,奋斗成就人生!
    2009年8月17日 4:27
    版主
  • 你好,

    看了X.X.Y的建议后:
    • 第一次查找, 遍历节点,匹配满足条件的节点,选中这个节点,并把这个节点记录到一个数组中,停止查找
    • 第二次查找, 遍历节点,匹配满足条件的节点并且判断是否在数组中是否存在这个节点,如果不存在选中这个节点,并把这个节点记录到一个数组中,停止查找,这就是下一个节点,如果没找到,就是没有,如果找到,而且没有存在在数组中,也就是不是以前找到的重复节点。
    • 以此类推 ...
    自己去实现这个逻辑,在实现时有问题来和我们讨论。

    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    2009年8月17日 8:40
    版主