Vous êtes sur la page 1sur 19

1. Visualización.

1.1 Introducción.
Objetos de visualización pueden ser cualquiera que nosotros queramos utilizar.
Pero aquellos más habituales en el enlace con las Bases de datos podían ser

DataGridView
TextBox ..
ListBox.

1.2 DataGridView.
Es un objeto de visualización, es una evolución del objeto DataGrid.
Es una cuadricula en la que se pueden visualizar datos enlazados a una tabla, o provenientes de
cualquier otra estructura de datos.
El enlace de las tablas a la cuadrícula se realiza mediante la propiedad DataSource.
Cuando se realiza éste enlace no es posible añadir filas de forma manual al DataGrid.
Dispone de un sin fin de opciones de configuración para mejorar el formato de visualización.
Existe la clase DataGridViewCellStyle, que gestiona los estilos de formato de dicho objeto, si bien se
recomienda no utilizarla cuando el volumen de datos es muy elevado.
Cuando se desea visualizar un elevado volumen de datos en este objeto, se debe activar la propiedad
VirtualMode en true, para mejorar el rendimiento.

Vemos un ejemplo de configuración de dicho objeto, por cuestiones estéticas hay que destacar la
combinación de las siguientes propiedades que permiten obtener una visualización de las filas en un formato
similar al antiguo papel pijama, lo cual facilita su interpretación, solo hay que utilizar dos colores contrastados y
de tonos suaves que no impidan la legibilidad del texto.

' Asignar el color de fondo para las filas de forma alternativa.


ObjDataGrid.AlternatingRowsDefaultCellStyle.BackColor = Color.Cornsilk
ObjDataGrid.RowsDefaultCellStyle.BackColor = Color.BlanchedAlmond

En el apartado del teclado, quizás tenga algunas deficiencias, pero se podrían solucionar creando una
clase que herede este objeto y en el cual se potencie el tratamiento del teclado, para así poder filtrar
convenientemente los datos.
1.2.1 Configuración.
El ejemplo es un poco largo, y no todo es necesario, pero tiene un pequeño resumen de las propiedades
de configuración más relevantes.

Public Sub ConfigDataGrid(ByVal Formulario As Form, _


ByRef ObjDataGrid As DataGridView, _
ByVal Estado As Boolean)

' Inicializar propiedades básicas


' Forma de acople del objeto a su contenedor, el Form
' DockStyle.None, respeta el formato del diseño
' DockStyle.Fill, genera espacio para cada columna y activa la barra
' horizontal si es necesario.
' los demás no generan pegas.
With ObjDataGrid
.Dock = DockStyle.None ' DockStyle.Fill
' Color de fondo de la zona no ocupada por el datagrid
.BackgroundColor = Formulario.BackColor
' texto del datagrid
.ForeColor = Color.Black
' Estilo del borde
.BorderStyle = BorderStyle.None

' Estilo del objeto


.CellBorderStyle = DataGridViewCellBorderStyle.Single
' color de las lineas entre celdas, el grid
.GridColor = SystemColors.ActiveBorder
' Columna de cursor lateral
.RowHeadersVisible = False
' Asignar color de fondo de la celda que toma el foco
.DefaultCellStyle.SelectionBackColor = Color.White
' Asignar color de primer plano de la celda que toma el foco
.DefaultCellStyle.SelectionForeColor = Color.Black
' Generar columnas automático
.AutoGenerateColumns = True
' Asignar valores apropiados para solo lectura y limitar la
' interacción con el objeto
.AllowUserToAddRows = Estado
.AllowUserToDeleteRows = estado
.AllowUserToOrderColumns = Estado
.EditMode = DataGridViewEditMode.EditOnEnter
.ReadOnly = False
' Sistema de selección de las celdas
.SelectionMode = DataGridViewSelectionMode.FullRowSelect
.MultiSelect = False
' Columnas del DataGrid para ajustadas al contenido cargado
.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader)
' Tamaño de las celdas, influye sobre las de AllowUserToResize...
.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCells
' El usuario puede o no cambiar el tamaño en alto o ancho
.AllowUserToResizeColumns = True
.AllowUserToResizeRows = True
End With

With ObjDataGrid.ColumnHeadersDefaultCellStyle
' Asignar la fila y columna de estilo de cabecera
.ForeColor = Color.Yellow
.BackColor = Color.Black
.Alignment = DataGridViewContentAlignment.MiddleCenter
.SelectionForeColor = Color.Coral
.WrapMode = DataGridViewTriState.NotSet
End With

With ObjDataGrid
.ColumnHeadersHeightSizeMode = _
DataGridViewColumnHeadersHeightSizeMode.AutoSize
.ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Sunken
' Asignar Estilo de selección de fila de cabecera por defecto de forma
' que el valor no se superponga a los valores de estilo de las celdas.
.RowHeadersDefaultCellStyle.SelectionBackColor = Color.Coral
.RowHeadersDefaultCellStyle.BackColor = Color.Blue
.RowHeadersWidthSizeMode = _
DataGridViewRowHeadersWidthSizeMode.AutoSizeToFirstHeader

' Asignar el color de fondo para las filas de forma alternativa


.AlternatingRowsDefaultCellStyle.BackColor = Color.Cornsilk
.RowsDefaultCellStyle.BackColor = Color.BlanchedAlmond
End With
End Sub
Independientemente de la configuración anterior, en cada programa se puede personalizar el ancho y
alineación de las columnas.

ObjDataGrid.Columns(0).Width = CInt(ObjDataGrid.Width * 0.08)

Y también la alineación de una columna.

ObjDataGrid.Columns(3).DefaultCellStyle.Alignment = _
DataGridViewContentAlignment.MiddleRight

Un ejemplo podría ser éste en el que el ancho de las columnas se asignan como un porcentaje del ancho
del objeto.

ObjDataGrid.Columns(0).Width = CInt(ObjDataGrid.Width * 0.08)


ObjDataGrid.Columns(1).Width = CInt(ObjDataGrid.Width * 0.1)
ObjDataGrid.Columns(2).Width = CInt(ObjDataGrid.Width * 0.5)
ObjDataGrid.Columns(3).Width = CInt(ObjDataGrid.Width * 0.1)
ObjDataGrid.Columns(3).DefaultCellStyle.Alignment = _
DataGridViewContentAlignment.MiddleRight
ObjDataGrid.Columns(4).Width = CInt(ObjDataGrid.Width * 0.12)
ObjDataGrid.Columns(4).DefaultCellStyle.Alignment = _
DataGridViewContentAlignment.MiddleRight

1.2.2 Carga de datos.


La carga de datos de éste objeto para su uso enlazado con una tabla de la base de datos es como sigue
en el ejemplo.

Public Sub CargaDataGrid( _


ByVal Conexion As System.Data.OleDb.OleDbConnection, _
ByRef Adaptador As System.Data.OleDb.OleDbDataAdapter, _
ByRef EnlaceTabla As BindingSource, _
ByRef ObjDataGrid As DataGridView, _
ByVal CadenaSql As String)

Dim ComandoActualizar As OleDb.OleDbCommandBuilder


Try
' Crear un nuevo adaptador de datos
Adaptador = New OleDb.OleDbDataAdapter(CadenaSql, Conexion)
' Crear un 'commandbuilder' que genere el SQL Update/Insert/Delete
' el comando, no puede cambiarse de sitio pues captura datos de la
' operación anterior del adaptador.
ComandoActualizar = New OleDb.OleDbCommandBuilder(Adaptador)
' Llenar la tabla con los datos y enlazarla con el 'bindingsource'
Dim Tabla As New DataTable
Adaptador.Fill(Tabla)
ObjDataGrid.DataSource = EnlaceTabla
EnlaceTabla.DataSource = Tabla
Catch ex As OleDb.OleDbException
MsgBox(ex.Message, MsgBoxStyle.Information)
End Try
End Sub

El enlace de los datos se realiza directamente también mediante la propiedad DataSource.

' Se enlaza el objeto


ObjDataGrid.DataSource = Tabla
1.2.3 Visualización.
A la hora de la visualización se puede crear el siguiente código para formatear en contenido o color las
columnas.

Private Sub ObjDataGrid_CellFormatting( _


ByVal sender As Object, _
ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) _
Handles ObjDataGrid.CellFormatting

Select Case e.ColumnIndex


Case 0 ‘ Fecha
e.Value = Strings.Right(e.Value.ToString, 2) & "-" & _
Strings.Mid(e.Value.ToString, 5, 2) & "-" & _
Strings.Left(e.Value.ToString, 4)
Case 5 ‘ Entradas o salidas
If e.Value IsNot Nothing Then
If e.Value.ToString = "1” Then TipoMovim = "E"
If e.Value.ToString = "2" Then TipoMovim = "S"
Select Case e.Value.ToString
Case "1"
e.Value = "Compra"
e.CellStyle.SelectionForeColor = Color.Blue
e.CellStyle.ForeColor = Color.Blue
Case "2"
e.Value = "Venta"
e.CellStyle.SelectionForeColor = Color.Red
e.CellStyle.ForeColor = Color.Red
Case "3"
e.Value = "Abono"
e.CellStyle.SelectionForeColor = Color.Blue
e.CellStyle.ForeColor = Color.Blue
Case "4"
e.Value = "Devol"
e.CellStyle.SelectionForeColor = Color.Red
e.CellStyle.ForeColor = Color.Red
End Select
End If
Case 6
If e.Value IsNot Nothing Then
Select Case TipoMovim
Case "S"
e.CellStyle.SelectionForeColor = Color.Red
e.CellStyle.ForeColor = Color.Red
Case "E"
e.CellStyle.SelectionForeColor = Color.Blue
e.CellStyle.ForeColor = Color.Blue
End Select
End If
End Select
End Sub
1.2.4 Validación.
A la hora del control de los datos en el evento CellValidating se puede desarrollar código de control.
La forma de identificar la columna objeto del control es con la propiedad ColumnIndex del objeto e.

Select Case e.ColumnIndex


Case 0

Si deseamos saber si el valor de la celda es nulo

If String.IsNullOrEmpty(e.FormattedValue.ToString()) Then

Si deseamos saber la longitud de un dato.

If e.FormattedValue.ToString().Length > 2 Then

Si deseamos el valor de un dato

If e.FormattedValue.ToString() = "1” Then TipoMovim = "E"

Private Sub ObjDataGrid_CellValidating( _


ByVal sender As Object, _
ByVal e As System.Windows.Forms.DataGridViewCellValidatingEventArgs) _
Handles ObjDataGrid.CellValidating

Dim Celda As DataGridViewCell


If ObjDataGrid.Rows(e.RowIndex).IsNewRow Then Return
Celda = ObjDataGrid.Item(ObjDataGrid.CurrentCellAddress.X, _
ObjDataGrid.CurrentCellAddress.Y)
Select Case e.ColumnIndex
Case 0
If String.IsNullOrEmpty(e.FormattedValue.ToString()) Then
MsgBox("No puede quedar en blanco.", MsgBoxStyle.Information, _
NomProgram)
e.Cancel = True
Else
If e.FormattedValue.ToString().Length > 2 Then
MsgBox("El código excede de la longitud.", _
MsgBoxStyle.Information, NomProgram)
e.Cancel = True
End If
End If
Case 1
If String.IsNullOrEmpty(e.FormattedValue.ToString()) Then
MsgBox("No puede quedar en blanco.", MsgBoxStyle.Information, _
NomProgram)
e.Cancel = True
End If
End Select
End Sub

Con “e.Cancel a true” se cancela la acción.


1.2.5 Crear las columnas sin estar enlazado.
El procedimiento que sigue realiza la configuración en columnas del DataGrid cuando éste no captura su
estructura desde el enlace con un DataTable.

Los pasos son indicar el número de columnas que tendrá el objeto

ObjDataGrid.ColumnCount = 4

su nombre de columna, Name, y su título, HeaderText.

ObjDataGrid.Columns.Item(0).Name = "Tipo"
ObjDataGrid.Columns.Item(0).HeaderText = "Tipo"

Las filas que procedan le asignaremos también la alineación adecuada.

ObjDataGrid.Columns.Item(3).DefaultCellStyle.Alignment = _
DataGridViewContentAlignment.MiddleRight

luego asignar a cada una el ancho pertinente.

ObjDataGrid.Columns(0).Width = CInt(ObjDataGrid.Width * 0.1)

El procedimiento completo es.

Private Sub ConfigurarDataGrid(ByVal EnlaceTabla As BindingSource)


'
' El objeto es un DataGridView
'
ObjDataGrid.ColumnCount = 4
ObjDataGrid.Columns.Item(0).Name = "Tipo"
ObjDataGrid.Columns.Item(0).HeaderText = "Tipo"

ObjDataGrid.Columns.Item(1).Name = "Codigo"
ObjDataGrid.Columns.Item(1).HeaderText = "Código"

ObjDataGrid.Columns.Item(2).Name = "Titulo"
ObjDataGrid.Columns.Item(2).HeaderText = "Título"

ObjDataGrid.Columns.Item(3).Name = "Cantidad"
ObjDataGrid.Columns.Item(3).HeaderText = "Cantidad"
ObjDataGrid.Columns.Item(3).DefaultCellStyle.Alignment = _
DataGridViewContentAlignment.MiddleRight

ObjDataGrid.Columns(0).Width = CInt(ObjDataGrid.Width * 0.1)


ObjDataGrid.Columns(1).Width = CInt(ObjDataGrid.Width * 0.1)
ObjDataGrid.Columns(2).Width = CInt(ObjDataGrid.Width * 0.6)
ObjDataGrid.Columns(3).Width = CInt(ObjDataGrid.Width * 0.1)
End Sub

En el procedimiento se puede usar al acabar una llamada a un procedimiento de configuración genérico.


1.2.6 Adición de una fila cuando el DataGrid está enlazado.
Añadir filas en un Datagrid es una acción que está supeditada al valor de las propiedades de
disponibilidad de edición

ObjDataGrid.AllowUserToAddRows = Estado
ObjDataGrid.AllowUserToDeleteRows = Estado
ObjDataGrid.AllowUserToOrderColumns = Estado

las cuales son las que marcan como responderá el objeto ante esta situación y gestionándose desde
dicho objeto.

Cuando la tabla está enlazada a una tabla y se permite la edición, los datos que se añaden o se borran
en el DataGrid se reflejan en la tabla.

La adición de un registro al objeto se realiza a través de la tabla a la que está enlazado.

Creamos un objeto DataRow, al que asignaremos los datos del registro de la tabla.
Posteriormente el objeto DataRow se añade a la tabla y el DataGrid visualiza su contenido.

Creamos el objeto, usamos el método NewRow, el cual nos devuelve un registro vacío con la estructura
de la tabla.

Dim Registro As DataRow = Tabla.NewRow

Asignar los datos al registro que hemos creado.

Registro.Item("Tipo") = Titulo.Codigo.ToString
Registro.Item("Codigo") = Titulo.Codig2.ToString

Después de haber asignado los datos, añadir el registro a la tabla.

Tabla.Rows.Add(Registro)

El código completo es el que sigue.

Private Sub AnyadirTitulos(ByRef Tabla as System.Data.DataTable)


Dim Registro As DataRow = Tabla.NewRow
Dim Titulo As ItemLista = CType(Lista04.SelectedItem, ItemLista)
Dim RegTit As System.Data.DataRow

Registro.Item("Tipo") = Titulo.Codigo.ToString
Registro.Item("Codigo") = Titulo.Codig2.ToString
Registro.Item("Titulo") = Titulo.ToString
Registro.Item("Cantidad") = "0"
Registro.Item("Precio") = Titulo.Codig3
Try
Tabla.Rows.Add(Registro)
Catch ex As ConstraintException
MsgBox("Título existente", MsgBoxStyle.Critical, NomProgram)
End Try
End Sub
1.2.7 Actualizar el contenido del DataGrid cuando está enlazado.
El enlace debe realizarse a través de un BindingSource.

Adaptador.Update(CType(Enlace.DataSource, DataTable))
MsgBox("Datos actualizados", MsgBoxStyle.Information)

Cuando se hace de forma directa la actualización es.

Adaptador.Update(Tabla)
MsgBox("Datos actualizados", MsgBoxStyle.Information)

1.2.8 Adición de una fila cuando el DataGrid no está enlazado.


Recordar la configuración de las propiedades de edición a su valor adecuado a lo que deseemos
realizar.
Se desactivan si es necesario esas propiedades.
En el ejemplo se han definido y cargado con datos las variables tipo, cod, denom y cant, para
posteriormente usarlas en la declaración e inicialización del objeto fila que después se añade al objeto
ObjDataGrid.

Private Sub AnyadirTituloDatagrid()


ObjDataGrid.AllowUserToAddRows = True

Dim Tipo, Cod, Denom As String

Tipo = "01"
Cod = "0001"
Denom = "Visual Basic Net 2005"

Dim Fila() As Object = {Tipo, Cod, Denom}

ObjDataGrid.AllowUserToAddRows = True
Try
ObjDataGrid.Rows.Add(Fila) ' deja por no estar enlazada a datos
Catch ex As ArgumentException
MsgBox(ex.Message, MsgBoxStyle.Information, NomProgram)
End Try

ObjDataGrid.AllowUserToAddRows = False
ObjDataGrid.CurrentCell = ObjDataGrid(3, ObjDataGrid.Rows.Count - 1)
End Sub

A continuación se posiciona el cursor en la columna tres de la fila añadida para completar los datos
manualmente.

ObjDataGrid.CurrentCell = ObjDataGrid(3, ObjDataGrid.Rows.Count - 1)

1.2.9 Borrado de una fila cuando el DataGrid está enlazado.


Es tan sencillo como ejecutar el código del ejemplo.

ObjDataGrid.Rows.Remove(ObjDataGrid.CurrentRow)

CurrentRow devuelve la fila actual que es la que se borra al presionar en un button por ejemplo.

La documentación de éste objeto la podemos encontrar en :

http://msdn2.microsoft.com/es-es/library/system.windows.forms.datagridview(VS.80).aspx
1.3 TextBox, caja de texto.
Es uno de los objetos que se pueden utilizar para la visualización y captura de los datos de una tabla.
Para poder conseguir que se visualicen los datos de una la tabla en el TextBox, hay que enlazarlo antes
con el origen de datos a través de un BindingSource.
El enlace se realiza con la propiedad DataBinding.

Private Sub Enlaces()


Campo00.DataBindings.Add("Text", EnlaceTabla, "CodProv")
Campo01.DataBindings.Add("Text", EnlaceTabla, "DenomCas")
Campo02.DataBindings.Add("Text", EnlaceTabla, "DenomVal")
End Sub

Los parámetros son

("Text",

La propiedad que se va a enlazar, entre comillas,

EnlaceTabla,

El objeto que se enlaza al TextBox, el que tiene los datos.

"CodProv")

El nombre del campo en el objeto de origen de los datos, nombre en la tabla.

El funcionamiento del BindingSource esta documentado en un tema anterior.

La visualización de su contenido a partir de aquí se realiza de forma automática, sin necesidad de


realizar ninguna asignación manual, aunque la diferencia entre un formato y otro no tiene mucha diferencia en
volumen de código.

La carga de los datos en la tabla correspondiente sería esta.

Private Sub CargaDatos()


If Conexion.State = ConnectionState.Closed Then Conexion.Open()
Adaptador = New OleDb.OleDbDataAdapter(CadenaSql, Conexion)
Adaptador.Fill(Tabla)
EnlaceTabla.DataSource = Tabla
Actualizador = New OleDb.OleDbCommandBuilder(Adaptador)
Conexion.Close()
End Sub

La actualización de los datos que hay en el TextBox se hace como sigue:

Private Sub Actualizar()


Conexion.Open()
Try
Adaptador.Update(CType(EnlaceTabla.DataSource, DataTable))
MsgBox("Datos actualizados.", MsgBoxStyle.Information, Me.Text)
Catch ex As OleDb.OleDbException
MsgBox("Datos existentes", MsgBoxStyle.Critical, Me.Text)
End Try
Conexion.Close()
Actualizado = True
End Sub

El destino del enlace de los textbox al objeto BindingSource es poder obtener estas acciones.
Private Sub Comando00_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles Comando01.Click, _
Comando02.Click, _
Comando03.Click, _
Comando04.Click, _
Comando05.Click, _
Comando06.Click, _
Comando07.Click, _
Comando08.Click, _
Comando09.Click

Dim Cual As Integer


Cual = CInt(Strings.Right(CType(sender, Button).Name, 2))
Select Case Cual
Case 1 ' cancelar
EnlaceTabla.CancelEdit()
Case 2 ' borrar
EnlaceTabla.RemoveCurrent()
Case 3 ' salida
Salida()
Case 4 ' principio
EnlaceTabla.MoveFirst()
Case 5 ' anterior
EnlaceTabla.MovePrevious()
Case 6 ' siguiente
EnlaceTabla.MoveNext()
Case 7 ' final
EnlaceTabla.MoveLast()
Case 8 ' nuevo
EnlaceTabla.AddNew()
Case 9 'actualizar
EnlaceTabla.EndEdit()
Actualizar()
End Select
End Sub

Dentro de un formulario que podría tener esa apariencia.

Y solo queda que en el Load del formulario se ejecute la configuración de la conexión, la llamada al
procedimiento de enlazar y la carga de los datos.
Con tan poco código, queda algo muy aparente, a falta de realizar las validaciones adecuadas según el
programa.

El contenido de la documentación de éste objeto podemos encontrarlo en:

http://msdn2.microsoft.com/es-es/library/system.windows.forms.textbox(VS.80).aspx

1.4 ListBox.
El enlace del objeto ListBox se realiza de la siguiente forma

ListBox.DataSource = ObjDataSet.Tables("TipoCliente")

Realiza el enlace con la tabla del DataSet.

ListBox.DisplayMember = "Denom"
Indica cual es el campo de la tabla en la parte visible del ListBox

ListBox.ValueMember = "Codigo"

Indica cual es el campo de la tabla que se utilizará como código del dato visualizado.

Codigo = ListBox.SelectedValue.ToString()

Se captura, en el evento clic, por ejemplo, el valor del código del elemento seleccionado.

El ComboBox funciona con la misma filosofía.

1.5 ListView, lista.


Es un objeto que dispone también de muchas opciones de visualización de datos.
Dada su flexibilidad, la configuración de las propiedades que determinan la forma en la que se visualiza
los datos, de ahí la precaución que hay que tener a la hora de asignar los valores a las mismas, pues en
función de su valor se pueden provocar errores motivados por la incongruencia de la configuración.

La propiedad View con el valor Details es la que marca muchas de esas propiedades de visualización.
Esta propiedad dispone de cuatro valores posibles que cambiarán el formato de la visualización de los
datos.

Los métodos BeginUpdate y EndUpdate permiten mejorar el rendimiento cuando se agregan muchos
elementos a un control ListView, impidiendo que se vuelva a dibujar el control cada vez que se agrega un
elemento.

Si la propiedad LabelEdit está establecida en true, se pueden realizar tareas como la validación del texto
editado antes y después de cambiarlo mediante la creación de un controlador de eventos para los eventos
BeforeLabelEdit y AfterLabelEdit.

A continuación exponemos un ejemplo de cómo cargar un objeto listview desde una tabla de la base de
datos.

El procedimiento es muy parecido a otros ya expuestos, y comentamos la parte que efectúa la carga.

Con esta declaración creamos un objeto fila como elemento de un ListView, que después se añadirá al
objeto.

Dim Fila As ListViewItem

Para poder cargar correctamente el ListView es necesario que éste tenga definida la cabecera, para ello
utilizamos el método GetName del objeto DataReader.

' Carga cabecera, sin la cabecera no funciona


For I = 0 To Lector.FieldCount - 1
ListView.Columns.Add(Lector.GetName(I))
Next

Ahora hay que ir creando los objetos fila para cargarlos y añadirlos después.

' crea un nuevo elemento de lista


Fila = New ListViewItem

' añade los datos


Fila.Text = CStr(Lector.Item(0))
For I = 1 To Lector.FieldCount - 1
' añade los sub elementos
Fila.SubItems.Add(Lector.Item(I).ToString)
Next

Y cuando tenemos la fila montada la añadimos al objeto ListView.

ListView.Items.Add(Fila)

Todo completo.

Private Sub CargaListView()


Dim Conexion As New System.Data.OleDb.OleDbConnection
Dim Comando As New System.Data.OleDb.OleDbCommand
Dim Lector As System.Data.OleDb.OleDbDataReader
Dim Fila As ListViewItem
Dim I As Integer

' Configurar el comando a ejecutar, una consulta almacenada


' en el archivo de la base de datos Access, Nombre.MDB
Comando.CommandText = "Usp_SelectProvincias"
' Tipo de comando a ejecutar
Comando.CommandType = CommandType.StoredProcedure
' Conexión a utilizar, configurada previamente.
Comando.Connection = Conexion
' Abrir la base de datos.
ConfigConexion(Conexion)
Conexion.Open()
' Ejecutar el comando, con un DataReader
Lector = Comando.ExecuteReader
' Hay registros ???
If Lector.HasRows Then
' Carga cabecera, sin la cabecera no funciona
For I = 0 To Lector.FieldCount - 1
ListView.Columns.Add(Lector.GetName(I))
Next
' recorre todas las filas
While Lector.Read()
' crea un nuevo elemento de lista
Fila = New ListViewItem

' añade los datos


Fila.Text = CStr(Lector.Item(0))

For I = 1 To Lector.FieldCount - 1
' añade los sub elementos
Fila.SubItems.Add(Lector.Item(I).ToString)
Next
ListView.Items.Add(Fila)
End While
End If
Lector.Close()

' Liberar recursos


Lector = Nothing
Comando.Dispose()
Comando = Nothing
Conexion.Dispose()
Conexion = Nothing
End Sub
Si deseamos obtener el código del elemento que se seleccione en el ListView podemos hacer esto.

CargaRegistro(ListView.SelectedItems.Item(0).Text)

Donde ListView.SelectedItems.Item(0).Text se convierte en un string, que recibe el procedimiento en


cuestión para cargarlo desde la base de datos, o un DataSet, partiendo de que el código se ha almacenado en
la columna 0.

El contenido de la documentación de éste objeto podemos encontrarlo en:

http://msdn2.microsoft.com/es-es/library/system.windows.forms.listview(VS.80).aspx

1.6 TreeView, árbol.


1.6.1 Introducción.
Este objeto es “práctico”, o sea se, es un objeto de efectos especiales, dado que lo que se puede
obtener con él se puede obtener con otros objetos, pero claro de forma menos vistosa.
Como explicación de cual es, la mejor, el explorador de Windows.

A la hora de cargarlo con datos, el peligro radica cuando al realizar la carga en el primer nivel, -y en los
demás-, el volumen de estos es muy elevado, en la SQL hay que limitar el número de registros a cargar, ya que
si no se podría dar la circunstancia, de haber cargado a lo mejor un elevado volumen de datos, para visualizar
un único dato, lo cual en tiempo puede no ser rentable.

Cada uno de los nodos del árbol es un objeto, del tipo TreeNode, el cual a su vez incluye una colección
de nodos, que pueden o no ya ser nodos raíz.
Es importante tener claro que cada nodo es un objeto TreeNode, porque a la hora de gestionar los
eventos, se realiza sobre este objeto TreeNode.

El nodo actual sería Node del objeto “e” del evento correspondiente.

e.Node

Si quisiéramos saber cual es el nivel del nodo en el que han hecho clic, podemos utilizar,

e.Node.Level

Esta propiedad es práctica porque así podemos saber el nivel del árbol en que está colocado el usuario y
saber si hemos de cargar Clientes o Facturas, por ejemplo.

Si necesitamos saber cual de los nodos ha recibido el clic, podemos utilizar

e.Node.Index

Si necesitamos información del nodo padre del nodo actual, podemos utilizar

e.Node.Parent

Este se puede anidar, o se puede retroceder lo que necesitemos en función del nivel en el que estemos.

e.Node.Parent.Parent.Tag.ToString
e.Node.Parent.Parent.Name

Hay métodos que nos permiten obtener el nodo raíz del nodo actual o el nodo hijo del nodo actual, pero
evidentemente para eso tenemos que haber cargado el objeto con datos.
1.6.2 Carga.
El evento en el que se puede activar la carga del TreView, en función del criterio que se elija, es el
Node_MouseClick.
En el ejemplo que veremos el árbol tiene cuatro niveles, tres en forma de árbol y uno con un ListView.
Las variables para la captura de los datos del nodo, no son imprescindibles, es por cuestión de claridad
del ejemplo.

Dim Codigo As String

Captura del nivel del árbol en el que está el nodo que recibe el clic.

Select Case e.Node.Level

Captura del dato código en el nodo que se ha hecho clic, en la propiedad Name, quizás no sea muy
afortunado el nombre de la propiedad, pues induce a errores.

Codigo = e.Node.Name

Con el dato capturado ya se puede proceder a la ejecución del procedimiento de llenado del nodo actual,
e.node.

CargaNodoClientes(Codigo, e.Node)

Si el dato que tenemos que cargar se compone del código de un nodo anterior al actual, la captura del
código del nodo anterior se hace como sigue, Parent es el nodo padre del actual.

Tipo = e.Node.Parent.Name

Y el código del actual igual que en ejemplo anterior.

Codigo = e.Node.Name

Para después pasar a cargar el nuevo nodo.

CargaNodoFacturas(Tipo, Codigo, e.Node)

Y el evento completo a continuación,

Private Sub Arbol_NodeMouseClick( _


ByVal sender As Object, _
ByVal e As System.Windows.Forms.TreeNodeMouseClickEventArgs) _
Handles Arbol.NodeMouseClick

Dim Tipo As String


Dim Codigo As String
Select Case e.Node.Level
Case 0
Codigo = e.Node.Name
CargaNodoClientes(Codigo, e.Node)
Case 1
Tipo = e.Node.Parent.Name
Codigo = e.Node.Name
CargaNodoFacturas(Tipo, Codigo, e.Node)
Case 2
Codigo = e.Node.Name
CargaListView(Codigo)
End Select
End Sub
A continuación la carga inicial, en la que el TreeView estaría vacío.
En las cargas hemos utilizado un Reader, que se supone más rápido que un DataTable.
En la sintaxis de la SQL, faltaría la limitación del volumen de registros a cargar.

En cuanto al funcionamiento del código es el siguiente.

Primero para agilizar la carga de datos en el TreeView, se desactiva la reposición de imagen.

' Impedir que se redibuje el objeto.


Arbol.BeginUpdate()

Vaciamos el objeto de un posible contenido

' Limpiar el contenido del objeto.


Arbol.Nodes.Clear()

Generación de los datos.

CadenaSQL = "Select Codigo, Denom " & _


"From TipoCliente " & _
"Order By Denom"
Try
' Abrir la base de datos.
Conexion.Open()
' Contenido del comando
Comando.CommandText = CadenaSQL
' Tipo de comando a ejecutar
Comando.CommandType = CommandType.Text
' Conexión a utilizar, configurada previamente.
Comando.Connection = Conexion
' Ejecución de SQL
Reader = Comando.ExecuteReader

El siguiente paso es la ejecución del bucle de carga de los datos, y crear un nodo con datos.

' Añadir los nodos raíz para cada tipo de cliente


Arbol.Nodes.Add(Reader.Item("Codigo").ToString,Reader.Item("Denom").ToString)

El primer parámetro del método Add es la parte que nos servirá después en el evento clic,

Arbol.Nodes.Add(Reader.Item("Codigo").ToString,

para la captura de la parte del código del nodo.

Codigo = e.Node.Name
CargaNodoClientes(Codigo, e.Node)

La segunda parte del evento es el texto que se verá en el árbol.

,Reader.Item("Denom").ToString)

Todo esto, puede enriquecerse con iconos en los nodos.


Para ello se crea un objeto ImageList, y las imágenes que se cargan en dicho objeto se asignan a las
propiedades ImageIndex y SelectedImageIndex los índices de las imágenes correspondientes.

El código completo de la carga es el que sigue.


Private Sub CargaArbol(ByRef Arbol as TreeView)
Dim CadenaSQL As String
Dim Comando As New System.Data.OleDb.OleDbCommand
Dim Reader As System.Data.OleDb.OleDbDataReader

' Impedir la reposición de imagen para agilizar el llenado


Arbol.BeginUpdate()

' Limpiar el contenido del objeto


Arbol.Nodes.Clear()

CadenaSQL = "Select Codigo, Denom " & _


"From TipoCliente " & _
"Order By Denom"
Try
' Abrir la base de datos.
Conexion.Open()
' Contenido del comando
Comando.CommandText = CadenaSQL
' Tipo de comando a ejecutar
Comando.CommandType = CommandType.Text
' Conexión a utilizar, configurada previamente.
Comando.Connection = Conexion
' Ejecución de SQL
Reader = Comando.ExecuteReader
Try
While Reader.Read
' Añadir los nodos raíz para cada tipo de cliente
Arbol.Nodes.Add(Reader.Item("Codigo").ToString, _
Reader.Item("Denom").ToString)
Arbol.Nodes.Item(Arbol.Nodes.Count - 1).Tag = _
Reader.Item("Codigo").ToString
End While
' Expandir el nodo creado
Arbol.Nodes.Item(1).Toggle() ' Expand()
Catch ex As OleDb.OleDbException
MsgBox(ex.Message, MsgBoxStyle.Information, "Leer reader")
End Try
Catch Ex As OleDb.OleDbException
MsgBox(Ex.Message, MsgBoxStyle.Information, "Crear reader")
End Try
Conexion.Close()
' Fin de impedir redibujar TreeView.
Arbol.EndUpdate()
End Sub

Esta sería la carga inicial del árbol, la carga de un nodo es idéntica lo que sucede es que en lugar de
recibirse como objeto un TreeView, el árbol, se recibe el nodo al cual se le añaden los datos.
En el ejemplo se recibe un objeto TreeView y un objeto nodo, todo es cuestión de diseño.

Private Sub CargaNodoClientes(ByVal Tipo As String, _


ByRef Arbol As TreeView, _
ByRef Nodo As TreeNode)
Dim CadenaSQL As String
Dim Comando As New System.Data.OleDb.OleDbCommand
Dim Reader As System.Data.OleDb.OleDbDataReader

' Impedir que se redibuje el objeto.


Arbol.BeginUpdate()

CadenaSQL = "Select Tipo, Codigo, RazonSocial " & _


"From Clientes " & _
"Where Tipo = '" & Tipo & "' " & _
"Order By RazonSocial"
Try
' Abrir la base de datos.
Conexion.Open()
' Contenido del comando
Comando.CommandText = CadenaSQL
' Tipo de comnndo a ejcutar
Comando.CommandType = CommandType.Text
' Conexión a utilizar, configurada previamente.
Comando.Connection = Conexion
' Ejecución de SQL
Reader = Comando.ExecuteReader
' Limpiar el contenido del objeto
Nodo.Nodes.Clear()
Try
While Reader.Read
' Añadir los nodos nivel cliente para cada tipo de cliente
Nodo.Nodes.Add(Reader.Item("Codigo").ToString, _
Reader.Item("RazonSocial").ToString)
End While
' Expandir o contraer el nodo creado
Nodo.Toggle()
Catch ex As OleDb.OleDbException
MsgBox(ex.Message, MsgBoxStyle.Information, "Leer reader")
End Try
Catch Ex As OleDb.OleDbException
MsgBox(Ex.Message, MsgBoxStyle.Information, "Crear reader")
End Try
Conexion.Close()
' Fin de impedir redibujar TreeView.
Arbol.EndUpdate()
End Sub

La otra posibilidad de carga, es la de utilizar un objeto ListView como complemento al TreeView, visto en
el apartado anterior.

Y todo puede mejorarse si utilizamos un contenedor, SplitContainer, para el TreeView y el ListView, de


forma que le asignemos la parte izquierda del Split al TreeView y la derecha al ListView.
En ambos objetos, TreeView y ListView, le asignamos a la propiedad Dock el valor Fill, que hará que se
acoplen al tamaño del Split. De esa forma cuando se ajuste con el ratón la barra vertical central del Split, estos
objetos se ajustarán en sus medidas para llenar toda el área visible del mismo, como el explorador de
Windows.
1.6.3 Configuración.
El objeto TreeView permite que se pueda ver las casillas de expansión a la izquierda del nodo o no, igual
que las líneas que unen los nodos en función del valor de las propiedades.

Private Sub ConfigArbol()


Arbol.ShowLines = True ' visualiza las líneas del arbol
Arbol.ShowPlusMinus = True ' visualiza el + y - en el nodo
Arbol.LabelEdit = False ' impide editar la etiqueta del nodo
Arbol.ShowRootLines = True ' une con una línea los nodos raíz
End Sub

La configuración del objeto dependerá mucho del uso que se quiera hacer de él, y del destino que le
vamos a dar.
Si deseamos o no incorporar iconos en los nodos, en función del contenido, si deseamos utilizar la
opción de checkbox que incorpora, si deseamos o no permitir la edición.
1.6.4 Algunos conceptos.
TreeNode.
Representa un nodo de TreeView. Como cada TreeNode puede contener una colección de otros objetos
TreeNode, puede ser difícil determinar la ubicación en la estructura de árbol cuando se recorre la colección en
iteración.
Ejemplo: TreeNode nodo = new TreeNode();

TreeNode.Nodes.
Obtiene la colección de nodos de árbol asignados al control de vista de árbol. La propiedad Nodes
contiene una colección de objetos TreeNode, cada uno de los cuales tiene una propiedad Nodes que puede
contener su propia TreeNodeCollection.

TreeNodeCollection.Add
Permite agregar un nuevo nodo de árbol a la colección, conviene mirar la sobrecarga de dicho método
para utilizar la más adecuada.
La utilizada en el ejemplo es adecuada para la opción que se ha elegido, que es la de guardar el código
del elemento mostrado para su posterior, utilización.
Pero disponemos también de la propiedad Tag, que es muy flexible, un cajón de sastre, y con ella se
pueden resolver muchos problemas.

TreeNodeCollection.Clear
Quita todos los nodos de árbol de la colección.

TreeNode.ExpandAll
Expande todos los nodos de árbol secundarios. El método ExpandAll expande todos los nodos de árbol
secundarios asignados a la colección de Nodes, Toogle, también realiza una tarea similar.

Nodo.Nodes.Index.
Devuelve el índice del nodo en el nodo actual, Nodo.

Nodo.Nodes.Item(X).
Devuelve un item del nodo actual, debe de ser menor que Count .

Existen los métodos NextNode, PrevNode para recorrer el Nodo actual, progresión de Index.
FirstNode y LastNode, que se posicionan al principio y al final respectivamente del nodo secundario del
nodo actual.

Selected nos permite seleccionar el nodo actual.

En los eventos siempre se trabaja con un objeto Nodo, independientemente de la profundidad a la que
estemos actuando, y conviene tener siempre su nivel presente, para saber donde estamos y como debemos
actuar.
La filosofía de carga ya se ha comentado al principio y de ella depende como se trabaje después sobre
dicho objeto.
Hay que tener presente que algunas acciones no tienen sentido si el árbol no está cargado, y también
que a lo mejor no tiene sentido cargar un árbol con mucho volumen de datos.

Parte de lo que se obtiene con éste objeto se puede hacer también con un DataGrid, sobre todo a nivel
de relaciones, pero es menos vistoso que este, y quizás menos intuitivo para los usuarios menos avezados.
1.6.5 Recorrer un árbol.
Podemos recorrer el contenido de un árbol con el siguiente ejemplo, de forma recursiva.

Private Sub Recursivo(ByVal n As TreeNode)

MessageBox.Show(“Nodo “ & n.Text)

Dim Nodo As TreeNode


For Each Nodo In n.Nodes
Recursivo(Nodo)
Next
End Sub

Todo lo referente a éste objeto podemos encontrarlo en :

http://msdn2.microsoft.com/es-es/library/system.windows.forms.treeview(VS.80).aspx

http://msdn2.microsoft.com/es-es/library/system.windows.forms.treeview_members(VS.80).aspx

Vous aimerez peut-être aussi