33
el Guille , la Web del Visual Basic, C#, .NET y más... Lo+ - WinFX - .NET - ADO.NET - ASP.NET - Cómo... - Colabora - VB6 - API - HTML - Vista - Links - Foros Llenar un TreeView desde un DataSet usando un método recurrente Utilizar la jerarquía definida en los datos de una tabla para llenar el TreeView con un método recurrente sencillo. Fecha: 13/Ene/2005 (12/Ene/05) Autor: Serge Valsse ([email protected] )

el Guille

Embed Size (px)

Citation preview

Page 2: el Guille

En muchas oportunidades he necesitado llenar un TreeView con los datos contenidos en una tabla de mi base de datos. Normalmente se tiene bien clara la jerarquía de los datos que se desean mostrar en la misma estructura de la tabla y esto se puede aprovechar para evitar estar definiendo nodo por nodo en el TreeView.

De igual manera si los datos que llenarán el TreeView no están en una tabla se puede generar un DataSet con los diferentes modos que existen y obtener la estructura que se requiere para este método que describiré en este artículo.

Supongamos que tenemos una tabla en nuestra base de datos con la siguiente estructura y datos:

Figura 1. Estructura de Tabla de origen de datos para llenar TreeView.

Obviamente los nombres pueden ser diferentes, pero para el ejemplo se necesitan que se llamen así.

NombreNodo: Deberá contener el texto que se desea desplegar en el TreeView como nodo.

IdentificadorNodo: Un número único que identifica a cada nodo. Puede ser el valor de la llave primaria de la tabla o algún otro campo calculado pero que sea único. Para este ejemplo es númerico pero puede ser string si así se requiere haciendo los cambios respectivos en el código desde luego.

IdentificadorPadre: Este campo debe contener el IdentificadorNodo del Nodo del cual depende es Nodo representado en el registro.

Para el ejemplo vamos a utilizar los siguientes datos:

Page 3: el Guille

Figura 2. Ejemplo de datos con jerarquía definida para llenar TreeView.

Si observamos el IdentificadorNodo del "Nodo 1" (que es 1), está en el campo IdentificadorPadre del "Nodo 1.1" y "Nodo 1.2", esto indica que serán hijos de "Nodo 1", de igual manera "Nodo 1.1.1" y "Nodo 1.1.2" serán hijos de "Nodo 1.1" ya que contienen en IdentificadorPadre el IdentificadorNodo que corresponde a este (2 para este caso).

Observe que los Nodos del primer nivel, es decir los que no tienen Padre deben llevar el valor 0 (cero) en el campo IdentificadorPadre ya que no dependen de nadie.

Bien, veamos ahora cual es el código del método que hará el trabajo de llenar el TreeView utilizando toda esta estructura de datos.

Creación de un formulario que llene un TreeView desde un DataSet usando un método recurrente

Para el ejemplo seguiremos los siguientes pasos:

1. Crear un proyecto de tipo Proyectos de Visual C#, Aplicación para Windows y llámelo EjemploTreeView.

2. En el formulario generado (Form1) agrege dos controles, un TreeView y un Button. Desde la ventana de propiedades del botón asignar la propiedad Text = "Llenar TreeView".

3. Declare un DataSet que pueda ser vista por toda la clase Form1.

System.Data.DataSet dataSetArbol;

4. En la ventana de Código agrege el método que se ejecutará recurrentemente llamándolo CrearNodosDelPadre.

Page 4: el Guille

private void CrearNodosDelPadre(int indicePadre, TreeNode nodePadre) { // Crear un DataView con los Nodos que dependen del Nodo padre pasado como parámetro. DataView dataViewHijos = new DataView(dataSetArbol.Tables["TablaArbol"]); dataViewHijos.RowFilter = dataSetArbol.Tables["TablaArbol"].Columns["IdentificadorPadre"].ColumnName + " = " + indicePadre;

// Agregar al TreeView los nodos Hijos que se han obtenido en el DataView. foreach(DataRowView dataRowCurrent in dataViewHijos) { TreeNode nuevoNodo = new TreeNode(); nuevoNodo.Text = dataRowCurrent["NombreNodo"].ToString().Trim();

// si el parámetro nodoPadre es nulo es porque es la primera llamada, son los Nodos // del primer nivel que no dependen de otro nodo. if(nodePadre == null) { treeView1.Nodes.Add(nuevoNodo); } // se añade el nuevo nodo al nodo padre. else { nodePadre.Nodes.Add(nuevoNodo); }

// Llamada recurrente al mismo método para agregar los Hijos del Nodo recién agregado.

CrearNodosDelPadre(Int32.Parse(dataRowCurrent["IdentificadorNodo"].ToString()), nuevoNodo); } }5. Para simplificar el ejemplo, adicione los siguientes métodos que simularán los datos obtenidos desde una base de datos.

// Los siguientes dos métodos son para el ejemplo, el dataset puede ser llenado desde una tabla // de la base de datos. Lo importante es que contenga un equivalente a los tres campos que se // llenan aqui. private void CrearDataSet() { dataSetArbol = new DataSet("DataSetArbol");

DataTable tablaArbol = dataSetArbol.Tables.Add("TablaArbol"); tablaArbol.Columns.Add("NombreNodo",typeof(string)); tablaArbol.Columns.Add("IdentificadorNodo",typeof(Int32)); tablaArbol.Columns.Add("IdentificadorPadre",typeof(Int32));

Page 5: el Guille

InsertarDataRow("Nodo 1",1,0); InsertarDataRow("Nodo 1.1",2,1); InsertarDataRow("Nodo 1.1.1",3,2); InsertarDataRow("Nodo 1.1.2",4,2); InsertarDataRow("Nodo 1.2",5,1);

InsertarDataRow("Nodo 2",6,0); InsertarDataRow("Nodo 2.1",7,6); InsertarDataRow("Nodo 2.2",8,6);

InsertarDataRow("Nodo 3",9,0); InsertarDataRow("Nodo 3.1",10,9); InsertarDataRow("Nodo 3.2",11,9); }

private void InsertarDataRow(string column1, int column2, int column3) { DataRow nuevaFila = dataSetArbol.Tables["TablaArbol"].NewRow(); nuevaFila["NombreNodo"] = column1; nuevaFila["IdentificadorNodo"] = column2; nuevaFila["IdentificadorPadre"] = column3; dataSetArbol.Tables["TablaArbol"].Rows.Add(nuevaFila); }6. En el constructor de la clase Form1() ingrese la llamada al método que llenará el DataSet. El código quedará como sigue:

public Form1() { // // Required for Windows Form Designer support // InitializeComponent();

// // TODO: Add any constructor code after InitializeComponent call // CrearDataSet(); }7. Finalmente en el evento Click del boton button1 asocie el método siguiente que llamará al método para el llenado del TreeView.

private void button1_Click(object sender, System.EventArgs e) { // Llamar al método por primera vez que llenará el TreeView, este método se llamará luego // a sí mismo recurrentemente. CrearNodosDelPadre(0, null); }8. Compile y ejecute el proyecto. Lo que obtendremos es lo siguiente:

Page 6: el Guille

Figura 3. Resultado después de hacer Click en el botón "Llenar TreeView".

Si necesitas obtener el IdentificadorNode del Nodo que el usuario selecciona se puede utilizar la propiedad Tag del nodo, por supuesto si previamente en la creación del nodo se almacenó dicho valor en esta propiedad.

Por favor no olvides calificar el artículo en la caja de PanoramaBox que se muestra al inicio de la página.

EJEMPLO2

Page 7: el Guille

Loveless, único en su especieEl blog de un informático con una buena ortografía

Inicio

Inicio > SQL Server, Tecnologías Microsoft, SQL Server, .NET, Programación, C#, Base de datos > Llenar un TreeView de ASP.NET con datos de SQL Server mediante recursividad

Llenar un TreeView de ASP.NET con datos de SQL Server mediante recursividad

Septiembre 17, 2010 lovelessisma Deja un comentario Ir a los comentarios

La vez pasa subí un artículo sobre recursividad en SQL Server, ahora sin más preámbulo hay que darle uso a eso.

En este primer ejemplo realizaremos una estructura de árbol en ASP.NET y C#, conocida como TreeView. La llenaremos de forma recursiva usando un procedimiento almacenado y con datos de la tabla tm_ubigeo. En este artículo está el código SQL de la base.

Primero creamos nuestro TreeView, al que llamaremos treevUbigeo, por supuesto después de haber creado el sitio Web en Visual Studio 2008 y haber agregado una página llamada sample1_TreeViewRecursivo.aspx (o como ustedes quieran que se llame):

Ahora iremos a la base creada en SQL Server 2005 y creamos el siguiente procedimiento almacenado:

Page 8: el Guille

Código:

ver fuente

imprimir ?

01 alter procedure [dbo].[pa_ubigeo_listar]

02 (

03     @tipo varchar(10),

04     @param1 int

05 )

06 as

07 begin

08     if @tipo = 'nodos'

09         begin

10            select tm_idubigeo, tm_nomubigeo, dbo.fc_Obtenervalorcomun('tm_tipoubigeo', tm_tipoubigeo) as tipoubigeo

11             from tm_ubigeo

12                 where tm_idubigeosup = @param1 13         end

14 end

El código anterior nos muestra un procedimiento almacenado que recibe dos parámetros, uno para definir el tipo de consulta y el otro para indicar el id de referencia. Consta de una condición, la cual nos mostrará los registros que coincidan según la id de referencia que enviemos.

Ahora procedemos a crear una clase en el App_Code, a la cual llamaremos clsConexion, la cual tendrá este código:

Código:

ver fuente

imprimir ?

01 public class clsConexion

02 {

03     String var_cadenaconexion = (@"server=WINDOWS-1F39AFE\SQLEXPRESS;database=bd_ejemplo_recursivo;integrated security=true");

Page 9: el Guille

04     SqlConnection var_conexion = new SqlConnection();

05     SqlCommand var_comando = new SqlCommand();

06     SqlDataAdapter var_adaptador = new SqlDataAdapter();

07   

08     public clsConexion() 09     {

10   

11     }

12   

13     public void abrirconexion()

14     {

15         var_conexion.ConnectionString = var_cadenaconexion;

16         if (var_conexion.State == ConnectionState.Closed)

17             var_conexion.Open();

18     }

19   

20     public void cerrarconexion()

21     {

22         if (var_conexion.State == ConnectionState.Open) 23             var_conexion.Close();

24     }

25   

26     public DataSet dtsUbigeoListar(string tipo, int idnodo)

27     {

28         DataSet var_resultado = new DataSet(); 29         try

30         {

31             var_comando.CommandText = "pa_ubigeo_listar";

32             var_comando.CommandType = CommandType.StoredProcedure;

33             var_comando.Connection = var_conexion;

34             var_comando.Parameters.Add("@tipo", SqlDbType.VarChar, 10).Value = tipo;

35             var_comando.Parameters.Add("@param1", SqlDbType.Int).Value = idnodo;

36             var_adaptador.SelectCommand = var_comando;

Page 10: el Guille

37             var_adaptador.Fill(var_resultado, "consulta");

38             var_comando.Parameters.Clear();

39         }

40         catch (Exception ex)

41         {

42             throw ex;

43         }

44         return var_resultado; 45     }

46 }

Primero están las variables necesarias para la conexión y ejecución de procedimientos. Los primeros dos métodos (aparte del constructor), son para abrir y cerrar la conexión a la base de datos respectivamente (si no lo has notado de seguro escuchas a Chino y Nacho a todo volumen mientras), y la función dtsUbigeoListar nos servirá para llenar el DataSet, teniendo el mismo número de parámetros del procedimiento almacenado pa_ubigeo_listar.

Nos dirigimos luego a la página Web, donde en su código programaremos el método mostrarNodos que hará la lógica del llenado recursivo del TreeView:

Código:

ver fuente

imprimir ?

01 clsConexion cn = new clsConexion();

02 private void mostrarNodos(TreeNode pad)

03 {

04     DataSet dts = new DataSet();

05     int i = 0;

06     dts = cn.dtsUbigeoListar("nodos", Convert.ToInt32(pad.Value)); 07     for(i = 1; i <= dts.Tables["consulta"].Rows.Count; i++)

08     {

09         TreeNode nodo = new TreeNode();

10        nodo.Text = dts.Tables["consulta"].Rows[i - 1]

["tm_nomubigeo"].ToString() + " --- " + dts.Tables["consulta"].Rows[i - 1]["tipoubigeo"].ToString();

11         nodo.Value = dts.Tables["consulta"].Rows[i - 1]["tm_idubigeo"].ToString();

Page 11: el Guille

12         pad.ChildNodes.Add(nodo);

13         mostrarNodos(nodo);

14     }

15 }

Este método tiene como único parámetro una variable de tipo TreeNode, cuyos valores cambiarán a cada llamada que se hace en la estructura for de la función, dentro de la cual se declara un nuevo nodo cada vez, y cada nodo creado se llenará de los datos obtenidos del DataSet que cambiarán también a cada llamada del método, y los cuales se añadirán conforme el for siga su curso. Como vemos, se cumple la recursividad al llamarse a la misma función dentro del for.

Al programar el siguiente código en el evento Page_Load de la página, se logrará el llenado del TreeView:

Código:

ver fuente

imprimir ?

01 protected void Page_Load(object sender, EventArgs e)

02 {

03     TreeNode nodo = new TreeNode();

04     this.treevUbigeo.Nodes.Clear();

05     nodo.Value = "0";

06     nodo.Text = "Ubigeo"; 07     treevUbigeo.Nodes.Add(nodo);

08     cn.abrirconexion();

09     mostrarNodos(nodo);

10     cn.cerrarconexion(); 11 }

Primero creamos un nodo nuevo, el cual agregaremos con datos iniciales, el valor 0 en su propiedad Value es muy importante dada la naturaleza de la función. El valor Text puede tener cualquier valor que busques, yo le puse “Ubigeo”.

Añadimos el nuevo nodo, y abrimos conexión para dar paso a la ejecución del método anteriormente mencionado, y cerramos conexión. Es muy tedioso poner el abrir y cerrar conexión dentro del método mostrarNodos, ya que hacemos que el proceso sea lento

Page 12: el Guille

porque se abrirá y se cerrará conexión cada vez que el método sea ejecutado. De esta manera es mejor y más productivo.

Ahora ejecutamos la página y vemos resultados:

Como ven resulta bastante útil el uso de la recursividad para llenar este tipo de estructuras, ya que se hace de una manera rápida, fácil y sencilla (bueno sencillo a mi modo de ver jeje).Bueno pendejos este fue el primer ejemplo, habrán otros dos más que de seguro les van a ser muy útiles. Nos vemos.

"Tu religión apesta" será el título de un próximo artículo que subiré ¿Tienes algo que decir al respecto? ¿Dudas sobre el ejemplo? ¿Sugerencias? Escríbeme a [email protected].

Page 13: el Guille

Descargar

Comparte esto:

Facebook

Ads by Google

Categorías:SQL Server, Tecnologías Microsoft, SQL Server, .NET, Programación, C#, Base de datos Etiquetas: Visual C#, SQL Server LikeBe the first to like this post.

Comentarios (0) Trackbacks (1) Deja un comentario Trackback 1. Aún no hay comentarios.

1. Septiembre 29, 2010 en 1:23 pm | #1

Combos (select) dependientes en ASP.NET con AJAX.NET, SQL Server y recursividad « Loveless, único en su especie

Deja un comentario

Your email address will not be published. Required fields are marked *

Page 15: el Guille

AJAX

Base de datos

C#

Java

Javascript

JQuery

Linux

MySql

PHP

Programación

Programas

Software libre

SQL Server

SQL Server

Tecnologías Microsoft

Temas aparte

Ubuntu

Utilitarios

Entradas recientes

Ubuntu me parece una   mierda… He   regresado

Lamento la   demora

¿Quieres demostrar amistad sincera a tu   amigo/a?…

Todo problema se convierte en   anécdota

Buscar

Buscar por:

Page 16: el Guille

Posts Más Vistos

Ubuntu me parece una mierda... Formulario de acceso con Java y MySQL

Acceso a base de datos SQL Server desde WebService, con aplicación de escritorio – Parte III

Acceso a base de datos SQL Server desde WebService, con aplicación de escritorio – Parte   II

Subir múltiples archivos con Uploadify

Acceso a base de datos SQL Server desde WebService, con aplicación de escritorio – Parte I

¿Quieres demostrar amistad sincera a tu amigo/a?...

Recursividad con SQL Server

El peor día de mi vida

Subir y redimensionar imágenes con PHP y SimpleImage

Archivero

Noviembre 2010 Octubre 2010

Septiembre 2010

Agosto 2010

Julio 2010

Plasta de etiquetas

Ajax ASP.NET Eclipse http://kzkggaara.wordpress.com Java Linux MySQL Otras cosas PHP Programas

SQL Server Visual C#

Revuelto de categorías

.NET AJAX Base de datos C# Java Javascript JQuery Linux MySql

PHP Programación Programas Software libre SQL Server

Page 17: el Guille

Tecnologías Microsoft Temas aparte Ubuntu

Utilitarios

Loveless Isma

http://pbckt.com/sB.QKik 2   days   ago http://pbckt.com/pB.d7oeFL 3   days   ago

http://pbckt.com/pB.dJdCdP 1   month   ago

http://pbckt.com/sB.UnCR 1   month   ago

http://pbckt.com/sB.Utyd 1   month   ago

Arriba WordPress Copyright ©2010 Loveless, único en su especie Blog de WordPress.com. Theme: INove by NeoEase.

EJEMPLO 03

Hola, Geovanny:

Ese error lo obtienes porque no estás encerrando entre comillas simples elvalor devuelto por el objeto DataRow:

dvHijos.RowFilter = "codpadre ='" & dr("codpadre").ToString & "'"

De todas maneras, y observando el código fuente que has publicado, creo quete estás complicando la vida para rellenar el objeto TreeView.

Lo habitual en estos casos es disponer de dos tablas en la base de datospara poder relacionarlas a través de un campo común: una tabla sería latabla Padres y otra la tabla Hijos, donde ambas tendría un campo llamado«IdPadre» que sería el que utilizarías para crear una relación «uno avarios» entre las tablas Padres e Hijos.

Page 18: el Guille

Pero no es necesario que establezcas la relación en la misma base de datos,porque la podemos crear en tiempo de ejecución, tal y como muestra elsiguiente ejemplo, que asume que en tu base de datos SQL Server tienes lassiguientes tablas:

Tabla Padres==========

IdPadre Clave principalNombre

Tabla Hijos========

IdHijo Clave principalNombreIdPadre Igual al IdPadre de la tabla Padres

Para rellenar el objeto TreeView ejecutarías lo siguiente:

' Conexión con la base de datos'Dim cnn As New SqlConnection("Data Source=(local);" & _

' DataAdaptersDim daPadres As New SqlDataAdapter("Select * from Padres", cnn)Dim daHijos As New SqlDataAdapter("Select * from Hijos", cnn)

' DataSetDim dsDatos As New DataSet

' Llenar el DataSetdaPadres.Fill(dsDatos, "Padres")daHijos.Fill(dsDatos, "Hijos")

' Creamos una relación a través del campo IdPadre común en' ambos objetos DataTable.'

Page 19: el Guille

Dim parentColumn As DataColumn = _dsDatos.Tables("Padres").Columns("IdPadre")

Dim childColumn As DataColumn = _dsDatos.Tables("Hijos").Columns("IdPadre")

Dim rel As DataRelation = _New DataRelation("Padres_Hijos", _parentColumn, childColumn, True)

' Añadimos la relación al objeto DataSet.'dsDatos.Relations.Add(rel)

' Para que no se repinte el control TreeView hasta que' se hayan creado los nodos.'TreeView1.BeginUpdate()

' Limpiamos el control TreeView.TreeView1.Nodes.Clear()

' Añadimos un objeto TreeNode ra¡z para cada objeto Padre' existente en el objeto DataTable llamado Padres.'For Each padre As DataRow In dsDatos.Tables("Padres").Rows

' Creamos el nodo padre.Dim parentNode As TreeNode = _New TreeNode(padre.Item("Nombre").ToString)

' Lo añadimos a la colección Nodes del control TreeView.TreeView1.Nodes.Add(parentNode)

' Añadimos un objeto TreeNode hijo por cada objeto Hijo existente' en el objeto Padre actual.'For Each hijo In padre.GetChildRows("Padres_Hijos")' Creamos el nodo hijoDim childNode As TreeNode = _New TreeNode(hijo.Item("Nombre").ToString)

Page 20: el Guille

' Lo añadimos al nodo padreparentNode.Nodes.Add(childNode)Next

Next

' Repintamos TreeView.'TreeView1.EndUpdate()

¡Eso es todo! Como podrás comprobar, utilizando una relación entre ambastablas, no tienes que estar filtrando datos en un objeto DataView porque nosería necesario utilizarlo.

Para probar el ejemplo, mejor será que crees un nuevo proyecto, añadas alformulario de inicio un control TreeView, y modifiques la cadena de conexiónpara que se adapte a tus necesidades. Por supuesto, vuelvo a insistir que enel ejemplo se asume que en la base de datos existen dos tablas llamadasPadres e Hijos (u otras tablas con otros nombres), que más o menos tengan lamisma estructura que he indicado anteriormente.

Un saludo

--

Hola, Alan:

Entiendo que lo que deseas hacer es referenciar un formulario por el nombrede éste, es decir, si seleccionas un elemento del control TreeView llamado«Form23» que se muestre dicho formulario. Para ello tendrás que utilizar elespacio de nombres System.Reflection. Si por ejemplo, tu proyecto se llama

Page 21: el Guille

«WindowsApplication1», y dentro de él tienes una clase Form llamada«Form23», referenciarías dicho formulario ejecutando el siguiente código enel evento «NodeMouseClick» del control TreeView:

Private Sub TreeView1_NodeMouseClick( ... )

' Referenciamos el nodo donde se ha efectuado el clic'Dim childNode As TreeNode = e.Node

' Si no es un nodo hijo, abandonamos el procedimiento'If childNode.Parent Is Nothing Then Return

Try' Referenciamos el ensamblado que se está ejecutando.'Dim asm As System.Reflection.Assembly = _System.Reflection.Assembly.GetExecutingAssembly()

' Obtenemos una referencia de un objeto Form por su nombre.'Dim frm As Form = _DirectCast(asm.CreateInstance("TreeViewDemo." & _childNode.Text), Form)

frm.Show()

Catch ex As ExceptionMessageBox.Show(ex.Message)

End Try

End Sub

Un saludo

--------------------------------------------------------------------------

Page 22: el Guille

En este artículo paso a paso se describe cómo mostrar los datos de un conjunto de datos jerárquico

mediante el control TreeView en Microsoft Visual Basic. NET. Para ello, establecer un principal,

secundario y terciario relación y rellénelo el control TreeView adecuadamente. TreeView control tiene

una colección de nodos con raíz objetos TreeNode. Cada objeto TreeNode tiene su propia colección de

nodos que contiene más de un objeto TreeNode de secundarios. A continuación, puede utilizar el

control TreeView para trabajar hacia abajo desde el nodo primario o raíz para los nodos secundarios

correspondiente y mostrar los datos apropiados.

Este ejemplo crea un conjunto de datos jerárquico, recorre cada tabla y agrega nodos al control

TreeView para cada tabla secundaria en el conjunto de datos.

Volver al principio

Requisitos

En la lista siguiente se describe el hardware, el software, la infraestructura de red y los Service

Packs recomendados que necesitará:

Microsoft Visual Studio .NET instalado en un sistema operativo compatible con Microsoft

Windows

Un servidor SQL con la base de datos de ejemplo Neptuno instalada

En este artículo se supone que está familiarizado con los temas siguientes:

Visual Basic .NET

Acceso a los datos de ADO.NET

Volver al principio

Crear el proyecto y agregar código

1. Inicie Visual Studio .NET y cree un nuevo proyecto de aplicación para Windows de Visual

Basic.

2. Agregar una referencia a System.Data.SqlClient agregando la línea siguiente al principio de su

archivo de Form1.vb:

3. Imports System.Data.SqlClient

4. Arrastre un control TreeView (Treeview1) desde el cuadro de herramientas hasta el formulario

(Form1).

Page 23: el Guille

5. Abra la ventana de código del formulario y, a continuación, pegue el código siguiente en el

evento Form1_Load :

Nota Debe reemplazar USER ID < nombre de usuario > y < contraseña > de la contraseña

con los valores correctos. Asegúrese de que el identificador de usuario tiene los permisos

adecuados realizar estas operaciones en la base de datos.

6. Dim DSNWind As DataSet

7. Dim CNnwind As New SqlClient.SqlConnection("DATA

SOURCE=servername;USER ID=<username>;PASSWORD=<strong

password>;INITIAL CATALOG=northwind;") '<==== CHANGE HERE

8. Dim DACustomers As New SqlClient.SqlDataAdapter("SELECT

CustomerID, CompanyName, ContactName, Country FROM customers WHERE

country = 'Germany'", CNnwind)

9. Dim DAOrders As New SqlClient.SqlDataAdapter("SELECT

CustomerID, OrderID, OrderDate, ShippedDate, ShipVia, Freight FROM

orders where customerid in (select customerid from customers where

country = 'Germany')", CNnwind)

10. Dim DAOrderDetails As New

SqlClient.SqlDataAdapter("Select * from [Order Details] where

OrderID in (SELECT OrderID FROM orders where customerid in (select

customerid from customers where country = 'Germany'))", CNnwind)

11.

12. DSNWind = New DataSet()

13. CNnwind.Open()

14. DACustomers.Fill(DSNWind, "dtCustomers")

15. DAOrders.Fill(DSNWind, "dtOrders")

16. DAOrderDetails.Fill(DSNWind, "dtOrderDetails")

17. 'Close the connection to the data store; free up the

resources

18. CNnwind.Close()

19.

20. 'Create a data relation object to facilitate the

relationship between the Customers and Orders data tables.

21. DSNWind.Relations.Add("CustToOrd",

DSNWind.Tables("dtCustomers").Columns("CustomerID"),

DSNWind.Tables("dtOrders").Columns("CustomerID"))

Page 24: el Guille

22. DSNWind.Relations.Add("OrdToDet",

DSNWind.Tables("dtOrders").Columns("OrderID"),

DSNWind.Tables("dtOrderdetails").Columns("OrderID"))

23. '''''''''''''''''''''''

24. TreeView1.Nodes.Clear()

25. Dim i, n As Integer

26. Dim parentrow As DataRow

27. Dim ParentTable As DataTable

28. ParentTable = DSNWind.Tables("dtCustomers")

29.

30. For Each parentrow In ParentTable.Rows

31. Dim parentnode As TreeNode

32. parentnode = New TreeNode(parentrow.Item(0))

33. TreeView1.Nodes.Add(parentnode)

34. ''''populate child'''''

35. '''''''''''''''''''''''

36. Dim childrow As DataRow

37. Dim childnode As TreeNode

38. childnode = New TreeNode()

39. For Each childrow In

parentrow.GetChildRows("CustToOrd")

40. childnode = parentnode.Nodes.Add(childrow(0) & "

" & childrow(1) & " " & childrow(2))

41. childnode.Tag = childrow("OrderID")

42. ''''populate child2''''

43. ''''''''''''''''''''''''''

44. Dim childrow2 As DataRow

45. Dim childnode2 As TreeNode

46. childnode2 = New TreeNode()

47. For Each childrow2 In

childrow.GetChildRows("OrdToDet")

48. childnode2 =

childnode.Nodes.Add(childrow2(0))

49.

50. Next childrow2

51. ''''''''''''''''''''''''

Page 25: el Guille

52.

53. Next childrow

54. '''''''''''''''

55. Next parentrow

EJEMPLO 4

ES BUENO

http://msdn.microsoft.com/es-es/library/7a9swst5(VS.80).aspx

EJEMPLO5

Introducción:

Cuando seleccionas un nodo en un TreeView, el valor de la propiedad FullPath contiene una cadena al estilo de Nodo_Padre\Nodo_Hijo\Nodo_Nieto, es decir, te devuelve el "path" o ruta de ese nodo al estilo de los directorios.

Aquí te voy a explicar cómo aprovechar esa forma de mostrar la ruta de un nodo en concreto, con idea de que puedas usarlo para seleccionar el nodo del TreeView que quieras en cualquier momento y sin necesidad de tener que recorrerlos todos para llegar al que te interesa.

El truco para hacer esto que te digo consiste en agregar las claves de los nodos para que tengan ese mismo contenido, es decir, en lugar de dejar que sea el propio runtime el que asigne los valores a las claves de los nodos, nosotros los asignaremos, pero para que después nos sirva para esto que te acabo de comentar al principio de este párrafo.Después para buscar el nodo que coincide con el texto, usamos el método Find, el cual devuelve un array del tipo TreeNode, pero que en la mayoría de los casos, solo usaremos el primer elemento del array devuelto por ese método.

En el siguiente código (para Visual Basic es el mostrado en el artículo, para C# lo puedes ver más abajo) te muestro cómo crear esas claves, y como podrás comprobar, consiste en darle a los nodos hijos (sub nodos) la misma clave que al padre, pero añadiéndole también la clave del hijo. Esas claves en realidad se van formando con el texto mostrado. Por supuesto, este truco solo es válido si no habrá repeticiones de claves, es decir, no habrá dos nombres iguales en la misma rama del árbol... la situación más parecida es la indicada de igualar esto a la estructura de un directorio, en la que no puede haber dos nombres iguales en un mismo directorio (nodo).

' Para sacar valores aleatorios

Page 26: el Guille

Private rnd As New Random

Private Sub Form1_Load(ByVal sender As Object, _ ByVal e As EventArgs) _ Handles MyBase.Load ' Añadir nodos al TreeView ' y asignarles claves para que tengan el mismo valor ' que lo que devuelve FullPath With TreeView1 For i As Integer = 1 To 10 Dim skNodo As String = "Nodo " & i.ToString("00") Dim tvn As TreeNode = .Nodes.Add(skNodo, "Nodo " & i.ToString("00")) For j As Integer = 1 To rnd.Next(2, 5) ' un valor de 2 a 4 Dim skHijo As String = skNodo & "\Hijo " & j.ToString Dim tvn2 As TreeNode = tvn.Nodes.Add(skHijo, "Hijo " & j.ToString) For k As Integer = 1 To rnd.Next(2, 4) ' un valor de 2 a 3 Dim skNieto As String = skHijo & "\Nieto " & k.ToString tvn2.Nodes.Add(skNieto, "Nieto " & k.ToString) Next Next Next End WithEnd Sub

 

Después, para seleccionar uno de los nodos sabiendo el "path completo" lo puedes hacer de esta forma (en el código tienes los comentarios para que sepas lo que se hace exactamente):

Private Sub btnSeleccionar_Click(ByVal sender As Object, _ ByVal e As EventArgs) _ Handles btnSeleccionar.Click If String.IsNullOrEmpty(TextBox2.Text) Then Exit Sub

' El nodo a seleccionar Dim sKey As String = TextBox2.Text

' El método Find devuelve un array del tipo TreeNode ' pero normalmente tendrá solo un valor si el nodo existe Dim tvn() As TreeNode = TreeView1.Nodes.Find(sKey, True) If tvn IsNot Nothing AndAlso tvn.Length > 0 Then TreeView1.SelectedNode = tvn(0) End IfEnd Sub

 

Si en cualquier momento quieres conocer el valor devuelto por la propiedad FullPath al seleccionar un nodo, lo puedes hacer con este método que intercepta el evento AfterSelect.

Page 27: el Guille

' Cuando se selecciona un nodo del TreeViewPrivate Sub TreeView1_AfterSelect(ByVal sender As Object, _ ByVal e As TreeViewEventArgs) _ Handles TreeView1.AfterSelect ' Mostrar en el textBox el path completo TextBox1.Text = e.Node.FullPath 'TextBox2.Text = e.Node.FullPathEnd Sub

 

Para crear este ejemplo, necesitas lo siguiente:

Un control TreeView llamado TreeView1

Dos cajas de texto (TextBox), una llamada TextBox1 y la otra TextBox2

Un botón llamado btnSeleccionar

Si usas C#, tendrás que interceptar estos eventos:

o El evento Load del formulario en el método Form_Load

o El evento Click del botón en el método btnSeleccionar_Click

o El Evento AfterSelect del TreeView en el método

TreeView1_AfterSelect

Después inserta todo el código mostrado en el formulario y ya tienes el ejemplo funcionando.

Más abajo tienes el código para C# y los ZIP con los proyectos, tanto para Visual Basic 2008 como para Visual C# 2008. Pero aunque esos proyectos estén creados con Visual Studio 2008, también te valdrán para Visual Studio 2005.

Espero que te sea de utilidad.

Nos vemos.Guillermo

EJEMPLO 7

http://www.recursosvisualbasic.com.ar/htm/trucos-codigofuente-visual-basic/180-cargar-base-dato-treeview.htm