C#如何在treeview控件winform的所有父子节点中搜索文本

Posted

技术标签:

【中文标题】C#如何在treeview控件winform的所有父子节点中搜索文本【英文标题】:C# How to search a text in all parent & child nodes of treeview control winform 【发布时间】:2019-11-06 02:53:48 【问题描述】:

我正在递归搜索所有 treeview 的 父节点和子节点中的文本,但没有按预期工作。

请参阅下面的代码,其中我在父子节点的所有节点中搜索无法正常工作的文本。请指导我需要修复什么。

private void txtSerach_KeyUp(object sender, KeyEventArgs e)
    
        if (e.KeyCode == Keys.Enter)
        
        if (txtSerach.Text.Trim() != "")
        
            if (treeView1.Nodes.Count > 0)
            
            nodefound = false;

            TreeNodeCollection nodes = treeView1.Nodes;
            foreach (TreeNode n in nodes)
            
                if (!nodefound)
                PrintRecursive(n);
                else
                return;
            
            
        
        
    

bool nodefound = false;

private void PrintRecursive(TreeNode treeNode)

    if (treeNode.Text.ToUpper().Contains(txtSerach.Text.ToUpper().ToString()))
    
    treeView1.SelectedNode = treeNode;
    treeView1.SelectedNode.Expand();
    treeView1.Focus();
    nodefound = true;
    return;
    

    foreach (TreeNode tn in treeNode.Nodes)
    
    PrintRecursive(tn);
    

屏幕截图

应在所有父节点和所有嵌套节点中搜索文本,如果找到,则应选择该节点。

谢谢

【问题讨论】:

您认为什么是“正确”,什么不是?我的意思是,请描述您期望的结果与您的代码产生的结果相比。 Is there a method for searching for TreeNode.Text field in TreeView.Nodes collection?的可能重复 【参考方案1】:

试试吧。

        private void txtSerach_KeyUp(object sender, KeyEventArgs e)
        
            if (e.KeyCode == Keys.Enter)
            
                if (txtSearch.Text.Trim() != "")
                
                    if (treeView1.Nodes.Count > 0)
                    
                        TreeNodeCollection nodes = treeView1.Nodes;
                        var selected = PrintRecursive(nodes, txtSearch.Text);
                        treeView1.SelectedNode = selected;
                        treeView1.SelectedNode.Expand();
                        treeView1.Focus();
                    
                
            
        


        private TreeNode PrintRecursive(TreeNodeCollection parents, string txtSearch)
        
            foreach (TreeNode node in parents)
            
                if (node.Nodes != null && node.Nodes.Count > 0)
                
                    var rs = PrintRecursive(node.Nodes, txtSearch);
                    if (rs != null)
                    
                        return rs;
                    
                
                if (node.Text.ToUpper().Contains(txtSearch.ToUpper().ToString()))
                
                    return node;
                
            
            return null;
        

【讨论】:

【参考方案2】:

此代码从树中找到一个键:

    public TreeNode Find(TreeNodeCollection nodes, string key)
    
        key = key.ToUpper();
        Stack<TreeNode> stackNodes = new Stack<TreeNode>();
        foreach (TreeNode item in nodes)
        
            stackNodes.Push(item);
        

        while (stackNodes.Count > 0)
        
            TreeNode currentNode = stackNodes.Pop();
            if (currentNode.Text.ToUpper() == key)
                return currentNode;
            else
                foreach (TreeNode item in currentNode.Nodes)
                
                    stackNodes.Push(item);
                
        

        return null;
    

你可以这样称呼它:

    private void findButton_Click(object sender, EventArgs e)
    
        if (!string.IsNullOrEmpty(keyTextBox.Text.Trim()))
        
            var result = Find(treeView1.Nodes, keyTextBox.Text.Trim());
            if (result != null)
            
                treeView1.SelectedNode = result;
                treeView1.Focus();
            
        
    

【讨论】:

如果 C21 在多个节点中可用,那么应该选择它....怎么可能?【参考方案3】:

试试这个:

      private void txtSerach_KeyUp(object sender, KeyEventArgs e)
      
         if (e.KeyCode == Keys.Enter)
         
            var searchFor = txtSerach.Text.Trim().ToUpper();
            if (searchFor != "")
            
               if (treeView1.Nodes.Count > 0)
               
                  if (SearchRecursive(treeView1.Nodes, searchFor))
                  
                     treeView1.SelectedNode.Expand();
                     treeView1.Focus();
                  
               
            
         
      

      private bool SearchRecursive(IEnumerable nodes, string searchFor)
      
         foreach (TreeNode node in nodes)
         
            if (node.Text.ToUpper().Contains(searchFor))
            
               treeView1.SelectedNode = node;
               return true;
            

            if (SearchRecursive(node.Nodes, searchFor))
               return true;
         

         return false;
      

【讨论】:

感谢您的代码,它正在工作,但是当我搜索存在于多个父节点下的国内文本时,它只选择一个子节点,但在其他没有被选中的节点中也找到了文本。 ....怎么办? 第一个文本应该与所有父节点进行比较,如果匹配,那么这些父节点将被选中。如果找到,还搜索所有父节点的所有子节点,然后将选择该节点。 我不相信 TreeView 控件支持多个选定节点。您可以在查找/查找下一个样式中实现它,让您按照自己的方式处理所有匹配项。

以上是关于C#如何在treeview控件winform的所有父子节点中搜索文本的主要内容,如果未能解决你的问题,请参考以下文章

C# winform treeview 节点展开状态的图标设置

C# winform如何计算控件上文字的实际宽度(像素)

c#、winform、treeview 部分节点加图片

C# winform 编程 自定义combobx控件,将treeview控件嵌入combobox中

如何在vs 2005 中将mdi父窗口分割成两部分,一边treeview,一边显示子窗口(c# winform)

c#的winform TreeView控件中,展开不同的节点,右边显示不同的内容,该怎么做啊,请帮帮我吧,谢谢~