none
Mostrar en textbox un nodo de un treeview y eliminar y añadir RRS feed

  • Pregunta

  • Hola, como van???
    quisiera preguntarles como visualizo en un textbox un nodo seleccionado en un treeview, yo estoy intentando esto pero me muestra en el textbox otra cosa:

    ESTE ES EL EVENTO DEL TREEVIEW QUE ME MUESTRA EL ÍTEM SELECCIONADO: MouseDoubleClick="MostrarTareaEnGeneradorTWF1"


    EN EL cs TENGO:
    public void MostrarTareaEnGeneradorTWF1(object sender, RoutedEventArgs e)
            {
                txtNombreTareaNueva.Text = TWLotesFase1.SelectedItem.ToString();
            }

    NO SE SACA NINGÚN ERROR PERO CUANDO DOY DOBLE CLICK EN EL NODO DEL ÁRBOL, ME MUESTRA EN EL TEXTBOX ESTO: System.Windows.Controls.TreeViewItem Header:TAREA1 Items.Count:0
    //TAREA1 ES LO QUE ACABO DE SELECCIONAR

    ademas de esto, no me lo esta eliminando, !!!!claro, no lo he seleccionado bien el que quiero eliminar!!!, cuando solucione el problema anterior estoy seguro que se solucionara el siguiente.....

    he intentado esto:
    TWLotesFase1.Items.RemoveAt(TWLotesFase1.Items.IndexOf(txtNombreTareaNueva.Text));

    y esto:
    TWLotesFase2.Items.RemoveAt(TWLotesFase2.Items.IndexOf(TWLotesFase2.SelectedItem));

    pero nada...

    muchas gracias por su colaboracion
    • Editado ccmmasi martes, 13 de abril de 2010 19:07
    viernes, 12 de marzo de 2010 21:40

Respuestas

  • hola cristuscam.

    con esta propiedad:

    TWLotesFase1.SelectedItem

    obtienes el objeto TreeViewItem seleccionado, con lo cual si haces un ToString(), te da el nombre del objeto.
    de modo que tienes que hacer un ToString() a la propiedad correspondiente que contiene el texto deseado, por ejemplo si quieres el texto de la propiedad "Header" debes hacer un casting y resolverla como en la siguiente linea:

    ((TreeViewItem)treeView.SelectedItem).Header.ToString();

    esto te daria el texto de la propiedad Header del TreeViewItem.

    para borrarlo, por ejemplo puedes hacer esto:

    treeView.Items.Remove(treeView.SelectedItem);

    y te borraria el item seleccionado.







    Saludos
    David González
    • Propuesto como respuesta David_González martes, 23 de marzo de 2010 7:41
    • Marcado como respuesta ccmmasi martes, 23 de marzo de 2010 14:31
    • Desmarcado como respuesta ccmmasi martes, 13 de abril de 2010 14:38
    • Marcado como respuesta ccmmasi lunes, 19 de abril de 2010 13:29
    lunes, 15 de marzo de 2010 10:10
  • hola, ya lo he hallado, 

    no se imaginan cuando encontre el codigo de dos lineas que mejora totalmente.

    para añadir bajo el elemento seleccionado:

            TreeViewItem item = new TreeViewItem();
            item.Header = txtNombreTareaNueva.Text;
    TreeViewItem parent = TreeViewUbicacion.SelectedItem as TreeViewItem; parent.Items.Add(item); parent.IsExpanded = true; txtNombreTareaNueva.Text = "";

    eliminar el item seleccionado:

    TreeViewItem item = (TreeViewItem)TreeViewUbicacion.SelectedItem;
            TreeViewItem parent = (((TreeViewItem)TreeViewUbicacion.SelectedItem).Parent) as TreeViewItem;
            parent.Items.Remove(item);

    • Marcado como respuesta ccmmasi lunes, 19 de abril de 2010 13:29
    lunes, 19 de abril de 2010 13:28

Todas las respuestas

  • hola cristuscam.

    con esta propiedad:

    TWLotesFase1.SelectedItem

    obtienes el objeto TreeViewItem seleccionado, con lo cual si haces un ToString(), te da el nombre del objeto.
    de modo que tienes que hacer un ToString() a la propiedad correspondiente que contiene el texto deseado, por ejemplo si quieres el texto de la propiedad "Header" debes hacer un casting y resolverla como en la siguiente linea:

    ((TreeViewItem)treeView.SelectedItem).Header.ToString();

    esto te daria el texto de la propiedad Header del TreeViewItem.

    para borrarlo, por ejemplo puedes hacer esto:

    treeView.Items.Remove(treeView.SelectedItem);

    y te borraria el item seleccionado.







    Saludos
    David González
    • Propuesto como respuesta David_González martes, 23 de marzo de 2010 7:41
    • Marcado como respuesta ccmmasi martes, 23 de marzo de 2010 14:31
    • Desmarcado como respuesta ccmmasi martes, 13 de abril de 2010 14:38
    • Marcado como respuesta ccmmasi lunes, 19 de abril de 2010 13:29
    lunes, 15 de marzo de 2010 10:10
  • Hola

    muchas gracias, ya me muestra la información deseada en el textbox, lo estoy haciendo como me dijiste

    txtNombreTareaNueva.Text = ((TreeViewItem)TWLotesFase1.SelectedItem).Header.ToString();
    pero con lo de borrar items del árbol, no he podido dar!!!, tengo esto y me elimina solo un ítem padre, cuando quiero eliminar un hijo, no me hace nada, no me saca error pero no lo elimina...
    TWLotesFase1.Items.Remove(TWLotesFase1.SelectedItem);
    muchas gracias

    miércoles, 17 de marzo de 2010 15:58
  • Hola crituscam.

    recuerda este post:

    http://social.msdn.microsoft.com/Forums/es-ES/wpfes/thread/e123d9a4-1d40-4c5f-b63d-430aba985c13

    tienes que tener en cuenta, que cada TreeViewItem es contenedor de sus propios hijos, de modo que el TreeView principal solo contiene los items raices.

    para buscar items en un TreeView, debes realizarlo recursivamente como se indica en el post anterior.


    Saludos
    David González
    • Propuesto como respuesta David_González martes, 23 de marzo de 2010 7:41
    martes, 23 de marzo de 2010 7:41
  • hola

    es que me ha ocurrido una cosa, 

    resulta que no he podido crear elementos en el tw despues del primer hijo, me explico, tengo este arbol:

    item 1

    item1.1

    item1.1.1

    item1.2

    item1.3

    me permite ingresarle items a los hijos directos (item 1, item1.1, item1.1.1), pero cuando intento ingresarle un item a los demas (item 1.2 o item 1.3) me saca un error

    el codigo que estoy utilizando es este:

     

     

    private void AñadiraTreeViewUbicacionlaNuevaTarea()
            {
                TreeViewItem item = new TreeViewItem();
                item.Header = txtNombreTareaNueva.Text;
    
                TreeViewItem parentItem = null;
                for (int i = 0; i < TreeViewUbicacion.Items.Count; i++)
                {
                    parentItem = getItem((TreeViewItem)TreeViewUbicacion.Items[i], ((TreeViewItem)TreeViewUbicacion.SelectedItem).Header.ToString());
                    if (parentItem != null) break;
                }
                parentItem.Items.Add(item);
                parentItem.IsExpanded = true;
            }
    
            private TreeViewItem getItem(TreeViewItem _rootItem, string _itemHeader)
            {
                // recorrer todos los items y sus hijos recursivamente para buscar el padre
                for (int a = 0; a <= _rootItem.Items.Count; a++)
                {
                    // si el nombre del nodo coincide se retorna
                    if (_rootItem.Header.ToString() == _itemHeader) return _rootItem;
    
                    // llamar recursivamente a todos los hijos para buscarlo
                    else if (_rootItem.Items.Count > 0)
                    {
                        return getItem((TreeViewItem)_rootItem.Items[a], _itemHeader);
                    }
                }
                // si no se encuentra se retorna null
                return null;
            }

    el error me saca es aca: 

    parentItem.Items.Add(item);
    y el error es este:

    Referencia a objeto no establecida como instancia de un objeto.

     

    y otra cosa, es que en el momento de eliminar, no me estaba eliminando hijos, con un arbol estatico que tengo lo logre hacer con este codigo para eliminar los hijos:

    TreeViewItem parent = (TreeViewUbicacion.SelectedItem as TreeViewItem).Parent as TreeViewItem;
                parent.Items.Remove(TreeViewUbicacion.SelectedItem);
    pero resulta que tambien tengo arboles dinamicos, que se crean en ejecucio, pero en ese no se como eliminar items ni padres ni hijos, 

    he logrado llegar al treeview con esta funcion:

    TreeView view = CanvasdeTreeviews.Children.OfType<TreeView>().Where(pre => (string)pre.Tag == ParentItem).SingleOrDefault<TreeView>();

    donde ParentItem es el nombre Tag del arbol. este codigo me funciona, pues con esta misma funcion llego al arbol dinamico para añadirle tareas y lo hace

    ahora, quiero es eliminarle items y no se como eliminarselos, si hubiera alguna forma de hacerlo como a un arbol estatico... estaba haciendo esto

    string ParentItem = "NombreARbol"; 
                TreeView view = CanvasdeTreeviews.Children.OfType<TreeView>().Where(pre => (string)pre.Tag == ParentItem).SingleOrDefault<TreeView>();
                
                TreeViewItem parent = (/*aca añadirle una funcion que me iguale o me posicione en una ubicacion seleccionada desde otro arbol*/).Parent as TreeViewItem;
                parent.Items.Remove(TreeViewUbicacion.SelectedItem);

    la funcion que habia pensado era esta pero me sale error de index o fuera de intervalo:

    TreeViewItem parent = ((view.Items.GetItemAt(((TreeViewItem)TreeViewUbicacion.SelectedItem).Items.CurrentPosition)) as TreeViewItem).Parent as TreeViewItem;
                

    sera que me pueden dar una ayudita¿?

    muchas gracias

    martes, 13 de abril de 2010 14:36
  • Hola crituscam.

    El error parece ser por que 'parentItem' es null y al acceder a la propiedad 'Items' te da el error.

    Pon un punto de interrupcion en esa linea y asegurate de que parentItem no sea null, si es necesario depura la funcion 'getItem' para ver por que no retorna el item correcto.

     

    En cuanto a lo de eliminar, da igual que sea un arbol generado estatica o dinamicamente, el problema es que no hace buen uso de la funcion 'Remove()'.

    En estos lenguajes de alto nivel, hay cosas que se pasan por alto y de ahi surgen la mayoria de los problemas.

    Debes pensar que los objetos, solo son punteros (si se ha programado en c/c++ esto debe estar muy claro), de modo que si tu tienes 2 TreeView y dependiendo de como esten creados, cada uno tendra TreeViewItems independientes, esto quiere decir que no es el mismo objeto un TreeViewItem del arbol A que otro del arbol B, ya que cada uno es un objeto independiente creado en una zona de memoria distinta, de modo que cuando se hace un:

    parent.Items.Remove(obj);

    Lo que hace la funcion es eliminar el item que contiene la direccion de memoria del objeto 'obj' que puede ser un item de otro arbol, con lo cual no va a eliminarlo, ya que no existe en este arbol.

    Debes pensar que en c# trabajas siempre con referencias (que no es lo mismo que punteros, aunque trabajan de forma relativamente similar) una referencia es un alias, 2 variables que apuntan a la misma direccion de memoria.

    de modo que cuando tu haces esto:

    TreeViewItem a = new TreeViewItem();
    // b apunta al mismo objeto que a
    TreeViewItem b = a;
    
    // ahora a, crea un nuevo objeto y a es diferente que b
    a = new TreeViewItem();
    de modo que en este codigo tienes 2 objetos creados en diferentes zonas de memoria y aunque tengan las mismas propiedades por que las hayas copiado, no son el mismo objeto ya que realmente todos los objetos son punteros del tipo de objeto, asi pues realmente si miras la memoria veras que las variables son direcciones de memoria diferentes, por lo tanto diferentes objetos.

     

     

     


    Saludos
    David González
    miércoles, 14 de abril de 2010 8:59
  • hola, ya lo he hallado, 

    no se imaginan cuando encontre el codigo de dos lineas que mejora totalmente.

    para añadir bajo el elemento seleccionado:

            TreeViewItem item = new TreeViewItem();
            item.Header = txtNombreTareaNueva.Text;
    TreeViewItem parent = TreeViewUbicacion.SelectedItem as TreeViewItem; parent.Items.Add(item); parent.IsExpanded = true; txtNombreTareaNueva.Text = "";

    eliminar el item seleccionado:

    TreeViewItem item = (TreeViewItem)TreeViewUbicacion.SelectedItem;
            TreeViewItem parent = (((TreeViewItem)TreeViewUbicacion.SelectedItem).Parent) as TreeViewItem;
            parent.Items.Remove(item);

    • Marcado como respuesta ccmmasi lunes, 19 de abril de 2010 13:29
    lunes, 19 de abril de 2010 13:28