Sunteți pe pagina 1din 5

Llenar un Control TreeView dinmicamente desde una Base de

Datos, con ASP.NET 2005


Por h@nz | 12/28/2006 | Visitas 35,792 | Voto 4.00
En este artculo vamos a demostrar como se manipula un control TreeView, cargando los
registros dinmicamente desde la base de datos.
Categoras : C#, ASP.NET
Descargar ejemplo LlenarTreeViewASPX.zip
El Control TreeView es un control jerrquico que normalmente se puede llenar desde un archivo
XML o de forma manual, pero en ocasiones no se pueden tener los datos en un XML y necesitamos
recuperarlos desde la Base de Datos. En este artculo veremos una forma de hacer este trabajo.
Hace poco tuve el siguiente problema, necesitaba crear un men en un control TreeView para una
aplicacin web, las opciones del men varan segn el usuario que ingrese al sistema. La idea bsica era
esa, bien, tener un archivo XML no me serva de nada, las opciones no eran fijas, sino que variaban, si
creaba varios archivos XML no los podra controlar si se decide cambiar las opciones puesto que el Admin
del sistema poda quitarle opciones a un usuario y mi Servidor Web no me da permiso de escribir
archivos, en fin.... el anlisis del problema demandaba mucho mas tiempo y ms condiciones que solo las
nombradas, la solucin? llenar el control TreeView directamente desde la Base de Datos.
Empezamos la aplicacin creando la siguiente estructura de directorios, tal como muestra la imgen
siguiente.

Ahora, no mostrar como crear las tablas ni como relacionarlas porque eso vara dependiendo de cada
caso particular, es decir que la lgica de negocios de cada caso es muy diferente, lo que s har ser
mostrar como debera quedar la consulta del Stored Procedure para poder crear la estructura jerrquica
del TreeView de forma correcta. Yo he considerado (en resmen) una tabla de Mdulos para los mdulos
de sistema (ejemplo: Mdulo de ventas, mdulo de compras, mdulo de control de almacenes, etc.), una
tabla de Grupos para las Opciones generales de men (por ejemplo: Men Pocesos, men Consultas,
men Configuracin, etc.) y una tabla de Opciones que contendr las opciones del Sistema, es decir, los
Casos de Uso o requerimientos funcionales segn UML, adems, esta tabla de Opciones debe tener un
campo en particular que contenga el url de la pgina web que cada opcin llamar (por ejemplo: la opcin
Generar Factura llamar al a pgina GenerarFactura.aspx). De este modo, la consulta que haga mi
Stored Procedure debe quedar como muestra el siguiente grfico.

Ahora, en el archivo adjunto que contiene el cdigo solo hay una tabla con esa misma estructura, eso se
debe como ya les dije a que los casos son diferentes y si coloco un SP que invoque los registros de la
tabla es para dejar en claro que el acceso a datos SIEMPRE se debe realizar a travs de un SP y JAMAS
directamente desde la pgina web o alguna clase. En mi caso y solo como ejemplo, he tenido que utilizar
aproximadamente 12 tablas para poder generar la consulta resultante, as que las relaciones de su BD las
deben ver Uds.
Ahora, lo primero que haremos ser crear la Clase que invocar al Stored Procedure desde la Base de
Datos. Crearemos una Clase (obviamente en la carpeta App_Code y si no hubiera, creamos esta carpeta
primero) llamada Usuario_DAL (el sufijo DAL es por Data Access Layer) y en esta clase escribiremos el
siguiente cdigo:
using System;
using System.Data;
using System.Configuration;
using System.Data.SqlClient;
public class Usuario_DAL
{
private int _idUsuario;
public Usuario_DAL(int idUsuario)
{_idUsuario = idUsuario;}
public DataTable leerOpciones()
{
SqlConnection cnn = new
SqlConnection(ConfigurationManager.ConnectionStrings["miBaseDatos"].ConnectionString);
SqlCommand cmd = new SqlCommand("uspListarOpcionesUsuario", cnn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@idUsuario", SqlDbType.Int).Value = _idUsuario;
cnn.Open();
DataTable dtt = new DataTable();
dtt.Load(cmd.ExecuteReader(), LoadOption.OverwriteChanges);
cnn.Close();
return dtt;
}
}
Bien, expliquemos el cdigo. El constructor de esta clase recibe un parmetro llamado idUsuario, que
debe ser el cdigo del usuario que ingresa al Sistema y que servir para hacer los filtros en las tablas
para conseguir mostrar solo las opciones de cada usuario. El mtodo leerOpciones como se darn cuenta
retorna un objeto DataTable. Se ejecuta el Stored procedure que devuelve la consulta que se vi en el
grfico anterior como un SqlDataReader, esto para cortar la conexin con la Base de Datos en cuanto se

ejecute esta accin, as liberamos la conexin con la Base de Datos. Este SqlDataReader se puede
convertir fcilmente en un objeto DataTable usando el mtodo Load de la instancia del DataTable, el
parmetro LoadOption.OverwriteChanges solo indica que se deben sobreescribir los datos si es que
hubiesen en el DataTable, como nuestro DataTable (dtt) esta vaco no nos preocupamos por eso.
Cerramos la conexin que utiliz nuestro objeto SqlCommand y devolvemos nuestro DataTable.
Ahora, este proceso solo nos ha servido para poder devolver el DataTable, ahora, falta el proceso que
carga las opciones en el TreeView y esto lo haremos en otra clase que vamos a crear (en la misma
carpeta App_Code) y le llamaremos Usuario_BLL (el sufijo BLL se debe a Bussiness Logic Layer). En
dicha clase escribiremos el siguiente cdigo:
using System;
using System.Data;
using System.Web.UI.WebControls;
public class Usuario_BLL
{
public Usuario_BLL(){}
public void cargarOpcionesUsuario(int idUsuario, TreeView tvw)
{
string grupo = "", modulo = "";
TreeNode nodoG = new TreeNode();
TreeNode nodoM = new TreeNode();
Usuario_DAL user = new Usuario_DAL(idUsuario);
DataTable dtt = user.leerOpciones();
for (int i = 0; i < dtt.Rows.Count; i++)
{
DataRow filaM = dtt.Rows[i];
if (modulo != filaM[1].ToString())
{
grupo = filaM[3].ToString();
nodoG = new TreeNode(grupo, filaM[2].ToString());
modulo = filaM[1].ToString();
nodoM = new TreeNode(modulo, filaM[0].ToString());
nodoG.ChildNodes.Add(new TreeNode(filaM[5].ToString(), filaM[4].ToString(), "", filaM[6].ToString(),
"_self"));
nodoM.ChildNodes.Add(nodoG);
tvw.Nodes.Add(nodoM);
}
else
{
if (grupo != filaM[3].ToString())
{
grupo = filaM[3].ToString();
nodoG = new TreeNode(grupo, filaM[2].ToString());
nodoM.ChildNodes.Add(nodoG);
}
nodoG.ChildNodes.Add(new TreeNode(filaM[5].ToString(), filaM[4].ToString(), "", filaM[6].ToString(),
"_self"));
}
}
dtt.Dispose();
dtt = null;
}
}
Analicemos. Esta clase no recibe parmetros en su constructor. Posee un nico mtodo llamado
cargarOpcionesUsuario que recibe dos parmetros, el primero es el cdigo del Usuario por el que
haremos el filtro y el segundo es el nombre del control TreeView que llenaremos con las opciones.

Instanciamos un obejto de la clase Usuario_DAL pasandole como dato el id de usuario para que nos
devuelva el objeto DataTable que necesitamos para hacer este trabajo.
La lgica para este ltimo paso es bastante sencilla, en realidad se trata de recorrer la tabla e ir
agregando las opciones a un nuevo objeto nodo (TreeNode), luego este nodo lo agregaremos como un
nodo hijo a un nodo de nivel superior, en este caso el que contendr los grupos y finalmente este nodo de
grupos lo agregaremos a un nodo principal que ser el que contenga los mdulos. La idea es que por
cada cambio en el campo de mdulos, agreguemos un nuevo mdulo, y por cada cambio en el campo
grupos, agreguemos un nuevo grupo, en el caso de las opciones no es necesario hacer esta validacin
pues cada opcin ser diferente.
Un objeto TreeNode tiene 5 sobrecargas, yo he utilizado dos de ellas:
* nodoG = new TreeNode(grupo, filaM[2].ToString()); - Esta pide el texto que se mostrar al usuario y el
valor que tendr dicho nodo, en este caso el cdigo del propio grupo.
* nodoG.ChildNodes.Add(new TreeNode(filaM[5].ToString(), filaM[4].ToString(), "", filaM[6].ToString(),
"_self")); - Esta segunda forma ademas, pide una imgen para mostrar, que no hemos considerado, un
URL para usarlo como Hipervnculo y en ltimo lugar, la ventana de destino del enlace, que ser nuestra
propia ventana.
Ahora, en una pgina web agregamos un control TreeView y escribimos el siguiente cdigo:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
Usuario_BLL user = new Usuario_BLL();
user.cargarOpcionesUsuario(1, TreeView1);
}
}
Obviamente en el Load de la pgina. el primer parmetro yo lo he considerado como fijo, pero en el caso
de Uds. puede ser una variable de Session, o un dato recuperado del URL o de un form, etc. que ser el
que se enve para el filtro en la clase de acceso a datos. El resultado final debe ser el que se muestra en
esta imgen.

La recomendacin que hara sera que colocanse su TreeView en un MasterPage y a partir de l hiciesen
sus pginas. Espero que este artculo les sea de utilidad y que lo apliquen, si le hacen alguna mejora,
compartanla!!!
Saludos, hasta el prximo artculo.
Descargar ejemplo LlenarTreeViewASPX.zip

S-ar putea să vă placă și