2012-07-17 38 views
8

Esta función solo busca primer nodo en treeview, que contiene SearchText.TreeView search

private TreeNode SearchNode(string SearchText,TreeNode StartNode) 
    { 
     TreeNode node=null; 
     while (StartNode!= null) 
     { 
      if (StartNode.Text.ToLower().Contains(SearchText.ToLower())) 
      { 
       node = StartNode; 
       break; 
      }; 
      if (StartNode.Nodes.Count != 0) 
      { 
       node=SearchNode(SearchText, StartNode.Nodes[0]);//Recursive Search 
       if (node != null) 
       { 
        break; 
       }; 
      }; 
      StartNode = StartNode.NextNode; 
     }; 
     return node; 
    } 


    private void button1_Click(object sender, EventArgs e) 
    { 
     string SearchText = this.textBox1.Text; 
     if (SearchText == "") 
     { 
      return; 
     }; 
     TreeNode SelectedNode = SearchNode(SearchText, treeView1.Nodes[0]); 
     if (SelectedNode != null) 
     { 
      this.treeView1.SelectedNode = SelectedNode; 
      this.treeView1.SelectedNode.Expand(); 
      this.treeView1.Select(); 
     }; 
    } 

¿Cómo debo cambiarlo, por lo que la función será capaz de encontrar no sólo el primer nodo, pero todos ellos, cada vez que hago clic en el botón 1, que se encuentra pegado nodo hasta el final, y luego comienza desde el principio Así que no debería buscar desde TreeView1.Nodes [0], sino desde TreeView1.SelectedNode ...

+0

¿Es esta WinForms o ASP.Net? En realidad, hay dos partes en esta pregunta: encontrar los nodos y luego mostrarlos. Sospecho que es por eso que el autor creó la función: solo devuelve un nodo para expandir el árbol a ese único nodo. – dash

+0

Esto es WinForms. No necesito mostrar todos los nodos al mismo tiempo, necesito seleccionar nodos por rotación –

Respuesta

13

Algo como lo siguiente debería estar bien para agregar al código de su Formulario.

private List<TreeNode> CurrentNodeMatches = new List<TreeNode>(); 

    private int LastNodeIndex = 0; 

    private string LastSearchText; 


    private void button1_Click(object sender, EventArgs e) 
    { 


     string searchText = this.textBox1.Text; 
     if (String.IsNullOrEmpty(searchText)) 
     { 
      return; 
     }; 


     if (LastSearchText != searchText) 
     { 
      //It's a new Search 
      CurrentNodeMatches.Clear(); 
      LastSearchText = searchText; 
      LastNodeIndex = 0; 
      SearchNodes(searchText, treeView1.Nodes[0]); 
     } 

     if (LastNodeIndex >= 0 && CurrentNodeMatches.Count > 0 && LastNodeIndex < CurrentNodeMatches.Count) 
     { 
      TreeNode selectedNode = CurrentNodeMatches[LastNodeIndex]; 
      LastNodeIndex++; 
      this.treeView1.SelectedNode = selectedNode; 
      this.treeView1.SelectedNode.Expand(); 
      this.treeView1.Select(); 

     } 
    } 

    private void SearchNodes(string SearchText, TreeNode StartNode) 
    { 
     TreeNode node = null; 
     while (StartNode != null) 
     { 
      if (StartNode.Text.ToLower().Contains(SearchText.ToLower())) 
      { 
       CurrentNodeMatches.Add(StartNode); 
      }; 
      if (StartNode.Nodes.Count != 0) 
      { 
       SearchNodes(SearchText, StartNode.Nodes[0]);//Recursive Search 
      }; 
      StartNode = StartNode.NextNode; 
     }; 

    } 

Hay dos partes en esto;

  1. Recoge todos los nodos en una página List<TreeNode>

  2. a través de la List<TreeNode> si la búsqueda no ha cambiado. Si la búsqueda ha cambiado, borre la lista y restablezca la indexación.

He probado esto con Windows Forms que se ejecutan bajo .Net 4 - IT páginas a través de cada nodo en un TreeView que contiene el texto de búsqueda, 1 por 1 hasta que llega al último nodo.

+0

Gracias tanto dash –

+0

Buena solución :). –

2

Deberá crear una colección de nodos (como List) y agregar cada nodo encontrado a esa lista y devolver ese en lugar de un solo nodo Además, tendrá que eliminar todas las declaraciones de interrupción

+0

No necesito mostrar todos los nodos al mismo tiempo, necesito seleccionar solo un nodo a la vez, pero cuando segunda vez, haga clic en el botón 1, necesito que se haya seleccionado el segundo resultado –

+0

Hmm, no se menciona eso en la publicación original ("todos ellos, cada vez que hago clic en el botón 1"). En ese caso, simplemente deje SearchNodes igual, y almacene el valor de retorno en algún lugar y páselo como el argumento StartNode. (Por defecto es treeView1.Nodes [0]) ... –

+0

Acctualmente no necesito almacenar el valor devuelto, solo puedo escribir treeView1.SelectedNode ("SelectedNode" es el último resultado de la función SearchNode). Pero eso no funciona si el resultado es un nodo derivado, no sé por qué –

-1

I usando esta solución para la búsqueda contiene texto en el nodo del árbol

int currentSearch = 0; 
int loop = 0; 
int found = 0; 

private bool FilterTreeNode(TreeNodeCollection nodes, string keyword) 
{ 
    bool result = false; 
    for (int i = 0; i < nodes.Count; i++) 
    { 
     if(result) 
      break; 
     loop++; 
     if (currentSearch < loop) 
     { 
      currentSearch++; 
      if (nodes[i].Text.Contains(keyword)) 
      { 
       found++; 
       _treeView.SelectedNode = nodes[i]; 
       _treeView.SelectedNode.Expand(); 
       _treeView.SelectedNode.EnsureVisible(); 
       OnFindResult(string.Format("Current result: {0} on total {1} nodes. FilePath: {2}", 
            found, _treeView.GetNodeCount(true), nodes[i].Name)); 
       return true; 
      } 
     } 
     result = FilterTreeNode(nodes[i].Nodes, keyword); 
    } 

    return result; 
}