Visual

44
Nombre de la asignatura: Programación Visual Parcial de estudio Segundo parcial Introducción ADO .NET es la nueva versión del modelo de objetos ADO (ActiveX Data Objetos), es decir, la estrategia que ofrece Microsoft para el acceso a datos. ADO .NET ha sido ampliado para cubrir toda las necesidades que ADO no ofrecía, ADO .NET está diseñado para trabajar con conjuntos de datos desconectados, lo que permite reducir el tráfico de red. ADO .NET utiliza XML como formato universal de trasmisión de los datos. ADO .NET posee una serie de objetos que son los mismos que aparecen en la versión anterior de ADO, como puede ser el objeto Connection o Command, e introduce nuevos objetos tales como el objeto DataReader, DataSet o DataView. ADO .NET se puede definir como: Un conjunto de interfaces, clases, estructuras y enumeraciones que permiten el acceso a los datos desde la plataforma .NET de Microsoft. Supone una evolución lógica del API ADO tradicional de Microsoft. Permite un modo de acceso desconectado a los datos que pueden provenir de múltiples fuentes de datos de diferente arquitectura de almacenamiento. Soporta un completo modelo de programación y adaptación basado en el estándar XML. Asesoría didáctica 1 Durante este mes usted deberá revisar el presente compendio con los temas relacionados con la programación, además en la Sección CONTENIDOS encontrará ejercicios realizados por mí; adicionalmente dispone de este material de apoyo que le servirá de referencia para la elaboración de la actividad correspondiente a este mes. Aplicaciones de estilo MDI Una aplicación de tipo o estilo MDI (Multiple Document Interface), Interfaz de Documento Múltiple, se compone de un formulario principal, también denominado formulario MDI, que actuará como contenedor de otros formularios (documentos) abiertos durante el transcurso del programa, denominados formularios hijos o secundarios MDI. Como ejemplos de este tipo de aplicación tenemos PowerPoint o Access. A diferencia de lo que ocurría en versiones anteriores de VB, un formulario MDI admite los mismos controles que un formulario normal, aunque dada su orientación de formulario contenedor, se recomienda limitar los controles en un MDI a los estrictamente necesarios. El menú es el ejemplo más identificativo de control idóneo para un formulario MDI, ya que a través de sus opciones, podremos abrir los formularios hijos de la aplicación. Seguidamente describiremos el proceso de creación de un proyecto que contenga un formulario MDI y dos formularios hijos, así como el comportamiento de estos últimos cuando son abiertos dentro del formulario padre MDI. Este ejemplo tiene el nombre MDIPru y se debe hacer clic aquí para acceder al mismo. Una vez creado el nuevo proyecto, cambiaremos el nombre del formulario por defecto a frmPrincipal. Para conseguir que este formulario tenga el comportamiento de un contenedor MDI, debemos asignar el valor True a su propiedad IsMdiContainer. También debemos establecer a este formulario como inicial en las propiedades del proyecto.

Transcript of Visual

Page 1: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

Introducción ADO .NET es la nueva versión del modelo de objetos ADO (ActiveX Data Objetos), es decir, la estrategia que ofrece Microsoft para el acceso a datos. ADO .NET ha sido ampliado para cubrir toda las necesidades que ADO no ofrecía, ADO .NET está diseñado para trabajar con conjuntos de datos desconectados, lo que permite reducir el tráfico de red. ADO .NET utiliza XML como formato universal de trasmisión de los datos. ADO .NET posee una serie de objetos que son los mismos que aparecen en la versión anterior de ADO, como puede ser el objeto Connection o Command, e introduce nuevos objetos tales como el objeto DataReader, DataSet o DataView. ADO .NET se puede definir como:

Un conjunto de interfaces, clases, estructuras y enumeraciones que permiten el acceso a los datos desde la plataforma .NET de Microsoft.

Supone una evolución lógica del API ADO tradicional de Microsoft.

Permite un modo de acceso desconectado a los datos que pueden provenir de múltiples

fuentes de datos de diferente arquitectura de almacenamiento.

Soporta un completo modelo de programación y adaptación basado en el estándar XML.

Asesoría didáctica 1

Durante este mes usted deberá revisar el presente compendio con los temas relacionados con la programación, además en la Sección CONTENIDOS encontrará ejercicios realizados por mí; adicionalmente dispone de este material de apoyo que le servirá de referencia para la elaboración de la actividad correspondiente a este mes.

Aplicaciones de estilo MDI Una aplicación de tipo o estilo MDI (Multiple Document Interface), Interfaz de Documento Múltiple, se compone de un formulario principal, también denominado formulario MDI, que actuará como contenedor de otros formularios (documentos) abiertos durante el transcurso del programa, denominados formularios hijos o secundarios MDI. Como ejemplos de este tipo de aplicación tenemos PowerPoint o Access. A diferencia de lo que ocurría en versiones anteriores de VB, un formulario MDI admite los mismos controles que un formulario normal, aunque dada su orientación de formulario contenedor, se recomienda limitar los controles en un MDI a los estrictamente necesarios. El menú es el ejemplo más identificativo de control idóneo para un formulario MDI, ya que a través de sus opciones, podremos abrir los formularios hijos de la aplicación. Seguidamente describiremos el proceso de creación de un proyecto que contenga un formulario MDI y dos formularios hijos, así como el comportamiento de estos últimos cuando son abiertos dentro del formulario padre MDI. Este ejemplo tiene el nombre MDIPru y se debe hacer clic aquí para acceder al mismo. Una vez creado el nuevo proyecto, cambiaremos el nombre del formulario por defecto a frmPrincipal. Para conseguir que este formulario tenga el comportamiento de un contenedor MDI, debemos asignar el valor True a su propiedad IsMdiContainer. También debemos establecer a este formulario como inicial en las propiedades del proyecto.

Page 2: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

Ahora pasaremos a la creación de los formularios hijos del MDI. El primero, frmCarta, permite la escritura en un TextBox multilínea, cuyo contenido podremos grabar a un archivo en disco. La Figura 291 muestra este formulario.

Figura 291. Formulario hijo de MDI para escribir un texto largo El código del botón que realiza la grabación del texto lo podemos ver en el Código fuente 497. Debemos importar el espacio de nombres System.IO, ya que en esta clase de formulario hacemos uso de los tipos File y StreamWriter.

Código fuente 497 El otro formulario hijo, frmInfo, muestra la fecha y hora actuales; esta última es actualizada a través del control Timer tmrTiempo (Figura 292).

Figura 292. Formulario hijo de MDI para mostrar fecha y hora actuales

Page 3: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

El Código fuente 498 muestra las instrucciones que se ejecutan en el evento Tick del control Timer.

Código fuente 498 El siguiente paso consiste en crear un menú para poder abrir los formularios hijos a través de sus opciones (Figura 293).

Figura 293. Menú del formulario MDI En las opciones Carta e información del menú, instanciaremos un objeto del formulario correspondiente, teniendo en cuenta que para conseguir que dichos formularios se comporten como hijos del MDI, debemos asignar a su propiedad MdiParent, la instancia actual del formulario en ejecución, es decir, Me. Veamos este punto en el Código fuente 499.

Código fuente 499

Page 4: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

En la Figura 294 mostramos el formulario MDI en ejecución, conteniendo a los formularios hijos dependientes.

Figura 294. Aplicación MDI en ejecución Controles de cuadros de diálogo del sistema Del conjunto de controles que nos ofrece la ventana Cuadro de herramientas del IDE, existe un grupo que nos permite el acceso a los cuadros de diálogo estándar del sistema operativo, esto es, los cuadros de selección de color, tipo de letra o fuente, apertura-grabación de archivo, etc. Para ilustrar el uso de algunos de estos controles, vamos a crear un proyecto de ejemplo con el nombre Diálogos Sistema, en el que describiremos su modo de uso en los aspectos de diseño y codificación. Crearemos pues, un nuevo proyecto de tipo aplicación Windows, y en su formulario, insertaremos un menú, añadiendo las siguientes opciones: Abrir, Guardar, Color y Fuente. Cada opción mostrará un tipo de diálogo del sistema. A continuación describiremos cada uno de los controles: ColorDialog Este control muestra el cuadro de diálogo del sistema para la selección de colores. Entre sus propiedades podemos destacar las siguientes. _Color. Contiene un tipo de la estructura Color, que nos permite obtener el color seleccionado por el usuario mediante este cuadro de diálogo, para poder aplicarlo sobre alguno de los elementos del formulario. _AllowFullOpen. Contiene un valor lógico que permite habilitar y deshabilitar el botón que Muestra el conjunto de colores personalizados del cuadro de diálogo de selección de colores. FontDialog Este control muestra el cuadro de diálogo del sistema para la selección del tipo de fuente. Entre sus propiedades podemos destacar las siguientes: _Font. Contiene un tipo de la clase Font. Una vez seleccionada una fuente por el usuario en el cuadro de diálogo, podremos cambiar la fuente de los controles del formulario. _ShowApply. Contiene un valor lógico que permite mostrar-ocultar el botón Aplicar, que nos permitirá asignar el tipo de letra sin cerrar el diálogo. Al pulsar este botón se desencadenará el evento Apply de este control de diálogo, en el que podremos escribir el código necesario para aplicar la nueva fuente seleccionada.

Page 5: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

SaveFileDialog Este control muestra el cuadro de diálogo del sistema, mediante el cual escribimos un nombre de archivo y elegimos un directorio, sobre el cual grabaremos información. Es importante precisar que el control no se ocupa del proceso de grabación de datos; su cometido es el permitirnos navegar por la estructura del sistema de archivos del equipo, y la selección de un nombre para el archivo a grabar. Entre las propiedades del control, podemos destacar las siguientes: _ Title. Contiene una cadena con el título que aparecerá en el cuadro de diálogo. _ InitialDirectory. Ruta inicial que mostrará el control al abrirse. _ Filter. Cadena con el tipo de archivos que mostrará el cuadro de diálogo al navegar por el sistema de archivos. El formato de esta cadena es el siguiente: NombreArchivo (*.Extensión)|*.Extensión; pudiendo situar varios filtros separados por el carácter de barra vertical ( | ). _ FilterIndex. Número que corresponde a alguno de los tipos de archivo establecidos en la propiedad Filter. _ FileName. Nombre del archivo en el que se realizará la escritura. _ DefaultExt. Cadena con la extensión por defecto a aplicar sobre el nombre del archivo. _ CheckFileExists. Valor lógico que nos permite comprobar si el archivo sobre el que vamos a grabar ya existe. _ ValidateNames. Valor lógico que comprobará si el nombre de archivo proporcionado contiene caracteres especiales, es decir, si se trata de un nombre válido. OpenFileDialog Este control muestra el cuadro de diálogo del sistema, mediante el que seleccionamos un archivo para poder abrirlo posteriormente, y realizar sobre las mismas operaciones de lectura-escritura. Al igual que en el control anterior, la lectura y escritura de información es algo que deberemos realizar por código, una vez que hayamos elegido el archivo mediante este cuadro de diálogo. Las propiedades de este control son prácticamente las mismas que las de SaveFileDialog, con algunas excepciones como las siguientes: _ Multiselect. Contiene un valor lógico, que nos permitirá la selección de múltiples archivos. _ ShowReadOnly. Permite mostrar la casilla de verificación para mostrar los archivos de sólo lectura. _ ReadOnlyChex. Permite obtener y establecer el valor para la casilla de verificación de sólo lectura del cuadro de diálogo. Ejercicio 1. Desarrollar una aplicación que permita seleccionar una imagen y luego poder guardar

esa imagen en otro lugar de la computadora.

Page 6: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

2. Digitar el siguiente Código dentro de cada uno de los Controles.

3. Dentro del Botón btnAbrir

4. Dentro del Botón btnPreview

5. Dentro del Botón btnNuevo

6. Dentro del Botón btnGuardar

Page 7: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

7. Dentro del Botón btnSalir

8. Ejecutar el Programa. 9. Presionar el Botón Abrir y seleccionar una imagen.

Acceso a datos con ADO .NET En este capítulo aprenderá a:

• Utilizar el Explorador de servidores para establecer una conexión con una base de datos.

• Crear un adaptador de datos que extraiga información específica de una base de datos.

• Crear un conjunto de datos que represente una o varias tablas de datos en un programa.

Page 8: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

• Utilizar los controles textbox, label y button para visualizar información de la base de datos y controles de navegación.

Para esto deberá revisar los siguientes temas del material adjunto a esta guía, el que se encuentra en formato PDF (Acrobat Reader); el archivo se llama. Acceso a datos con ADO_NET (PDF):

• Comparativa de ADO y ADO .NET • Beneficios de ADO .NET • Arquitectura de datos desconectados • DataSet • ADO .NET y XML • Visión general de ADO .NET • Las clases de ADO .NET • Estableciendo la conexión

Las clases de ADO .NET Las clases DataAdapter Como hemos comentado en anteriores apartados, los objetos DataAdapter (SqlDataAdapter y OleDbDataAdapter) van a desempeñar el papel de puente entre el origen de datos y el DataSet, permitiéndonos cargar el DataSet con la información de la fuente de datos, y posteriormente, actualizar el origen de datos con la información del DataSet. Un objeto DataAdapter puede contener desde una sencilla sentencia SQL, como hemos visto en el apartado anterior, hasta varios objetos Command. La clase DataAdapter dispone de cuatro propiedades, que nos van a permitir asignar a cada una, un objeto Command (SqlCommand u OleDbCommand) con las operaciones estándar de manipulación de datos. Estas propiedades son las siguientes:

• InsertCommand. Objeto de la clase Command, que se va a utilizar para realizar una inserción de datos.

• SelectCommand. Objeto de la clase Command que se va a utilizar para ejecutar una sentencia Select de SQL.

• UpdateCommand. Objeto de la clase Command que se va a utilizar para realizar una modificación de los datos.

• DeleteCommand. Objeto de la clase Command que se va a utilizar para realizar una eliminación de datos.

Un método destacable de las clases SqlDataAdapter/OleDbDataAdapter es el método Fill( ), que ejecuta el comando de selección que se encuentra asociado a la propiedad SelectCommand, los datos obtenidos del origen de datos se cargarán en el objeto DataSet que pasamos por parámetro. La Figura 344 muestra la relación entre los objetos DataAdapter y el objeto DataSet.

Fig. 344. Relación entre objetos DataAdapter y DataSet

Page 9: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

Para demostrar el uso de los objetos DataAdapter vamos a desarrollar un proyecto con el nombre PruDataAdapter. En esta aplicación vamos a utilizar el mismo objeto DataAdapter para realizar una consulta contra una tabla e insertar nuevas filas en esa misma tabla. En primer lugar diseñaremos el formulario del programa. Como novedad, introduciremos el control DataGrid, que trataremos con más profundidad en un próximo apartado. Baste decir por el momento, que a través del DataGrid visualizaremos una o varias tablas contenidas en un DataSet. La Figura 345 muestra el aspecto de esta aplicación en funcionamiento.

Figura 345. Formulario para operaciones con DataAdapter y DataGrid.

Respecto al código del formulario, en primer lugar, vamos a declarar varios objetos de acceso a datos a nivel de la clase para poder tenerlos disponibles en diversos métodos. Veamos el Código fuente 569. Imports System.Data.SqlClient Public Class Form1 Inherits System.Windows.Forms.Form Private oConexion As SqlConnection Private oDataSet As DataSet Private oDataAdapter As SqlDataAdapter '.... '....

Código fuente 569 En el siguiente paso escribiremos el procedimiento del evento Load del formulario, y el método CargarDatos( ), que se ocupa de cargar el DataSet, y asignárselo al DataGrid a través de su propiedad DataSource. Observe el lector que en el método CargarDatos( ) lo primero que hacemos es vaciar el DataSet, puesto que este objeto conserva los datos de tablas y registros; en el caso de que no limpiáramos el DataSet, se acumularían las sucesivas operaciones de llenado de filas sobre la tabla que contiene. Veamos el Código fuente 570. Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load ' crear conexión oConexion = New SqlConnection() oConexion.ConnectionString = "Server=(local);Database=MUSICA;uid=sa;pwd=;" ' crear adaptador oDataAdapter = New SqlDataAdapter() ' crear comandos para inserción, consulta con sus parámetros y asignarlos al adaptador

Page 10: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

Dim oCmdInsercion As New SqlCommand("INSERT INTO AUTORES " & _ "(IDAutor,Autor) VALUES(@IDAutor,@Autor)", oConexion) oDataAdapter.InsertCommand = oCmdInsercion oDataAdapter.InsertCommand.Parameters.Add(New SqlParameter("@IDAutor", SqlDbType.Int)) oDataAdapter.InsertCommand.Parameters.Add(New SqlParameter("@Autor", SqlDbType.NVarChar)) Dim oCmdConsulta As New SqlCommand("SELECT * FROM AUTORES", _oConexion) oDataAdapter.SelectCommand = oCmdConsulta ' crear conjunto de datos oDataSet = New DataSet() Me.CargarDatos() End Sub Private Sub CargarDatos() ' vaciar el dataset oDataSet.Clear() oConexion.Open() ' abrir conexión ' utilizar el adaptador para llenar el dataset con una tabla oDataAdapter.Fill(oDataSet, "Autores") oConexion.Close() ' cerrar conexión ' enlazar dataset con datagrid; ' en DataSource se asigna el dataset, ' en DataMember el nombre de la tabla del ' dataset que mostrará el datagrid Me.grdDatos.DataSource = oDataSet Me.grdDatos.DataMember = "Autores" End Sub

Código fuente 570 Finalmente, en el botón Grabar, escribiremos las instrucciones para insertar un nuevo registro en la tabla. Veamos el Código fuente 571. Private Sub btnGrabar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGrabar.Click Dim iResultado As Integer ' asignar valores a los parámetros para el comando de inserción oDataAdapter.InsertCommand.Parameters("@IDAutor").Value = Me.txtIDAutor.Text oDataAdapter.InsertCommand.Parameters("@Autor").Value = Me.txtAutor.Text ' abrir conexión oConexion.Open() ' ejecutar comando de inserción del adaptador iResultado = oDataAdapter.InsertCommand.ExecuteNonQuery() ' cerrar conexión oConexion.Close() Me.CargarDatos() MessageBox.Show("Registros añadidos: " & iResultado) End Sub

Código fuente 571 Navegación y edición de registros en modo desconectado Anteriormente vimos la forma de realizar operaciones de edición en modo conectado, sobre las tablas de una base de datos, empleando los objetos Command. Como también ya sabemos, la arquitectura de ADO .NET está orientada a un modelo de trabajo desconectado del almacén de datos, al que recurriremos sólo cuando necesitemos obtener los datos para su consulta y manipulación, o bien, cuando esos mismos datos desconectados, los hayamos modificado y tengamos que actualizarlos en la fuente de datos.

Page 11: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

El objeto DataSet, combinado con un grupo de objetos enfocados al mantenimiento de datos desconectados, como son DataAdapter, DataTable, DataRow, etc., nos va a permitir realizar tareas como la navegación entre los registros de una tabla del DataSet, además de la modificación de sus datos en las operaciones habituales de inserción, modificación y borrado de filas. El proyecto NavegaEdita que se acompaña como ejemplo, muestra los pasos necesarios que debemos dar para crear un sencillo mantenimiento de datos para una tabla albergada en un DataSet, junto a las típicas operaciones de navegación por las filas de dicha tabla. Seguidamente iremos desgranando el conjunto de pasos a realizar. Partimos de una sencilla base de datos en SQL Server, que contiene la tabla Clientes, con los campos más característicos de esta entidad de datos: código cliente, nombre, fecha ingreso, crédito. Una vez creado un nuevo proyecto en VB.NET, diseñaremos el formulario de la aplicación que como vemos en la Figura 346, a través de sus controles, nos permitirá realizar las operaciones mencionadas. Pasando a la escritura del código del programa, en primer lugar importaremos el espacio de nombres System.Data.SqlClient, y declararemos a nivel de clase un conjunto de variables para la manipulación de los datos. Veamos el Código fuente 572. Imports System.Data.SqlClient Public Class Form1 Inherits System.Windows.Forms.Form ' variables a nivel de clase para la manipulación de datos Private oDataAdapter As SqlDataAdapter Private oDataSet As DataSet Private iPosicFilaActual As Integer '.... '....

Código fuente 572

Figura 346. Formulario de navegación y edición manual de datos Como siguiente paso, escribiremos el manipulador del evento Load del formulario y un método para cargar los datos del registro actual en los controles del formulario, el Código fuente 573 muestra esta parte. Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load ' crear conexión Dim oConexion As SqlConnection oConexion = New SqlConnection() oConexion.ConnectionString = "Server=(local);" & _

Page 12: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

"Database=Gestion;uid=sa;pwd=;" ' crear adaptador Me.oDataAdapter = New SqlDataAdapter("SELECT * FROM Clientes", _ oConexion) ' crear commandbuilder Dim oCommBuild As SqlCommandBuilder = New SqlCommandBuilder(oDataAdapter) ' crear dataset Me.oDataSet = New DataSet() oConexion.Open() ' llenar con el adaptador el dataset Me.oDataAdapter.Fill(oDataSet, "Clientes") oConexion.Close() ' establecer el indicador del registro a mostrar de la tabla Me.iPosicFilaActual = 0 ' cargar columnas del registro en los controles del formulario Me.CargarDatos() End Sub Private Sub CargarDatos() ' obtener un objeto con la fila actual Dim oDataRow As DataRow oDataRow = Me.oDataSet.Tables("Clientes").Rows(Me.iPosicFilaActual) ' cargar los controles del formulario con ' los valores de los campos del registro Me.txtIDCliente.Text = oDataRow("IDCliente") Me.txtNombre.Text = oDataRow("Nombre") Me.txtFIngreso.Text = oDataRow("FIngreso") Me.txtCredito.Text = oDataRow("Credito") ' mostrar la posición actual del registro ' y el número total del registros Me.lblRegistro.Text = "Registro: " & _ Me.iPosicFilaActual + 1 & " de " & _ Me.oDataSet.Tables("Clientes").Rows.Count End Sub

Código fuente 573 Observe el lector que en el evento Load hemos creado un objeto CommandBuilder, pasándole como parámetro el DataAdapter. Como ya sabemos, un DataAdapter contiene una serie de objetos Command para las operaciones de consulta, inserción, etc. La misión en este caso del objeto CommandBuilder es la de construir automáticamente tales comandos y asignárselos al DataAdapter, ahorrándonos ese trabajo de codificación. En cuanto a las operaciones de navegación por la tabla, no hay un objeto, como ocurría con el Recordset de ADO, que disponga de métodos específicos de movimiento como MoveNext( ), MoveLast( ), etc. Lo que debemos hacer en ADO .NET, tal y como muestra el método CargarDatos() es obtener del DataSet, la tabla que necesitemos mediante su colección Tables, y a su vez, a la colección Rows de esa tabla, pasarle el número de fila/registro al que vamos a desplazarnos. En nuestro ejemplo utilizaremos la variable iPosicFilaActual, definida a nivel de clase, para saber en todo momento, la fila de la tabla en la que nos encontramos. El Código fuente 574 muestra el código de los botones de navegación, reunidos en el GroupBox Navegar del formulario. Private Sub btnAvanzar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAvanzar.Click ' si estamos en el último registro, ' no hacer movimiento If Me.iPosicFilaActual = _ (Me.oDataSet.Tables("Clientes").Rows.Count - 1) Then MessageBox.Show("Último registro") Else ' incrementar el marcador de registro y actualizar los controles con los datos del registro

Page 13: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

actual Me.iPosicFilaActual += 1 Me.CargarDatos() End If End Sub Private Sub btnRetroceder_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRetroceder.Click ' si estamos en el primer registro, no hacer movimiento If Me.iPosicFilaActual = 0 Then MessageBox.Show("Primer registro") Else ' disminuir el marcador de registro y actualizar los controles con los datos del registro actual Me.iPosicFilaActual -= 1 Me.CargarDatos() End If End Sub Private Sub btnPrimero_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrimero.Click ' establecer el marcador de registro en el primero Me.iPosicFilaActual = 0 Me.CargarDatos() End Sub Private Sub btnUltimo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnUltimo.Click ' establecer el marcador de registro en el primero obteniendo el número de filas que contiene la tabla menos uno Me.iPosicFilaActual = (Me.oDataSet.Tables("Clientes").Rows.Count - 1) Me.CargarDatos() End Sub

Código fuente 574

Respecto a las operaciones de edición, debemos utilizar los miembros del objeto tabla del DataSet, como se muestra en el Código fuente 575. Una vez terminado el proceso de edición, actualizaremos el almacén de datos original con el contenido del DataSet, empleando el DataAdapter. Private Sub btnInsertar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnInsertar.Click Dim oDataRow As DataRow ' obtener un nuevo objeto fila de la tabla del dataset oDataRow = Me.oDataSet.Tables("Clientes").NewRow() ' asignar valor a los campos de la nueva fila oDataRow("IDCliente") = Me.txtIDCliente.Text oDataRow("Nombre") = Me.txtNombre.Text oDataRow("FIngreso") = Me.txtFIngreso.Text oDataRow("Credito") = Me.txtCredito.Text ' añadir el objeto fila a la colección de filas de la tabla del dataset Me.oDataSet.Tables("Clientes").Rows.Add(oDataRow) End Sub Private Sub btnModificar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnModificar.Click Dim oDataRow As DataRow

Page 14: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

' obtener el objeto fila de la tabla del dataset ' en el que estamos posicionados oDataRow = Me.oDataSet.Tables("Clientes").Rows(Me.iPosicFilaActual) ' modificar las columnas de la fila excepto la correspondiente al identificador cliente oDataRow("Nombre") = Me.txtNombre.Text oDataRow("FIngreso") = Me.txtFIngreso.Text oDataRow("Credito") = Me.txtCredito.Text End Sub Private Sub btnActualizar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnActualizar.Click ' actualizar los cambios realizados en el dataset ' contra la base de datos real Me.oDataAdapter.Update(Me.oDataSet, "Clientes") End Sub

Código fuente 575

El caso del borrado de filas es algo diferente, por ello lo mostramos aparte del resto de operaciones de edición. En el Código fuente 576 vemos el código del botón Eliminar, dentro del cual obtenemos la fila a borrar mediante un objeto DataRow, procediendo a su borrado con el método Delete( ). Para actualizar los borrados realizados, empleamos el método GetChanges( ) del objeto DataTable, obteniendo a su vez, un objeto tabla sólo con las filas borradas; información esta, que pasaremos al DataAdapter, para que actualice la información en el origen de datos. Private Sub btnEliminar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEliminar.Click Dim oDataRow As DataRow ' obtener el objeto fila, de la tabla del dataset en el que estamos posicionados oDataRow = Me.oDataSet.Tables("Clientes").Rows(Me.iPosicFilaActual) oDataRow.Delete() ' borrar la fila mediante el método GetChanges(), obtenemos una tabla ' con las filas borradas Dim oTablaBorrados As DataTable oTablaBorrados = Me.oDataSet.Tables("Clientes").GetChanges(DataRowState.Deleted) ' actualizar en el almacén de datos las filas borradas Me.oDataAdapter.Update(oTablaBorrados) ' confirmar los cambios realizados Me.oDataSet.Tables("Clientes").AcceptChanges() ' reposicionar en la primera fila Me.btnPrimero.PerformClick() End Sub

Código fuente 576

Asesoría didáctica 2 Una base de datos es una colección de datos clasificados y estructurados que son guardados en uno o varios ficheros pero referenciados como si de un único fichero se tratara. Para crear y manipular Bases de Datos Relacionales, objetivo de esta unidad, existen en el mercado varios sistemas administradores de bases de datos; por ejemplo, Access, SQL Server, Oracle y DB2. Otros sistemas administradores de bases de datos de interés y de libre distribución son MySQL y PostgreSQL. Para el desarrollo de las actividades usted deberá revisar el compendio con los temas relacionados al crear proyectos de instalación, adicionalmente dispone de este material de apoyo que le servirá de referencia para la elaboración de las tareas correspondientes a este mes.

Page 15: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

Crear o agregar un proyecto de instalación Los proyectos de instalación sirven para crear archivos de Windows Installer (.msi), que se utilizan con el fin de distribuir la aplicación para su instalación en otro equipo o servidor Web. Existen dos tipos de proyectos de instalación: los proyectos de instalación estándar creados por instaladores para aplicaciones Windows en un equipo de destino, y los proyectos de instalación Web creados por instaladores para aplicaciones Web en un servidor Web. Nota: Los proyectos de instalación Web no están disponibles en la edición Standard de Visual Basic .NET. Para obtener más información vea Características de Visual Basic Standard.

Para crear un nuevo proyecto de instalación

1. En el menú Archivo, elija Agregar proyecto y después haga clic en Nuevo proyecto.

2. En el cuadro de diálogo Agregar nuevo proyecto, seleccione la carpeta Proyectos de instalación e implementación.

3. Elija Proyecto de instalación para una instalación estándar o Proyecto de instalación Web para el Web.

Para agregar un proyecto de instalación existente a una solución

1. En el menú Archivo, elija Agregar proyecto y después haga clic en Proyecto existente.

2. En el cuadro de diálogo Agregar proyecto existente, busque en la ubicación del proyecto de instalación y haga clic en Abrir.

Agregar elementos a un proyecto de implementación

Para crear un instalador, primero hay que especificar qué hay que incluir en el instalador y en qué lugar del equipo de destino hay que instalarlo. Para ello, hay que agregar elementos al proyecto de implementación.

Los tipos de elementos que se pueden agregar a un proyecto de implementación son los resultados del proyecto, archivos, módulos de combinación y componentes.

Para agregar resultados del proyecto o un archivo a un proyecto de implementación

1. Abra el Editor del sistema de archivos. Para obtener más información, vea Abrir los editores de implementación.

2. Seleccione la carpeta del equipo de destino donde se vaya a instalar el elemento.

Nota: Es posible crear nuevas carpetas en el equipo de destino. Para obtener más información vea Agregar y eliminar carpetas en el Editor del sistema de archivos.

3. En el menú Archivo, elija Agregar y después haga clic en Resultados del proyecto o Archivo. En el cuadro de diálogo que aparece, seleccione el elemento que desea agregar.

Nota: También se pueden agregar elementos a un proyecto de implementación haciendo clic con el botón secundario del mouse en el nodo del proyecto en Explorador de soluciones. Todos los elementos agregados de esta forma se colocarán en la carpeta predeterminada. Para las aplicaciones estándar, la carpeta predeterminada es la carpeta Aplicación, y para las aplicaciones Web es la carpeta Aplicación Web. Los elementos se pueden mover a otra carpeta.

Para agregar un módulo de combinación o un componente a un proyecto de implementación

Page 16: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

1. Seleccione el proyecto de implementación en el Explorador de soluciones. 2. En el menú Archivo, elija Agregar y, a continuación, haga clic en Módulo de

combinación o Componente. En el cuadro de diálogo que aparece, seleccione el elemento que desea agregar.

Presentación de Datos Utilizando el control DataGrid Este control, del que ya realizamos una pequeña demostración en un apartado anterior, nos va a permitir realizar enlace complejo de datos con ADO .NET. Se trata de la versión mejorada del control DataGrid de ADO, disponible en Visual Basic 6, pero con una serie de funcionalidades optimizadas y otras nuevas añadidas. Para utilizar algunas de sus características, crearemos un proyecto de prueba con el nombre DataGridPru (hacer clic aquí para acceder a este ejemplo), consistente en un formulario MDI, con una serie de opciones de menú, a través de las cuales, mostraremos diversas características de este control y algunas otras adicionales sobre ADO .NET. La opción de menú DataGrid + Normal mostrará el formulario frmNormal, que contiene un sencillo DataGrid con una tabla. Podemos editar los registros de la tabla y añadir nuevos; al trabajar en desconexión, hasta que no pulsemos el botón Actualizar de este formulario, el objeto DataAdapter del mismo no actualizará los datos del DataSet hacia la base de datos física. Otra característica incluida por defecto es la ordenación de las filas por columna al hacer clic en su título. Finalmente, al redimensionar el formulario, también cambiará el tamaño del DataGrid, puesto que hemos utilizado su propiedad Anchor para anclarlo a todos los bordes de la ventana. La Figura 350 muestra este formulario.

Figura 350. DataGrid editable

Page 17: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

El Código fuente 582 muestra el código principal de este formulario. Recordamos al lector, la necesidad de crear un objeto CommandBuilder para el DataAdapter, ya que en caso contrario, al intentar actualizar el DataSet contra la base de datos, se producirá un error.

El Código fuente 582

Acceso a Elementos de un DataGrid en el Cliente Utilizamos ASP .NET y JavaScript

Introducción

Cuando utilizamos un DataGrid en ASP .NET podemos necesitar tener acceso a más de un elemento de este, como por ejemplo, en el caso de que queramos llamar a otra página pasándole más de un argumento. El problema

Por ejemplo, si tenemos este DataGrid:

Nos puede interesar abrir una página con el nombre del beneficiario y el número del cliente. Por supuesto, desde el evento OnSelectedIndexChanged del DataGrid podríamos tener acceso a esos elementos, pero eso supone un roolback al servidor, con la pérdida de tiempo que eso supone. También tenemos la opción de utilizando una HyperLinkColumn en el DataGrid, asociarle un campo del DataSet, pero solo podemos asignarle un campo, pero no varios. En este ejemplo, nos interesa abrir una página pop-up de envío de mensajes, y le queremos pasar el número del cliente y el nombre del beneficiario.

Page 18: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

La solución La solución a este problema pasa por utilizar una función JavaScript para navegar por el DOM del documento y acceder a los valores de las columnas que nos interesen. En primer lugar, agregamos a nuestro DataGrid una columna HyperLinkColumn: <asp:HyperLinkColumn Text="Enviar Mensaje" NavigateUrl="javascript:NuevoMensaje(this)"></asp:HyperLinkColumn> De esta manera, cuando hagamos clic en esta columna, llamamos a la función JavaScript NuevoMensaje, pasándole como argumento this, que es una referencia al enlace donde hemos pulsado. La función JavaScript es la siguiente: function NuevoMensaje(obj) { Número = obj.document.activeElement.parentElement.parentElement.firstChild.innerText; Nombre = obj.document.activeElement.parentElement.parentElement.firstChild.nextSibling.innerText; dirección = "NuevoMensaje.aspx"; dirección += "?Numero=" + Número; dirección += "&Nombre=" + Nombre; window.open(direccion,"Mensajes","width=500,height=400,toolbars=no,menubar=no,scrollbars=yes,resizable=yes"); }

Para obtener tanto el número como el nombre, navegamos por el objeto actual (obj.document.activeElement) hacia arriba, recorriendo el árbol de la estructura del elemento Table (la representación en HTML del DataGrid) hasta el elemento TR (mediante parentElement), que sería:

obj.document.activeElement.parentElement.parentElement

Para obtener el número, una vez que estamos en el elemento TR, en la fila, descendemos por el árbol hasta la primera celda TD (mediante firstChild), y obtenemos el texto representado en ella (mediante innerText).

Para obtener el nombre, una vez que estamos en el elemento raíz de nuestro árbol (TR), nos movemos hacia la siguiente celda (mediante nextSibling) y obtenemos de nuevo el contenido de esa celda (mediante innerText)

De esta manera, podemos navegar por la fila seleccionada para conseguir los valores que necesitemos.

Una vez que tenemos los valores deseados, creamos una variable donde ponemos la dirección de la página y le agregamos en la QueryString estos dos valores. En la página "NuevoMensaje.aspx" los leeremos de esta manera:

Request.QueryString["Número"] Request.QueryString["Nombre"]

Page 19: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

Para abrir esta página mediante una ventana pop-up, utilizamos el método window.open, donde el primer argumento es la página. El segundo argumento, optativo, es el nombre de la ventana, y el tercer argumento, también optativo son atributos de la ventana.

Personalizando el Control DataGrid

http://www.elguille.info/colabora/NET2005/Percynet_PersonalizandoDataGrid.htm

Fuentes de datos para el control de DataGrid

Las fuentes de datos válidos para la DataGrid incluyen:

• Clase DataTable • Clase DataView • Clase DataSet • Clase DataViewManager

Si su fuente es un conjunto de datos, puede ser un objeto en el formulario o un objeto que se pasó al formulario a través de un servicio Web XML. Puede unir a los conjuntos de datos, ya sean escritos o no escritos.

Puede unir a las siguientes estructuras si sus elementos exponen propiedades públicas: Cualquier componente que implemente la interfaz IList. Esto incluye:

• Arreglos de una sola dimensión. • Cualquier componente que implemente la interfaz IListSource. • Cualquier componente que implemente la interfaz IBindingList.

Un uso común del control de DataGrid es mostrar una sola tabla de datos desde un conjunto de datos. Sin embargo, también se puede utilizar el control para mostrar múltiples tablas, incluyendo tablas relacionadas. La presentación de la cuadrícula se ajusta automáticamente de acuerdo con la fuente de datos:

• Tabla individual. La tabla aparece en una cuadrícula.

• Tablas múltiples. La cuadrícula puede mostrar una vista de árbol en la que los usuarios pueden navegar para localizar la tabla que desean mostrar.

Cuando el control de DataGrid muestra una tabla y la propiedad AllowSorting se configura a verdadero, los datos se pueden clasificar al hacer clic en los encabezados de la columna. El usuario también puede agregar filas y editar celdas.

La relación entre un conjunto de tablas se muestra utilizando una estructura principal / secundaria de navegación. Las tablas principales son el nivel más alto de datos, y las tablas secundarias son aquellas tablas de datos que se derivan de los listados individuales en las tablas principales. Los expansores se muestran en cada fila principal que contenga una tabla secundaria. Al hacer clic en un ampliador, se genera una lista de vínculos tipo Web en las tablas secundarias, que cuando se seleccionan causan que las tablas secundarias aparezcan en pantalla. Al hacer clic en el icono "mostrar / ocultar las filas principales" ocultará la información acerca de la tabla principal (o causará que reaparezca si la ha ocultado previamente). Un botón hacia atrás permite la navegación inversa en la tabla vista previamente.

Algunas características del control de DataGrid, como colores, fuente de texto, alterar colores de fondo y propiedades de los datos, se puede formatear en el ambiente de diseño utilizando la ventana Propiedades. Están disponibles varias propiedades tales como CaptionForeColor, CaptionBackColor y CaptionFont.

Page 20: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

Columnas y filas

Una DataGrid consiste en una colección de objetos DataGridTableStyle dentro de la propiedad TableStyles del control de DataGrid. Un estilo de tabla puede contener una colección de objetos DataGridColumnStyle incluidas en la propiedad GridColumnStyles del objeto DataGridTableStyle. Puede editar las propiedades TableStyles y ColumnStyles con editores de colección a los que se accede a través de la ventana Propiedades.

Cualquier objeto DataGridTableStyle asociado con el control de DataGrid puede ser accedido a través de GridTableStylesCollection. GridTableStylesCollection se puede editar en el diseñador con el Editor de la colección DataGridTableStyle, o de manera programática a través de la propiedad TableStyles del control de DataGrid, como se muestra en el ejemplo que se encuentra más abajo.

Los estilos de la tabla y los estilos de la columna se sincronizan con los objetos DataTable y DataColumn al establecer sus propiedades MappingName en las propiedades TableName y ColumnName apropiadas. Cuando un objeto DataGridTableStyle sin estilos de columna se agrega a una unión de control DataGrid a una fuente de datos válida, y la propiedad MappingName del estilo de la tabla se configura a una propiedad TableName válida, se crea una colección de objetos DataGridColumnStyle para ese estilo de tabla. Para cada objeto DataColumn que se encuentra en la colección Columnas del objeto DataTable, se agrega un objeto DataGridColumnStyle correspondiente al objeto GridColumnStylesCollection, al cual se accede a través de la propiedad GridColumnStyles del objeto DataGridTableStyle. Se pueden agregar o eliminar columnas de la cuadrícula utilizando el método Agregar o Eliminar en el objeto GridColumnStylesCollection.

Una colección de tipos de columna extiende la clase DataGridColumnStyle con capacidades de formateo y edición enriquecidas. Todos los tipos de columna se heredan de la clase base DataGridColumnStyle. La clase que se crea depende de la propiedad DataType del objeto DataColumn en el cual se basa DataGridColumn. Por ejemplo, un objeto DataColumn con su propiedad DataType configurada a System.Boolean se asociará con DataGridBoolColumn. La siguiente tabla describe cada uno de estos tipos de columna.

DataGridTextBoxColumn Acepta y muestra los datos como cadenas formateadas o no formateadas.

Page 21: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

Las capacidades de edición son las mismas que las que se utilizan para editar datos en un TextBox sencillo. Se hereda de DataGridColumnStyle.

DataGridBoolColumn Acepta y muestra valores verdaderos, falsos y nulos. Se hereda de DataGridColumnStyle.

Eventos

Aparte de los eventos de control comunes como MouseDown, Intro y Desplazar, el control de DataGrid soporta los eventos asociados con la edición y navegación dentro de la cuadrícula. La propiedad CurrentCell determina cuál celda se selecciona. El evento CurrentCellChanged surge cuando el usuario navega a una celda nueva. Cuando el usuario navega a una tabla nueva (a través de las relaciones principales / secundarias), el evento Navegar surge. El evento BackButtonClick surge cuando el usuario hace clic en el botón posterior cuando ve una tabla secundaria, y el evento ShowParentDetailsButtonClick surge cuando se hace clic en el icono "mostrar / ocultar filas principales.

Ejemplo 1. Para poder mostrar los datos en la tabla, primero debe unir el control de DataGrid al

conjunto de datos. 2. Declare un nuevo estilo de tabla y establezca el nombre de su correlación.

3. Declare un estilo de columna nuevo y establezca el nombre de su correlación y otras

propiedades. 4. Invoque el método Agregar del objeto GridColumnStylesCollection para agregar la

columna al estilo de la tabla. 5. Invoque el método Agregar del objeto GridTableStylesCollection para agregar el estilo

de tabla a la cuadrícula de datos.

VB .NET

...

DataGrid1.SetDataBinding(DsCustomers1, "Clientes") Dim tableStyle As New DataGridTableStyle tableStyle.MappingName = "Customers" Dim myDataCol As New DataGridBoolColumn myDataCol.HeaderText = "My New Column" myDataCol.MappingName = "Current" tableStyle.GridColumnStyles.Add(myDataCol) DataGrid1.TableStyles.Add(tableStyle) ...

C# .NET

... dataGrid1.SetDataBinding(DsCustomers1, "Clientes"); DataGridTableStyle tableStyle = new DataGridTableStyle(); tableStyle.MappingName = "Customers";

Page 22: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

DataGridBoolColumn myDataCol = new DataGridBoolColumn(); myDataCol.HeaderText = "My New Column"; myDataCol.MappingName = "Current"; tableStyle.GridColumnStyles.Add(myDataCol); dataGrid1.TableStyles.Add(tableStyle); ...

Ahora veamos un ejemplo sencillo de cómo aplicar los conceptos explicados anteriormente. En este ejemplo (formatear una datagrid usando estilos) se muestra cómo poco a poco vamos creando estilos de columnas y el estilo de tabla, los cuales serán usados para formatear los datos de cada columna de nuestra datagrid. Revise el código.

A continuación, sigue el código en Visual Basic NET:

Imports System Imports System.Drawing Imports System.Collections Imports System.ComponentModel Imports System.Windows.Forms Imports System.Data Public Class Form1 Inherits System.Windows.Forms.Form ' ... ' código generado por el diseñador de Windows form ' ... Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) _ Handles MyBase.Load 'establecemos la referencia cultural del subproceso actual Español-Perú. System.Threading.Thread.CurrentThread.CurrentCulture = _ New System.Globalization.CultureInfo("es-PE") Dim TableName As New String("MyTable") Dim ObjEstiloTabla As New DataGridTableStyle With ObjEstiloTabla .MappingName = TableName .AlternatingBackColor = Color.Coral .BackColor = Color.Orange .ForeColor = Color.White .HeaderForeColor = Color.Blue .LinkColor = SystemColors.Control .AllowSorting = False .HeaderFont = New System.Drawing.Font("Verdana", 8.25F, _ System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, _ CType(1, System.Byte)) End With Me.DataGrid1.TableStyles.Add(ObjEstiloTabla) Me.DataGrid1.DataSource = GetMyTable(TableName) Dim ObjEstiloColumna As DataGridTextBoxColumn 'formateamos la columna 0 ó "Integer" para datos enteros ObjEstiloColumna = DataGrid1.TableStyles(0).GridColumnStyles(0) If Not (ObjEstiloColumna Is Nothing) Then ObjEstiloColumna.Format = "n1" End If

Page 23: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

'formateamos la columna 1 ó "Double" para datos de tipo double ObjEstiloColumna = DataGrid1.TableStyles(0).GridColumnStyles(1) ' If Not (ObjEstiloColumna Is Nothing) Then ObjEstiloColumna.Format = "f3" End If 'formateamos los datos de la columna anterior como moneda nacional '(en este caso, usaremos la moneda nacional peruana) ObjEstiloColumna = DataGrid1.TableStyles(0).GridColumnStyles(2) ' If Not (ObjEstiloColumna Is Nothing) Then ObjEstiloColumna.Format = "c2" End If 'formateamos los datos de la columna 3 ó "Date" como Date ObjEstiloColumna = DataGrid1.TableStyles(0).GridColumnStyles(3) ' If Not (ObjEstiloColumna Is Nothing) Then ObjEstiloColumna.Format = "d" ObjEstiloColumna.Width = 100 End If End Sub Private Function GetMyTable(ByVal TableName As String) As DataTable Dim dt As New DataTable(TableName) Dim RowsCount As Integer = 10 dt.Columns.Add(New DataColumn("Integer", GetType(Integer))) dt.Columns.Add(New DataColumn("Double", GetType(Double))) dt.Columns.Add(New DataColumn("s/. Double", GetType(Double))) dt.Columns.Add(New DataColumn("Date", GetType(DateTime))) Dim r As New Random 'objeto que generará un número aleatorio Dim i As Integer While i < RowsCount Dim d As Double = 1000 * r.NextDouble() Dim dr As DataRow = dt.NewRow() dr(0) = Fix(d) dr(1) = d dr(2) = d dr(3) = DateTime.Now.Date.AddMonths(CType(r.NextDouble * 21, Double)) dt.Rows.Add(dr) i += 1 End While Return dt End Function End Class

Page 24: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

Espacios de nombres usados en el código de este artículo: System.Drawing System.Collections System.ComponentModel System.Data System.Threading System.Globalization

Agregando funcionalidad al control DataGrid con VB .NET

http://www.elguille.info/colabora/puntoNET/yosall_datagrid.htm

En este ejemplo de código vamos a ver cómo agregar funcionalidad al Control DataGrid con VB .NET

Entre las funcionalidades que agregaremos están el poder agregar columnas calculadas dinámicamente al DataGrid, poder darle formato a las columnas, poder evitar o permitir agregar más registros en el DataGrid (el registro que aparece al final del DataGrid con un asterisco *), poder validar las teclas presionadas por el usuario a fin de permitir solo números o bien convertir las letras minúsculas a MAYÚSCULAS y finalmente el poder sumar una columna completa de manera rápida y colocar su resultado dinámicamente en un control Label.

'**************************************************************************** '* Código realizado por Eduardo Puchades Fuentes © (Mexicano) ;-) * '**************************************************************************** Public Class Form1 Inherits System.Windows.Forms.Form #Region "Código generado por el Diseñador de Windows Forms"

Page 25: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

#End Region Private Sub CheckBox5_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox5.CheckedChanged ' Aquí cambiamos el valor de AllowNew para ' evitar o permitir agregar registros ' a nuestro DataGrid Dim Valor As Boolean If sender.Checked = True Then Valor = False Else Valor = True End If 'Instanciamos y creamos nuestro manejador Dim cm As CurrencyManager cm = CType(BindingContext(DataSet1, Me.DataSet1.Tables(0).TableName), CurrencyManager) 'Instanciamos y creamos un DataView asociado a nuestro manejador CurrencyManager Dim Dv As DataView = CType(cm.List, DataView) 'Asignamos el valor que deseamos para evitar o permitir nuevos registros Dv.AllowNew = Valor End Sub Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'Cargamos nuestro DataSet leyendo nuestro archivo XML que contiene los datos Me.DataSet1.ReadXml("..\Datos.xml") 'Asignamos el DataSource y el DataMember de nuestro DataGrid Me.DataGrid1.DataSource = Me.DataSet1 Me.DataGrid1.DataMember = Me.DataSet1.Tables(0).TableName End Sub Private Sub CheckBox2_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox2.CheckedChanged 'Aquí vamos a agregar una columna en tiempo de ejecución 'llamada Cantidad para que el usuario pueda cambiar la cantidad If sender.Checked = True Then 'Cambiamos el estado del cursor poniendo un reloj de arena Me.Cursor = System.Windows.Forms.Cursors.WaitCursor 'Declaramos una variable de DataColumn y creamos la columna Dim MiColum As DataColumn = New DataColumn MiColum.DataType = System.Type.GetType("System.Int32") MiColum.AllowDBNull = False MiColum.DefaultValue = 1 MiColum.Caption = "Cantidad" MiColum.ColumnName = "Cantidad" 'Agregamos la columna a la colección de columnas del DataSet1 Me.DataSet1.Tables(0).Columns.Add(MiColum) 'Regresamos el estado del cursor a normal Me.Cursor = System.Windows.Forms.Cursors.Default End If End Sub Private Sub CheckBox3_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox3.CheckedChanged

Page 26: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

'Aquí vamos a agregar una columna calculada dinámicamente 'y llamada SubTotal para multiplicar la columna Precio x cantidad If sender.Checked = True Then 'Verificamos que ya esté agregada la columna de Cantidad If Me.DataSet1.Tables(0).Columns.Count = 3 And Me.CheckBox2.Checked = False Then Me.CheckBox2.Checked = True 'Cambiamos el estado del cursor poniendo un reloj de arena Me.Cursor = System.Windows.Forms.Cursors.WaitCursor 'Declaramos una variable de DataColumn y creamos la columna Dim MiColum As DataColumn = New DataColumn MiColum.DataType = System.Type.GetType("System.Decimal") MiColum.AllowDBNull = False MiColum.DefaultValue = 1 MiColum.Caption = "Sub Total" MiColum.ColumnName = "SubTotal" 'Aplicamos el tipo de operación que deseamos MiColum.Expression = "Precio * Cantidad" 'Agregamos la columna a la colección de columnas del DataSet1 Me.DataSet1.Tables(0).Columns.Add(MiColum) 'Regresamos el estado del cursor a normal Me.Cursor = System.Windows.Forms.Cursors.Default End If End Sub Private Sub CheckBox4_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox4.CheckedChanged 'Aquí vamos a agregar una columna calculada dinámicamente 'y llamada Impuesto para multiplicar la columna SubTotal x .1 If sender.Checked = True Then 'Verificamos que ya esté agregada la columna de Subtotal If Me.DataSet1.Tables(0).Columns.Count <= 4 And Me.CheckBox3.Checked = False Then Me.CheckBox3.Checked = True 'Cambiamos el estado del cursor poniendo un reloj de arena Me.Cursor = System.Windows.Forms.Cursors.WaitCursor 'Declaramos una variable de DataColumn y creamos la columna Dim MiColum As DataColumn = New DataColumn MiColum.DataType = System.Type.GetType("System.Decimal") MiColum.AllowDBNull = False MiColum.DefaultValue = 1 MiColum.Caption = "Impuesto" MiColum.ColumnName = "Impuesto" 'Aplicamos el tipo de operación que deseamos MiColum.Expression = "SubTotal * .1" 'Agregamos la columna a la colección de columnas del DataSet1 Me.DataSet1.Tables(0).Columns.Add(MiColum) 'Regresamos el estado del cursor a normal Me.Cursor = System.Windows.Forms.Cursors.Default End If End Sub Private Sub CheckBox6_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox6.CheckedChanged 'Aquí vamos a agregar una columna calculada dinámicamente 'y llamada Total para sumar la columna Subtotal + Impuesto If sender.Checked = True Then 'Verificamos que ya esté agregada la columna de Impuesto If Me.DataSet1.Tables(0).Columns.Count <= 5 And Me.CheckBox4.Checked = False Then Me.CheckBox4.Checked = True 'Cambiamos el estado del cursor poniendo un reloj de arena Me.Cursor = System.Windows.Forms.Cursors.WaitCursor

Page 27: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

'Declaramos una variable de DataColumn y creamos la columna Dim MiColum As DataColumn = New DataColumn MiColum.DataType = System.Type.GetType("System.Decimal") MiColum.AllowDBNull = False MiColum.DefaultValue = 1 MiColum.Caption = "Total" MiColum.ColumnName = "Total" 'Aplicamos el tipo de operación que deseamos MiColum.Expression = "SubTotal + Impuesto" 'Agregamos la columna a la colección de columnas del DataSet1 Me.DataSet1.Tables(0).Columns.Add(MiColum) 'Regresamos el estado del cursor a normal Me.Cursor = System.Windows.Forms.Cursors.Default End If End Sub Private Sub DataGrid1_CurrentCellChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles DataGrid1.CurrentCellChanged 'Aquí vamos a sumar toda la columna llamada Total 'Comprobamos que nuestro DataGrid tenga nuestra columna llamada Total If Me.CheckBox7.Checked = True And Me.DataSet1.Tables(0).Columns.Count = 7 Then 'Declaramos una variable objeto Dim objSum As Object ' Y Ocupamos la Función Compute del DataTable para sumar y asignar el valor a la variable ' Note que estamos ocupando el Nombre de la columna agregada como Total en Sum(Total) ' y después de la coma estamos agregando un filtro para que sume únicamente los registros donde el ' Valor de la columna Total es mayor que 0, así evitamos que al utilizar números negativos ' Estos ocasionen un resultado inesperado, puede ocupar ese filtro para sumar únicamente ' Los registros de un producto determinado o un producto con descuento por ejemplo. objSum = Me.DataSet1.Tables(0).Compute("Sum(Total)", "Total > 0") ' Convertimos el resultado a un string y le damos formato de Moneda Me.Label1.Text = Format(CStr(objSum), "Currency") End If End Sub Private Sub CreaFormato() 'Aquí vamos a aplicar un formato a nuestro DataGrid 'y vamos a validar las teclas presionadas en las columnas Precio y Cantidad 'Borramos la tabla de estilos en el DataGrid si es que existe Me.DataGrid1.TableStyles.Clear() 'Instanciamos y creamos una nueva tabla de estilos Dim TableStyle1 As New DataGridTableStyle 'Le indicamos el nombre de la tabla de nuestro DataSet TableStyle1.MappingName = Me.DataSet1.Tables(0).TableName 'Creamos un formato de celdas Alternando el color blanco del fondo 'con un color gris claro TableStyle1.AlternatingBackColor = Color.LightGray 'Instanciamos y creamos nuestro primer formato de columna Dim TextCol1 As New DataGridTextBoxColumn 'Le indicamos el nombre de la columna

Page 28: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

TextCol1.MappingName = "IDProducto" 'Le indicamos el nombre que deseamos aparezca en el encabezado de la columna TextCol1.HeaderText = "IDProducto" 'Le indicamos el ancho de la columna TextCol1.Width = 70 'Agregamos nuestro formato de columna a la colección de nuestra Tabla de estilos TableStyle1.GridColumnStyles.Add(TextCol1) 'Instanciamos y creamos nuestro segundo formato de columna Dim TextCol2 As New DataGridTextBoxColumn 'Le indicamos el nombre de la columna TextCol2.MappingName = "Nombre" 'Le indicamos el nombre que deseamos aparezca en el encabezado de la columna TextCol2.HeaderText = "Nombre" 'Le indicamos el ancho de la columna TextCol2.Width = 120 'Agregamos nuestro formato de columna a la colección de nuestra Tabla de estilos TableStyle1.GridColumnStyles.Add(TextCol2) ¡Atención! 'Aquí vamos a instanciar y crear nuestro tercer formato de columna 'Pero puede usted notar que estoy ocupando una clase llamada 'DataGridTextBoxColumnSoloNumeros esta clase es una clase que previamente he 'Creado y esta clase es un componente heredado de DataGridTextBoxColumn 'A esta clase heredada le he agregado la Funcionalidad de permitirnos 'Validar las teclas que presionan los usuarios, evitando de esta manera 'que inserten letras donde solo deben ir números. 'En esta clase también he agregado un ejemplo para poder convertir 'las teclas presionadas por el usuario de minúsculas a MAYÚSCULAS 'Instanciamos y creamos nuestro Tercer Formato de columna 'ocupando la clase antes mencionada Dim TextCol3 As New DataGridTextBoxColumnSoloNumeros 'Le indicamos que la alineación la queremos del lado derecho TextCol3.Alignment = HorizontalAlignment.Right 'Le indicamos el nombre de la columna TextCol3.MappingName = "Precio" 'Le indicamos el nombre que deseamos aparezca en el encabezado de la columna TextCol3.HeaderText = "Precio" 'Le indicamos el ancho de la columna TextCol3.Width = 60 'Aquí con la letra "c" le estamos indicando que queremos un formato currency (Moneda) TextCol3.Format = "c" 'Agregamos nuestro formato de columna a la colección de nuestra Tabla de estilos TableStyle1.GridColumnStyles.Add(TextCol3) 'Instanciamos y creamos nuestro Cuarto Formato de columna 'ocupando la clase antes mencionada Dim TextCol4 As New DataGridTextBoxColumnSoloNumeros 'Le indicamos que la alineación la queremos del lado derecho TextCol4.Alignment = HorizontalAlignment.Right 'Le indicamos el nombre de la columna TextCol4.MappingName = "Cantidad" 'Le indicamos el nombre que deseamos aparezca en el encabezado de la columna TextCol4.HeaderText = "Cantidad" 'Le indicamos el ancho de la columna TextCol4.Width = 60 'Aquí con la letra "g" le estamos indicando que queremos un formato de número general TextCol4.Format = "g" 'Agregamos nuestro formato de columna a la colección de nuestra Tabla de estilos

Page 29: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

TableStyle1.GridColumnStyles.Add(TextCol4) 'Instanciamos y creamos nuestro segundo formato de columna Dim TextCol5 As New DataGridTextBoxColumn 'Le indicamos que la alineación la queremos del lado derecho TextCol5.Alignment = HorizontalAlignment.Right 'Le indicamos el nombre de la columna TextCol5.MappingName = "SubTotal" 'Le indicamos el nombre que deseamos aparezca en el encabezado de la columna TextCol5.HeaderText = "Sub total" 'Le indicamos el ancho de la columna TextCol5.Width = 60 'Aquí con la letra "c" le estamos indicando que queremos un formato currency (Moneda) TextCol5.Format = "c" 'Agregamos nuestro formato de columna a la colección de nuestra Tabla de estilos TableStyle1.GridColumnStyles.Add(TextCol5) 'Instanciamos y creamos nuestro segundo formato de columna Dim TextCol6 As New DataGridTextBoxColumn 'Le indicamos que la alineación la queremos del lado derecho TextCol6.Alignment = HorizontalAlignment.Right 'Le indicamos el nombre de la columna TextCol6.MappingName = "Impuesto" 'Le indicamos el nombre que deseamos aparezca en el encabezado de la columna TextCol6.HeaderText = "Impuesto" 'Le indicamos el ancho de la columna TextCol6.Width = 60 'Aquí con la letra "c" le estamos indicando que queremos un formato currency (Moneda) TextCol6.Format = "c" 'Agregamos nuestro formato de columna a la colección de nuestra Tabla de estilos TableStyle1.GridColumnStyles.Add(TextCol6) 'Instanciamos y creamos nuestro segundo formato de columna Dim TextCol7 As New DataGridTextBoxColumn 'Le indicamos que la alineación la queremos del lado derecho TextCol7.Alignment = HorizontalAlignment.Right 'Le indicamos el nombre de la columna TextCol7.MappingName = "Total" 'Le indicamos el nombre que deseamos aparezca en el encabezado de la columna TextCol7.HeaderText = "Total" 'Le indicamos el ancho de la columna TextCol7.Width = 60 'Aquí con la letra "c" le estamos indicando que queremos un formato currency (Moneda) TextCol7.Format = "c" 'Agregamos nuestro formato de columna a la colección de nuestra Tabla de estilos TableStyle1.GridColumnStyles.Add(TextCol7) Me.DataGrid1.TableStyles.Add(TableStyle1) End Sub Private Sub CheckBox1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox1.CheckedChanged If sender.Checked = True Then CreaFormato() Else Me.DataGrid1.TableStyles.Clear() End If

Page 30: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

End Sub End Class

Aquí termina el código del Form1

NOTA: Este código no incluye la sección de código generado por el diseñador de Windows Forms.

Esta es la clase heredada de DataGridTextBoxColumn para validar las teclas presionadas en el DataGrid.

Option Strict Off Option Explicit On Imports Microsoft.VisualBasic Imports System Imports System.ComponentModel Imports System.Windows.Forms Public Class DataGridTextBoxColumnSoloNumeros Inherits DataGridTextBoxColumn Public Sub New() MyBase.New() AddHandler Me.TextBox.KeyPress, New System.Windows.Forms.KeyPressEventHandler(AddressOf HandleKeyPress) End Sub Private Sub HandleKeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs) 'Aquí puede cambiar el código para que el usuario únicamente presione letras 'o para cambiar las letras minúsculas por MAYÚSCULAS con el ejemplo siguiente 'If e.KeyChar.IsLower(e.KeyChar) Then ' e.KeyChar.ToUpper(e.KeyChar) 'End If 'Ignora la tecla presionada si no es dígito o tecla de control If e.KeyChar.IsDigit(e.KeyChar) Then e.Handled = False ElseIf e.KeyChar.IsControl(e.KeyChar) Then e.Handled = False Else e.Handled = True End If 'Ignora la tecla presionada si el valor es más grande de cuatro dígitos If ((Me.TextBox.Text.Length >= 4) AndAlso Not (e.KeyChar.IsControl(e.KeyChar)) AndAlso Me.TextBox.SelectionLength = 0) Then e.Handled = True End If End Sub End Class Enlace de Datos con ADO .NET y DATA Bind http://www.elguille.info/colabora/NET2005/Percynet_EnlaceDatos_ParteI.htm

Page 31: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

Para mayor referencia puede consultar esta página y descargarse los archivos digitales como ejemplos. Enlace o vinculación de datos - Parte I El enlace de datos es el mecanismo proporcionado por la plataforma .NET, que en aplicaciones con interfaz Windows o en aplicaciones Web enlaza objetos contenedores de datos con los controles de formulario, para poder realizar operaciones de navegación y edición. Es así que, este artículo explicará cómo colocar un conjunto de datos en un formulario Windows y cómo permitir a los usuarios interactuar con el conjunto de datos a través de los controles de formulario Windows. Aprenderá también, cómo vincular datos SQL Server a los controles de formulario Windows tales como adjuntar datos a cuadros de texto, lista combinadas y cuadrículas de datos. Cabe resaltar que este artículo se limita a la vinculación de datos en formularios Windows y no a formularios Web Forms, dado que a la naturaleza de las páginas de formularios Web Forms y a la arquitectura de la programación Web, el enlace de datos en este tipo de páginas difiere ligeramente del efectuado en otros formularios más tradicionales, como los formularios Windows Forms.

NOTA Para la comprensión de este artículo usted debe conocer conceptos básicosacerca de ADO NET. Si usted no tiene conocimientos en ADO .NET, revise lossiguientes artículos sobre la Arquitectura y Funcionalidad de ADO .NET, tanto enmodo conectado como en modo desconectado. Arquitectura y Funcionalidad de ADO .NET (Conectado) Arquitectura y Funcionalidad de ADO .NET (Desconectado)

Tipos de Data Binding o enlace a datos Simple Data Binding. Consiste en una asociación entre un control que puede mostrar un único dato y el objeto que actúa como contenedor de datos, como por ejemplo el enlace entre un control TextBox o un label y un objeto DataColumn de una DataTable de un DataSet. Complex Data Bindings. Este tipo de enlace es posible entre un control que puede actuar como interfaz o visualizador de datos debido a que dispone de la capacidad de mostrar varios o todos los datos, normalmente más de un registro, del objeto contenedor de datos. Esto se utiliza normalmente en controles DataGrid ("grilla"), ListBox o ErrorProvider. Un ejemplo clásico viene a ser el enlace entre una grilla y un objeto DataTable de un DataSet. Elementos del Data Binding Es posible enlazar datos (Databind) con los controles de formularios Windows, no solamente desde orígenes de datos tradicionales (como DataSets ADO .NET), sino también a casi cualquier estructura que contenga datos como estructuras, colecciones, propiedades y otros controles. Cualquier objeto que deriva de la clase Control tiene una colección de tipo ControlBindingsCollection (expuesta en la propiedad DataBinding) que puede tener objetos Binding (para enlazar). El mecanismo de enlace automático de datos a controles está compuesto por un elevado conjunto de elementos del conjunto de tipos del .NET Framework, entre clases, colecciones, enumeraciones, etc. Entre ellos tenemos: Binding Clase que permite crear un enlace (Binding) para un control indicando algunos parámetros, donde el primer parámetro es la propiedad de destino, el segundo parámetro es el objeto origen que contiene todos los datos y el tercer parámetro es el campo origen en el objeto origen. Cuando hay una modificación en la propiedad de destino, el cambio también se hace para el objeto Origen. Si el objeto es un Dataset, los datos de la base de datos no son modificados. El Dataset debe ser sincronizado con la base de datos. Por ejemplo, puede vincular el campo ContactName y un control TextBox1 de la siguiente manera: Me.SqlDataAdapter1.Fill(Me.DataSet11, "Customers")

Page 32: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

Dim bind As Binding bind = New Binding("Text", Me.DataSet11, "Customers.Contactname") 'otra manera de configurar nuestro enlace es usando este código. 'bind = New Binding("Text", Me.DataSet11.Tables("Customers"), "Contactname") Me.TextBox1.DataBindings.Add(bind) BindingContext Propiedad de la clase Form que representa el contexto de enlace a datos establecido en los controles del formulario, es decir, toda la información de enlaces establecida entre los controles y objetos proveedores de datos. Devuelve un objeto de tipo BindingManagerBase o administrador base de enlaces de datos. Cada objeto que herede de la clase Control puede tener un sólo objeto BindingContext. Ese objeto BindingContext administra los objetos BindingManagerBase para ese control y cualquier control que esté incluido. Hay que utilizar BindingContext con el fin de crear o devolver BindingManagerBase para un origen de datos utilizado por los controles con enlace a datos incluidos. Normalmente, se utiliza el objeto BindingContext de la clase Form con el fin de devolver objetos BindingManagerBase para los controles con enlace a datos del formulario. Si se utiliza un control contenedor, como GroupBox, Panel o TabControl, para incluir controles con enlace a datos, se puede crear un objeto BindingContext sólo para ese control contenedor y sus controles. De este modo, cada parte de un formulario puede ser administrada por su propio objeto BindingManagerBase. BindingMangerBase Objeto que se encarga de administrar un conjunto de objetos de enlace, por ejemplo, los de un formulario obtenidos a través del BindingContext del formulario. Para devolver un objeto BindingManagerBase concreto, es necesario pasar uno de los siguientes parámetros a la propiedad Item: 1. Sólo el origen de datos, si el objeto BindingManagerBase que se desea no requiere una

ruta de desplazamiento. Por ejemplo, si BindingManagerBase administra un conjunto de objetos Binding que usan ArrayList o DataTable como DataSource, no se requiere ninguna ruta de desplazamiento.

2. Origen de datos y ruta de desplazamiento. La ruta de desplazamiento (establecida en el

parámetro DataMember de la propiedad Item) es obligatoria cuando BindingManagerBase administra un conjunto de objetos Binding cuyo origen de datos contiene múltiples objetos. Por ejemplo, DataSet puede contener varios objetos DataTable vinculados mediante objetos DataRelation. En tal caso, se requiere la ruta de desplazamiento para permitir que BindingContext devuelva el objeto BindingManagerBase correcto.

Yo le aconsejaría que siempre opte por manejar una ruta de desplazamiento, aún cuando esté manejando un origen de datos sencillo como un sólo DataTable, de esta manera, se evitarán algunas complicaciones y podrán ser más "formales".

NOTA: Algo a resaltar es que una de las características interesantes en eldesarrollo con Visual Basic .NET es la posibilidad de vincular cualquier propiedad deun control visible, como su propiedad BackColor o ForeColor, a una columna dedatos. De esta manera, existe la posibilidad de que un origen de datos localcontrole dinámicamente el formato de un formulario así como los datos quemuestra el formulario.

Ejemplo ilustrativo... A continuación mostraré un ejemplillo donde tras rellenar el conjunto de datos (usando el asistente de configuración de objetos ADO .NET ) asociado a un formulario, haremos referencia al conjunto de datos mediante los controles de formulario. Para vincular los controles de formulario a las columnas del conjunto de datos (una sola tabla) y que los cuadros dependan de la pulsación de nuestros botones navegadores se necesitan unas

Page 33: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

cuantas líneas de código o también puede hacerlo en tiempo de diseño (esto le ahorraría bastante tiempo). Esencialmente se trata de navegar los registros cuyos campos son CustomerId, CompanyName, ContactName, ContactTitle de la tabla Customers de la base de datos Northwind, para esto previamente debió vincularse los respectivos controles TextBox a cada una de estas columnas. Como le decía, esta vinculación puede hacerse en tiempo de diseño o en tiempo de ejecución, personalmente, lo hice en tiempo de diseño, pero no se alarme, que a continuación le enseño a hacerlo de ambas maneras. Para que se vaya haciendo una idea acerca de lo que verá, allí le va la interfaz del formulario.

Esto es fácil. Siga los siguientes pasos para implementar el ejemplo: 1. Debe generar el conjunto de datos (tan sólo los campos CustomerId, CompanyName, ContactName, ContactTitle de la tabla Customers), mediante el asistente de configuración de ADO .NET. 2. Ahora agregue cuatro controles TextBox sobre su formulario Windows y en la propiedad DataBinding de cada uno de los controles debe establecer el campo a enlazar, como se aprecia en la siguiente imagen:

Opcionalmente puede hacerlo mediante código. Y esto sería: Dim AdministradorBaseDeEnlaces As BindingManagerBase Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles MyBase.Load

Page 34: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

'Rellenamos nuestro contenedor de datos Me.SqlDataAdapter1.Fill(Me.MisDatos1, "Customers") 'Establecemos la vinculación para cada uno de los controles TextBox. Dim Bind As Binding Bind = New Binding("Text", Me.MisDatos1, "Customers.CustomerId") Me.TextBox1.DataBindings.Add(Bind) Bind = Nothing Bind = New Binding("Text", Me.MisDatos1, "Customers.CompanyName") Me.TextBox2.DataBindings.Add(Bind) Bind = Nothing Bind = New Binding("Text", Me.MisDatos1, "Customers.ContactName") Me.TextBox3.DataBindings.Add(Bind) Bind = Nothing Bind = New Binding("Text", Me.MisDatos1, "Customers.ContactTitle") Me.TextBox4.DataBindings.Add(Bind) Bind = Nothing 'Finalmente obtenemos del contexto de enlace de nuestro 'formulario un objeto administrador que nos servirá para navegar 'cada uno de los registros de la tabla customers. AdministradorBaseDeEnlaces = Me.BindingContext(Me.MisDatos1, "Customers") End Sub Sobre la base del código anterior, este sería el resto de código que hace posible la navegación de los registros. Private Sub Navegar(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles Button1.Click, Button2.Click, Button3.Click, Button4.Click If sender Is Me.Button1 Then Me.AdministradorBaseDeEnlaces.Position = _ Me.AdministradorBaseDeEnlaces.Position.MinValue ElseIf sender Is Me.Button2 Then Me.AdministradorBaseDeEnlaces.Position += 1 ElseIf sender Is Me.Button3 Then Me.AdministradorBaseDeEnlaces.Position -= 1 ElseIf sender Is Me.Button4 Then Me.AdministradorBaseDeEnlaces.Position = _ Me.AdministradorBaseDeEnlaces.Position.MaxValue End If End Sub 3. Después de realizar la vinculación (en tiempo de diseño) debemos implementar la funcionalidad de nuestros botones navegadores. Y esto sería todo el código: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles MyBase.Load 'Rellenamos nuestro contenedor de datos Me.SqlDataAdapter1.Fill(Me.MisDatos1, "Customers") End Sub Private Sub Navegar(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles Button1.Click, Button2.Click, Button3.Click, Button4.Click If sender Is Me.Button1 Then Me.BindingContext(Me.MisDatos1, "Customers").Position = _ Me.BindingContext(Me.MisDatos1, "Customers").Position.MinValue ElseIf sender Is Me.Button2 Then Me.BindingContext(Me.MisDatos1, "Customers").Position += 1 ElseIf sender Is Me.Button3 Then Me.BindingContext(Me.MisDatos1, "Customers").Position -= 1

Page 35: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

ElseIf sender Is Me.Button4 Then Me.BindingContext(Me.MisDatos1, "Customers").Position = _ Me.BindingContext(Me.MisDatos1, "Customers").Position.MaxValue End If End Sub

NOTA: Le recomiendo que la vinculación de datos lo haga, en la medida posible, en tiempo de diseño, ya que es más rápido, fácil y se necesita menos código, de esta manera se evitará unos pequeños dolores de cabeza durante la depuración de código.

4. Hasta aquí hemos terminado. Ahora tiene que ir navegando cada uno de los registros de la tabla customers.

Como habrá notado, es relativamente sencillo realizar este tipo de vinculación. Vínculo de un DataSet con un Control DataGrid Una vez terminado de explicar el ejemplo de Enlace Simple de Datos o Simple DataBinding, pasaremos a aprender algo más divertido, se trata de cómo implementar la vinculación Compleja de Datos usando controles un poco más complicados como por ejemplo una grilla, un ListBox... pero por esta vez usaré la Grilla. Para esto agregaremos un control DataGrid en el formulario, este control se va a enlazar con la tabla Customers de la base de datos Northwind. A través de este formulario podemos editar los registros de la tabla y añadir nuevos; al trabajar en desconexión, hasta que no pulsemos el botón Actualizar de este formulario, el objeto DataAdapter no actualizará los datos del DataSet hacia la base de datos física. Observe que he modificado los campos City y Country en el primer registro de la grilla. Luego de actualizar, un mensaje nos avisará que los cambios han sido guardados. Una forma práctica de verificar esto, es volver a cargar la aplicación, la cual contendrá los cambios que haya realizado.

Page 36: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

Ahora dejo a su disposición todo el código que hace posible la ilustración anterior. Imports System.Data.SqlClient Public Class Form1 Inherits System.Windows.Forms.Form 'CÓDIGO GENERADO POR EL DISEÑADOR DE WINDOWS FORMS Public DataSet As New DataSet Public Adapter As SqlDataAdapter Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles MyBase.Load Me.StatusBar1.Panels(0).Text = "Percy Reyes:: ¡Los peruanos Sí podemos !" Dim SQL_CONECTION_STRING As String = "Server=localhost;" & _ "DataBase=Northwind;Integrated Security=SSPI;Connect Timeout=5" Dim oConection As New SqlConnection(SQL_CONECTION_STRING) Dim SQL_COMMAND_STRING As String = "Select CustomerID,CompanyName,ContactName," & _ "ContactTitle,Address,City,Country From Customers" Adapter = New SqlDataAdapter(SQL_COMMAND_STRING, oConection) Dim oCommandBuilder As SqlCommandBuilder = New SqlCommandBuilder(Adapter) DataSet = New DataSet Adapter.Fill(DataSet, "Clientes") Me.DataGrid1.DataSource = DataSet Me.DataGrid1.DataMember = "Clientes" End Sub Private Sub BtnActualizar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles BtnActualizar.Click If DataSet.HasChanges Then Adapter.Update(DataSet, "Clientes") Me.StatusBar1.Panels(0).Text = "Los cambios han sido guardados." Me.Timer1.Enabled = True Me.Timer1.Start() End If

Page 37: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

End Sub Public i As Integer Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles Timer1.Tick If i = 5 Then i = 0 Timer1.Stop() Timer1.Enabled = False Me.StatusBar1.Panels(0).Text = "Percy Reyes: ¡Los peruanos Sí podemos!" Else i += 1 Me.StatusBar1.Panels(0).Text = " " Me.StatusBar1.Panels(0).Text = Space(2 * i) & "Los cambios han sido guardados." End If End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles Button1.Click End End Sub End Class Relación Maestro/Detalles en dos DataGrid Es posible configurar las propiedades del DataGrid de tal manera que nos permita visualizar más de una tabla, permitiendo al usuario elegir cualquiera de las tablas que se muestran en él, también podemos trabajar con tablas relacionadas, permitiéndonos obtener, de esta manera, las filas hijas, relacionadas con la fila seleccionada de la tabla padre. Este control implementa de forma transparente todos los mecanismos necesarios gracias al DataBinding, por lo que, una vez creada la relación, sólo hemos de asignar a su propiedad DataSource, la tabla padre del DataSet. Podemos separar la visualización de las tablas maestro detalle en dos DataGrid independientes. Para sincronizar ambos controles, debemos asignar al que actuará como detalle, una cadena con el nombre de la tabla maestra, junto con el nombre de la relación empleando el siguiente formato: TablaMaestra.Relacion. Más adelante muestro un sencillo ejemplo de cómo lograr esto. Sigamos. Como le decía, en muchas ocasiones las aplicaciones tienen que trabajar con tablas relacionadas. Aunque un conjunto de datos contiene tablas y columnas al igual que una base de datos, no incluye intrínsecamente la capacidad de las bases de datos para relacionar tablas. No obstante, se pueden crear objetos DataRelation que establezcan una relación entre una tabla primaria (maestra) y una tabla secundaria (de detalle) sobre la base de una clave común. El objeto DataRelation puede ejecutar dos funciones:

• Puede poner a su disposición los registros relacionados con el registro con el que esté trabajando. Proporciona registros secundarios cuando se está en un registro primario y un registro primario si se está trabajando con un registro secundario.

• Puede exigir restricciones de integridad referencial, como la eliminación de los

registros secundarios relacionados cuando se elimina un registro primario.

NOTA: Es importante comprender la diferencia entre una combinación auténtica yla función de un objeto DataRelation. En una combinación auténtica, los registrosse toman de tablas primarias y secundarias y se ponen en un único conjunto deregistros planos. Cuando se utiliza un objeto DataRelation no se crea ningúnconjunto de registros nuevo. En su lugar, se hace un seguimiento de la relaciónentre las tablas y se mantienen sincronizados los registros primarios y secundarios.

Ejemplo

Page 38: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

Para esta ilustración emplearemos dos tablas (Categories y Products) de la base de datos Northwind. Estableceremos la relación maestro-detalle entre estas dos tablas a través de la columna CategoryId. Luego de hacer esto, escribiremos el código necesario para visualizar la tabla detalle "Productos" en otra DataGrid de acuerdo con la fila seleccionada en la tabla padre "Categorias".

Allí le dejo con el código para que lo revise y espero sea de utilidad. Imports System.Data.SqlClient Public Class Form1 Inherits System.Windows.Forms.Form 'CÓDIGO GENERADO POR EL DISEÑADOR DE WINDOWS FORMS Public DataSet As New DataSet Public AdapterCategories As SqlDataAdapter Public AdapterProducts As SqlDataAdapter Dim SQL_CONECTION_STRING As String = "Server=localhost;" & _ "DataBase=Northwind;Integrated Security=SSPI;Connect Timeout=5" Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles MyBase.Load Me.StatusBar1.Panels(0).Text = "Percy

Page 39: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

Reyes:: ¡Los peruanos Sí podemos !" Dim oConection As New SqlConnection(SQL_CONECTION_STRING) Dim SQL_STRING_CATEGORIES As String = "Select CategoryID,CategoryName,Description From Categories" Dim SQL_STRING_PRODUCTS As String = "Select ProductID,ProductName, SupplierID, " & _ " CategoryID,QuantityPerUnit,UnitPrice,UnitsInStock, UnitsOnOrder From Products" AdapterCategories = New SqlDataAdapter(SQL_STRING_CATEGORIES, oConection) Dim oCommandBuilder1 As SqlCommandBuilder = New SqlCommandBuilder(AdapterCategories) AdapterProducts = New SqlDataAdapter(SQL_STRING_PRODUCTS, oConection) Dim oCommandBuilder2 As SqlCommandBuilder = New SqlCommandBuilder(AdapterProducts) DataSet = New DataSet AdapterCategories.Fill(DataSet, "Categorias") Me.DataGrid1.DataSource = DataSet Me.DataGrid1.DataMember = "Categorias" AdapterProducts.Fill(DataSet, "Productos") Me.DataGrid2.DataSource = DataSet DataSet.Relations.Add("Categorias_Productos", DataSet.Tables("Categorias").Columns("CategoryId"), _ DataSet.Tables("Productos").Columns("CategoryId")) Me.DataGrid2.DataMember = "Categorias.Categorias_Productos" Me.DataGrid1.CaptionText = "Tabla maestra: " & _ UCase(DataSet.Relations("Categorias_Productos").ParentTable.TableName.ToString()) End Sub Private Sub BtnActualizar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles BtnActualizar.Click If DataSet.HasChanges Then AdapterCategories.Update(DataSet, "Categorias") AdapterProducts.Update(DataSet, "Productos") Me.StatusBar1.Panels(0).Text = "Los cambios han sido guardados." Me.Timer1.Enabled = True Me.Timer1.Start() End If End Sub Public i As Integer Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As

Page 40: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

System.EventArgs) _ Handles Timer1.Tick If i = 5 Then i = 0 Timer1.Stop() Timer1.Enabled = False Me.StatusBar1.Panels(0).Text = "Percy Reyes:: ¡Los peruanos Sí podemos!" Else i += 1 Me.StatusBar1.Panels(0).Text = " " Me.StatusBar1.Panels(0).Text = Space(2 * i) & "Los cambios han sido guardados." End If End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles Button1.Click End End Sub Private Sub DataGrid1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) _ Handles DataGrid1.MouseDown Try 'este código nos permite capturar el contenido de la celda actual, e informar al usuario sobre la lista de productos por categoría. Dim Hit As DataGrid.HitTestInfo Hit = Me.DataGrid1.HitTest(e.X, e.Y) If Hit.Type = DataGrid.HitTestType.Cell Then Me.DataGrid2.CaptionText = "Tabla detalle: Lista de " & _ UCase(DataSet.Relations("Categorias_Productos").ChildTable.TableName.ToString()) & _ "de " & Mid(UCase(DataSet.Relations("Categorias_Productos").ParentTable.TableName.ToString()), _ 1, DataSet.Relations("Categorias_Productos").ParentTable.TableName.Length - 1) _ & Space(1) & Microsoft.VisualBasic.UCase(Me.DataGrid1(Hit.Row, 1)) End If Catch ex As Exception Me.DataGrid2.CaptionText = "Tabla detalle: Lista VACÍA " End Try End Sub End Class

Espacios de nombres usados en el código de este artículo: System.Data System.Data.SqlClient

Page 41: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

Actividades de aprendizaje

Actividad de aprendizaje 2.1.

Planteamiento

Tomando de referencia el material entregado Acceso a datos con ADO_NET (PDF), realice los siete (7) casos de conexión a las bases de datos (desde la página 23 a la 27 del material que se encuentra en la Sección Contenidos), para esto usted puede usar bases de datos ya creadas que existen en los motores de base de datos (SQL Server, Microsoft Access, Oracle, MySQL) o crear una base de prueba. Por favor, documente este trabajo en Word del funcionamiento de la conexión.

Orientaciones didácticas

Recuerde que deberá documentar en Word cada programa que vaya creando, con el código fuente que programó o digitó (no imprima el código fuente que la herramienta inserta en forma automática), también debe capturar las pantallas de corridas con datos de prueba y comprimir los archivos.

El archivo comprimido debe incluir el documento de Word con el desarrollo de la guía y el código fuente de cada programa, de faltar alguno de ellos su nota tendrá una rebaja del 50% del puntaje correspondiente a cada actividad.

Actividad de aprendizaje 2.2.

Planteamiento

Realice los siguientes ejercicios del tema ’Consultas a bases de datos’ del archivo Acceso a datos con ADO_NET (PDF): Ejercicio 1 (página 27), Ejercicio 2 (página 28), Ejercicio 3 (página 29), Ejercicio 4 (página 30).

Orientaciones didácticas

Revise el material que se encuentra en la Sección CONTENIDOS. Recuerde que deberá documentar en Word cada programa que vaya creando, con el código fuente que programó o digitó (no imprima el código fuente que la herramienta inserta en forma automática), también debe capturar las pantallas de corridas con datos de prueba y comprimir los archivos.

El archivo comprimido debe incluir el documento de Word con el desarrollo de la guía y el código fuente de cada programa, de faltar cada alguno de ellos su nota tendrá una rebaja del 50% del puntaje correspondiente a cada actividad.

Actividad de aprendizaje 2.3.

Planteamiento

Realice los siguientes ejercicios del tema ‘Mantenimiento de una tabla (p. 67) del archivo Acceso a datos con ADO_NET (PDF): Ejercicio 37 (pp. 69, 70, 71 y 72), Ejercicio 38 (pp. 72 y 73).

Orientaciones didácticas

Revise el material que se encuentra en la Sección Contenidos. Recuerde que deberá documentar en Word cada programa que vaya creando, con el código fuente que programó o digitó (no imprima el código fuente que la herramienta inserta en forma automática), también debe capturar las pantallas de corridas con datos de prueba y comprimir los archivos.

El archivo comprimido debe incluir el documento de Word con el desarrollo de la

Page 42: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

guía y el código fuente de cada programa, de faltar cada alguno de ellos su nota tendrá una rebaja del 50% del puntaje correspondiente a cada actividad.

Actividad de aprendizaje 2.4.

Planteamiento

Utilizando todos los conocimientos aprendidos de formularios, menús, MDI y base de datos realice lo siguiente:

Cree una aplicación que permita automatizar el proceso de registro de solicitudes, toma de exámenes atrasados y cambios de centro.

Para esto usted debe diseñar la Base de Datos con las siguientes tablas:

Estudiante, Materias, Centros de Apoyo, Semestres.

La aplicación debe contar con los formularios de administración de información de las tablas Estudiante, Semestres, Centros de Apoyo, Materias, las que deben incluir las operaciones de crear, modificar, eliminar, consultar y los cursores de movimiento de registro.

Su aplicación debe contar con formularios MDI (menú principal) y

formularios contenedores por cada opción de menú.

La aplicación debe contar con un formulario de seguridad que pida usuario y clave al inicio de la aplicación.

No añada más requerimientos ya que los demás requisitos se pedirán en la siguiente guía.

Orientaciones didácticas

Revise el material de la Sección Contenidos.

Recuerde que deberá documentar en Word cada programa que vaya creando, con el código fuente que programó o digitó (no imprima el código fuente que la herramienta inserta en forma automática), también debe capturar las pantallas de corridas con datos de prueba y comprimir los archivos.

El archivo comprimido debe incluir el documento de Word con el desarrollo de la guía y el código fuente de cada programa, de faltar alguno de ellos su nota tendrá una rebaja del 50% del puntaje correspondiente a cada actividad.

Actividad de aprendizaje 2.5.

Planteamiento

Continúe con la aplicación que se planteó en la actividad de aprendizaje anterior y agregue los siguientes requisitos:

Cree la tabla o tablas la que permitan registrar la información de una

solicitud para rendir examen atrasado o con cambio de centro (investigue qué información se pide en la solicitud para exámenes atrasados y cambios de centro).

Cree los formularios de administración de información de la tabla registro

de solicitudes, la que debe incluir las operaciones de crear, modificar, eliminar y los cursores de movimiento de registro. Por cada formulario o tabla deberá generarse un reporte e impresión.

Cree los siguientes reportes:

o Reporte de estudiantes que rinden exámenes por cambio de centro

Page 43: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

El tutor de la asignatura

o Reporte de estudiantes que rinden exámenes por fechas de examen o Reporte de estudiantes que rinden exámenes por centro de apoyo

Documente la creación del instalador del sistema.

Orientaciones didácticas

Entregue el proyecto en un CD, el que contendrá: el programa instalador del sistema, fuentes y base de datos.

Usted deberá enviar el CD con lo solicitado la primera semana de los segundos exámenes, al centro de apoyo 50 ó a las oficinas de la Carrera de la Tecnología en Computación.

Enviar a

Envíe la guía didáctica a través de la plataforma, mediante la Sección Contenidos, en un archivo cuyo nombre debe ser: Formato: G#.Apellido.Apellido.Nombre.Asignatura

Preguntas o dudas

Envíe sus preguntas o dudas a través de la plataforma: utilice la sección Enviar correo y marque el nombre de su tutor.

Page 44: Visual

Nombre de la asignatura: Programación Visual

Parcial de estudio Segundo parcial

Puntaje por Actividad

Actividad 3 Puntaje Actividad de aprendizaje 2.1. 2 Actividad de aprendizaje 2.2. 2 Actividad de aprendizaje 2.3. 2 Actividad de aprendizaje 2.4. 5 Actividad de aprendizaje 2.5.

Tarea a 1.5 puntos Tarea b 3 puntos Tarea c 3 puntos Tarea d 1.5 puntos

9

Total 20