lunes, 15 de febrero de 2010

C# - [ASP.NET] TreeView búsqueda recursiva


Introducción
El ejemplo muestra como realizar una búsqueda recursiva.
En este se buscan los ítem que contengan en la descripción del nodo lo ingresado en un Textbox de búsqueda
Luego se carga un ListBox con los datos, la selección de un ítem es reflejada en el treeview
Carga del TreeView
La primer operación que se realizaría será la carga del árbol
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
        LoadTreeView();

}

private void LoadTreeView()
{
    TreeNode node1 = new TreeNode("Node 1");
    node1.ChildNodes.Add(new TreeNode("Node 1 - 1"));
    node1.ChildNodes.Add(new TreeNode("Node 1 - 2"));
    node1.ChildNodes.Add(new TreeNode("Node 1 - 3"));
    node1.ChildNodes.Add(new TreeNode("Node 1 - 4"));
    TreeView1.Nodes.Add(node1);

    TreeNode node2 = new TreeNode("Node 2");
    node2.ChildNodes.Add(new TreeNode("Node 2 - 1"));
    node2.ChildNodes.Add(new TreeNode("Node 2 - 2"));
    node2.ChildNodes.Add(new TreeNode("Node 2 - 3"));
    node2.ChildNodes.Add(new TreeNode("Node 2 - 4"));
    TreeView1.Nodes.Add(node2);

    TreeNode node3 = new TreeNode("Node 3");
    node3.ChildNodes.Add(new TreeNode("Node 3 - 1"));
    node3.ChildNodes.Add(new TreeNode("Node 2 - 4"));
    TreeView1.Nodes.Add(node3);
}
Búsqueda Recursiva
Una vez introducido el valor que se quiere buscar en los nodos del treeview, se acciona el evento del botón.
Mediante el método Find() se analizaría cada nodo comenzando por los definidos como padres (root) y en caso de detectar nodos hijos seguir de forma recursiva por cada rama del árbol añadiendo nuevos ítems en caso de que estos coincidan con el criterio de búsqueda.

protected void btnBuscar_Click(object sender, EventArgs e)
{
    List<TreeNode> lista = Find(txtBuscar.Text);

    lbItemsEncontrados.Items.Clear();

    foreach (TreeNode item in lista)
    {
        ListItem itemlist = new ListItem(item.Text, item.ValuePath);
        lbItemsEncontrados.Items.Add(itemlist);
    }
}

private List<TreeNode> Find(string param)
{
    List<TreeNode> list = new List<TreeNode>();

    foreach (TreeNode item in TreeView1.Nodes)
    {
        if (item.Text.Contains(param))
            list.Add(item);

        if (item.ChildNodes.Count > 0)
          list.AddRange(FindChild(item.ChildNodes, param));

    }

    return list;
}

private List<TreeNode> FindChild(TreeNodeCollection nodes, string param)
{
    List<TreeNode> list = new List<TreeNode>();

    foreach (TreeNode item in nodes)
    {
        if (item.Text.Contains(param))
            list.Add(item);

        if (item.ChildNodes.Count > 0)
            list.AddRange(FindChild(item.ChildNodes, param));
    }

    return list;
}
Selección de los ítems en la lista
El control ListBox donde se han cargado los valores encontrado en la búsqueda no provee una propiedad u opción para obtener los ítems que se han seleccionado.
Es por eso que ante un cambio en la selección es necesario recorrer todos los ítem de la lista y actualizar el estado de selección en el treeview.
Algo interesante para remarcar es el uso de la propiedad Value, en la búsqueda del nodo especifico. Si se analizo el código de la búsqueda recursiva se habrá notado que los items de listbox se han cargado usando la propiedad ValuePath del TreeView, la cual simplifica la selección de un nodo en concreto.

protected void lbItemsEncontrados_SelectedIndexChanged(object sender, EventArgs e)
{
    for (int i = 0; i < lbItemsEncontrados.Items.Count; i++)
    {
        ListItem item = lbItemsEncontrados.Items[i];

        TreeNode node = TreeView1.FindNode(Convert.ToString(item.Value));
        node.Checked = item.Selected;
        
    }

}
[C#]


[VB.NET]

6 comentarios:

  1. COMO HAGO PARA OBTENER UN TERCER NODO PERO EN EL MISMO ARBOL
    NODE 1
    NODE 1.1
    NODE 1.1.1

    ResponderEliminar
  2. COMO HAGO PARA OBTENER UN TERCER NODO PERO EN EL MISMO ARBOL
    NODE 1
    NODE 1.1
    NODE 1.1.1

    ResponderEliminar
  3. Hola Leandro, de nuevo con una duda sobre c#, te comento.
    Tengo un aplicación WPF con un TreeView que lleno de forma dinámica en C# agregando Items, el problema que tengo es que al agregar estos items les quiero asignar un evento selected con un código como este tree5.Selected += subitem_Selected5;
    el problema es que esté método solo lo quiero para el nodo de nivel 5, pero al seleccionarlo es como si heredara los eventos selected de los nodos padre (4,3,2,1,0) y mi objetivo es que cada nivel tenga diferente comportamiento en el selected. Existe alguna forma de indicarle a los nodos hijos que no hagan el selected sobre sus nodos padres?

    ResponderEliminar
  4. Hola amigo me podrias pasar el codigo fuente ....Tu direccion o servidor esta caido
    un saludo y la verdad que tus tutoriales son de los mejor

    ResponderEliminar