La Biblia de
Visual Basic
.NET
Luis Dueñas
La Biblia de Visual Basic .NET
Acerca del Autor
Luis Dueñas Huaroto es un especialista en desarrollo de Software con más
de 20 años de experiencia, tiene estudios superiores en Economía,
Computación y Maestría en Ingeniería de Sistemas con especialización en
Ingeniería de Software.
El autor tiene las certificaciones: Microsoft Certified Professional (MCP),
Microsoft Office User Spercialist (MOUS), Microsoft Certified Solution
Developer .NET (MCSD), Microsoft Certified Technology Specialist (MCTS) y
Microsoft Certified Trainer (MCT), además conoce las versiones de Visual
Basic 3,4,5,6 y .NET desde sus inicios habiendo trabajado con todas las
versiones de .NET Framework y Visual Studio.
Actualmente se desempeña como consultor Senior y Team Leader en una
importante Consultora de Sistemas, además de laborar como docente hace
más de 10 años en ISILTECH que es el centro de especialización del
Instituto San Ignacio de Loyola.
También realiza capacitaciones de desarrollo sobre la plataforma .NET a
Empresas, entre las cuales tenemos: Provías Nacional del Ministerio de
Transportes y Comunicaciones, Policia Nacional del Perú, Clinica Ricardo
Palma, Banco INTERBANK, BCTS Consulting, entre otros.
Para cualquier contacto con el llamar al teléfono 997500549 o enviar un
mail a [Link]@[Link]
Luis Dueñas Pag 2
La Biblia de Visual Basic .NET
Dedicatoria
Este libro va dedicado a las personas que cada día me obligan a investigar
más y a aprender nuevos temas, en especial a mis alumnos y mis
compañeros de trabajo.
Sobre todo va dedicado para mis alumnos más antiguos como: Raúl Antón,
Marcelino Cabanaconza, Luis y Nano Agape, Juan Carlos Moreno y Edward
Schwarz.
Luis Dueñas Pag 3
La Biblia de Visual Basic .NET
Indice
Introducción
Capítulo 1: .NET Framework 4, Visual Studio 2010 y Visual Basic .NET 2010
1. Introducción a Microsoft .NET Framework 4
1.1. Componentes de Microsoft .NET Framework
1.2. Biblioteca de Clases de .NET Framework (BCL)
1.3. Motor de Ejecución de Lenguaje Común (CLR)
1.4. Novedades del .NET Framework 4
2. Visual Studio .NET 2010
2.1. Descripción del Entorno Integrado de Desarrollo (IDE)
2.2. Novedades de Visual Studio 2010
3. Visual Basic .NET 2010
3.1. Estructuras de Control de Flujo
3.2. Tipos de Datos en Visual Basic
3.3. Operadores y Expresiones en Visual Basic
3.4. Variables en Visual Basic
3.5. Novedades de Visual Basic 2010
Capítulo 2: Programando con Visual Basic .NET 2010
1. Trabajar con el Entorno de Windows y el Sistema
1.1. Obtener Información del Sistema
1.2. Obtener Directorios Especiales de Windows
1.3. Acceder al Registro de Windows
1.4. Trabajar con Procesos o Tareas del Sistema
2. Manejo de Entrada y Salida
2.1. Manejar Unidades, Directorios, Rutas y Archivos
2.2. Leer y Escribir en un Archivo
2.3. Dividir y Unir Archivos
2.4. Comprimir y Descomprimir un Archivo
3. Programación Orientada a Objetos (POO)
3.1. Introducción a la POO y MDD
3.2. Creando Bibliotecas de Clases
3.3. Creando una Aplicación que use las Bibliotecas de Clases
4. Programación Asíncrona y Paralelismo
Luis Dueñas Pag 4
La Biblia de Visual Basic .NET
4.1. Threads
4.2. Eventos Asíncronos
4.3. Delegados CallBacks
4.4. Programación Paralela
5. Criptografía o Cifrado de Datos
5.1. Cifrado Simétrico por Caracter
5.2. Cifrado Simétrico por Bloques
5.3. Valores Hash Criptográficos
Capítulo 3: Accediendo a Datos con ADO .NET
1. Trabajando en Forma Conectada
1.1. Introducción al Acceso a Datos con ADO .NET
1.2. Conectarse a un Origen de Datos
1.3. Ejecutando Comandos de Selección
1.4. Realizando un Mantenimiento Conectado
2. Trabajando en Forma Desconectada con DataSet
2.1. Trabajando con Tablas y Relaciones
2.2. Trabajando con Vistas
2.3. Mantenimiento Desconectado con DataSet
3. Trabajando en Forma Desconectada con Listas de Objetos
3.1. Llenando una Lista de Objetos
3.2. Filtrando Datos en una Lista de Objetos
3.3. Ordenando y Buscando datos en una Lista de Objetos
3.4. Mantenimiento con Objetos
4. LINQ
4.1. LINQ a DataSet
4.2. LINQ a SQL
4.3. LINQ a Entidades
Capítulo 4: Desarrollando Aplicaciones Windows Forms
1. Trabajando con el Formulario y los Controles Windows
1.1. Trabajando con el Formulario Windows
1.2. Usando Controles Básicos
1.3. Usando Controles de Listas
1.4. Usando Controles de Vistas
2. Creando Formularios MDIs, Menús, Diálogos y Barras
Luis Dueñas Pag 5
La Biblia de Visual Basic .NET
2.1. Creando Formularios MDIs
2.2. Creando Menús
2.3. Usando Dialogos de Windows
2.4. Agregando Barras
3. Usando el Control DataGridView
3.1. Personalizando Columnas en el DataGridView
3.2. Mostrando una Imagen en una Columna
3.3. Personalizando las Cabeceras de las Columnas
3.4. Graficando en el DataGridView
3.5. Paginando en un DataGridView
4. Creando una Biblioteca de Controles Windows
4.1. Creando Controles Extendidos
4.2. Creando Controles de Usuario
4.3. Creando Controles Personalizados
5. Creando Reportes e Impresiones en Windows Forms
5.1. Usando PrintDocument
5.2. Informes de Microsoft
5.3. Trabajando con Word
5.4. Trabajando con Excel
5.5. Usando el Control Chart
Capítulo 5: Desarrollando Aplicaciones Web con ASP .NET
1. Trabajando con el Formulario y los Controles Web
1.1. Introducción a ASP .NET
1.2. Creando un Simple Sitio Web
1.3. Usando Controles Web Intrínsecos
1.4. Usando Controles Web de Imágenes
1.5. Usando el Control FileUpload y Controles de Validación
2. Mejorando el Diseño y Navegabilidad del Sitio Web
2.1. Creando y usando Hojas de Estilos en Cascada
2.2. Paginas Principales y Controles de Navegación
2.3. Usando Controles de Vistas MultiView y Views
3. Usando el Control GridView
3.1. Personalizando Columnas en el GridView
3.2. Paginando en el GridView
3.3. Ordenando en el GridView
Luis Dueñas Pag 6
La Biblia de Visual Basic .NET
3.4. Mantenimiento de Datos en el GridView
4. Creando Plantillas en Controles Enlazados a Datos
4.1. Trabajando con el Control Repeater
4.2. Trabajando con el Control DataList
4.3. Creando Plantillas Jerárquicas
Capítulo 6: Desarrollando Aplicaciones con WPF
1. Creando Aplicaciones Básicas con WPF
1.1. Introducción a WPF
1.2. Trabajando con Ventanas
1.3. Trabajando con Páginas
1.4. Usando Cuadros de Diálogo
2. Usando Enlace de Datos
2.1. Introducción al Enlace de Datos
2.2. Usando Enlace de Datos
2.3. Usando Conversión de Datos
2.4. Usando Plantillas de Datos
2.5. Usando el Control DataGrid
3. Manejando Documentos
3.1. Introducción al Manejo de Documentos
3.2. Trabajando con Documentos Fijos
3.3. Creando Anotaciones en Documentos
3.4. Trabajando con Documentos Dinámicos
4. Manejando Multimedia
4.1. Introducción al Manejo de Multimedia
4.2. Implementando Voz
4.3. Trabajando con Audio y Video
Indice de Ejemplos del Libro
Enlaces de Referencia
Luis Dueñas Pag 7
La Biblia de Visual Basic .NET
Introducción
Tratar de escribir una obra completa sobre desarrollo de aplicaciones
usando Visual Basic en .NET Framework es muy ambicioso, por lo cual se
ha dividido en 2 partes, éste libro es la primera parte de este esfuerzo y
contiene 6 capítulos.
El primero es conceptual y brinda información sobre .NET Framework,
Visual Studio y Visual Basic. El segundo capítulo nos enseña como
programar en Visual Basic usando algunas clases de .NET Framework como
el entorno, entrada y salida, programación orientada a objetos,
programación asíncrona y seguridad de datos.
El tercer capítulo trata el acceso a datos usando ADO .NET y se divide en
programación conectada, programación desconectada con DataSet y
también con Lista de Objetos, al final se revisa LINQ.
El cuarto capítulo enseña el desarrollo de aplicaciones para Windows
usando WinForms y contiene temas como el formulario y los controles,
creación de MDIs y menús, uso de diálogos y barras de herramientas,
también trata detalladamente el control DataGridView y cómo crear una
librería de controles para Windows y finalmente diferentes formas de crear
reportes e impresiones en Windows.
En el quinto capítulo se aprederá a desarrollar aplicaciones Web usando
ASP .NET Web Forms, iniciando con el formulario y los controles Web,
mejorando el diseño usando Hojas de Estilo en Cascada y mejorando la
navegabilidad mediante controles de navegación y paginas principales,
también usando controles MultiView y Views para usar fichas o tabs.
En el último capítulo de este libro veremos Windows Presentations
Foundation (WPF) para crear aplicaciones Windows y del Explorador,
trabajaremos con enlace de datos, manejo de documentos y finalmente
implementaremos características Multimedia.
Como parte del segundo libro estaría quedando ASP .NET MVC, Silverlight,
Windows Communication Foundation (WCF), Windows Workflow
Foundation (WWF), Desarrollo con MS Office en .NET y Desarrollo con MS
SharePoint en .NET.
Luis Dueñas Pag 8
La Biblia de Visual Basic .NET
Capitulo 1: .NET Framework 4, Visual Studio 2010 y
Visual Basic .NET 2010
En este primer capítulo del libro daremos una revisión rápida de la
arquitectura y componentes de la plataforma de desarrollo Microsoft .NET
Framework 4, las características de la Herramienta de Desarrollo Visual
Studio 2010 y del Lenguaje Visual Basic .NET 2010.
En los 3 veremos las características principales así como las novedades de
esta versión, tanto de plataforma, del entorno de desarrollo de Visual
Studio así como del Lenguaje Visual Basic.
Luis Dueñas Pag 9
La Biblia de Visual Basic .NET
1. Introducción a Microsoft .NET Framework 4
Microsoft .NET Framework 4.0 es la ultima plataforma de desarrollo
Microsoft que permite crear todo tipo de aplicaciones desde aplicaciones de
consola para programas en lotes o batch, aplicaciones Windows para
Cliente/Servidor, aplicaciones Web parta Internet o Intranet, Servicios Web
para inter operar con otras plataformas, Servicios Windows para ejecutar
tareas en segundo plano, y otros tipos de aplicaciones.
También nos permite crear Librerías o Bibliotecas de clases reusables, ya
sea a nivel de código, de controles, de servicios, de flujos, etc., las cuales
pueden utilizarse en diferentes tipos de aplicaciones.
A partir de la versión 3.0 se incluyo en el .NET Framework el poder crear
aplicaciones de mejor presentación visual con WPF (Windows Presentations
Foundation), también se unifico las aplicaciones distribuidas que antes se
implementaban mediante Web Services, COM+ y NET Remoting en un solo
conjunto de componentes llamado WCF (Windows Communication
Foundation) y también se dio la posibilidad de crear aplicaciones de flujo de
trabajo o colaboración con WWF (Windows Workflow Foundation).
Para realizar el desarrollo de aplicaciones o librerías en .NET el
desarrollador puede elegir entre muchos Lenguajes .NET algunos de
Microsoft como C#, J#, Visual Basic, Visual C++ y otros de diferentes
proveedores: como ADA, APL, ASML, BETA, BF, C, Clarion#, COBOL,
Cobra, CULE, E#, Eiffel, Flash, Forth, Fortran, G#, Jaskel, JavaScript, LISP,
LOGO, Mercury, Modula 2, Oberon, Pascal, Perl, PHP, Prolog, Python, RPG,
Ruby, Scala, Scheme, Smaltalk, etc.
Esta ultima característica de los lenguajes .NET es una diferencia
fundamental con respecto a JAVA en donde el desarrollador solo programa
usando un lenguaje (Java), en cambio con .NET Framework, podemos
elegir entre muchos lenguajes, esta elección se hará de acuerdo a la
experiencia que tenga la persona, en este libro vamos a usar el lenguaje
Basic, es decir Visual Basic .NET.
Visual Basic .NET es recomendable para las personas que se inician en el
desarrollo de software y no han visto ningún lenguaje, pero también para
aquellos desarrolladores con experiencia que vienen de Visual Basic 3, 4, 5
Luis Dueñas Pag 10
La Biblia de Visual Basic .NET
o 6; de Foxpro, Visual Foxpro o Power Builder; ya que tiene características
similares a estos, como el Modelo Conducido por Eventos (Event Driven
Model o MDE), además de ser Orientado a Objetos (OOP), entre otras
características modernas.
1.1. Componentes de Microsoft .NET Framework
Para desarrollar necesitamos una plataforma o entorno de desarrollo al cual
se le conoce como Framework de Desarrollo, el .NET Framework es la
plataforma que necesitamos para realizar cualquier tipo de desarrollo y se
compone de 2 elementos principales:
Las Bibliotecas de Clase Base (BCL): conjunto de librerías de contienen
clases que permiten crear la aplicación.
El Motor de Ejecución de Lenguaje Común (CLR): conjunto de
programas que permiten compilar (a código nativo) y ejecutar la
aplicación entre otras tareas que se detallan más adelante.
Cuando desarrollemos aplicaciones con .NET Framework, debemos tener
en cuenta el tipo de Aplicación:
Aplicación Administrada: manejada por el CLR o motor de ejecución de
.NET, por ejemplo las aplicaciones de Consola, Windows, WPF, etc.
Aplicación No Administrada: manejada por otro motor, por ejemplo las
Aplicaciones Web son manejadas por el motor de ejecución de ASP NET
y por el IIS, las aplicaciones COM+ son manejadas por el DLLHost, etc.
Luis Dueñas Pag 11
La Biblia de Visual Basic .NET
Gráfico 1.1: .NET Framework en contexto
Luis Dueñas Pag 12
La Biblia de Visual Basic .NET
1.2. Biblioteca de Clases de .NET Framework (BCL)
La BCL es una colección de más de 5000 tipos orientados a objetos
distribuidos en más de 80000 miembros, los tipos se clasifican en:
Tipos por Valor: Se copia el valor a la variable
Tipos Simples del .Net Framework: char, boolean, byte, int, etc.
Enumeraciones.
Estructuras.
Tipos por referencia
Tipos complejos de .NET Framework: String, StringBuilder,
DataSet, FileStream, StreamReader, StreamWriter, etc.
Clases.
Enumeraciones.
Cada tipo contiene elementos o miembros que pueden ser:
Construtores y Destructores
Propiedades, Metodos y Eventos
Campos (variables publicas)
Delegados (punteros a funciones)
Enumeraciones
Operadores
A su vez los tipos están organizados físicamente en Librerías (Assemblies) y
lógicamente en Espacios de Nombres (Namespace). Por ejemplo los tipos
simples se encuentran en la librería [Link], los tipos principales en
[Link], el formulario y los controles Windows Forms en System.
[Link], etc.
Luis Dueñas Pag 13
La Biblia de Visual Basic .NET
La BCL tiene más de 255 espacios de nombres principales que agrupan a
los tipos por categorías de uso, la mayoría inician con System y unos
cuantos con Microsoft, entre los principales tenemos:
Espacio nombres Descripción
[Link] Contienen clases que admiten la compilación y
generación de código mediante el lenguaje Visual
Basic. Los espacios de nombres secundarios
contienen tipos que proporcionan servicios al
compilador de Visual Basic y tipos que incluyen
compatibilidad con el modelo de aplicaciones de
Visual Basic, el espacio de nombres My, expresiones
lambda y conversión de código.
Microsoft.Win32 Proporcionan tipos que administran eventos
provocados por el sistema operativo, que manipulan
el Registro del sistema, y que representan
identificadores de archivo y del sistema operativo.
System Contiene clases que le permiten hacer coincidir con
los URI con plantillas URI y grupos de plantillas URI.
[Link] Contienen todas las clases necesarias para crear y
trabajar con actividades en Windows Workflow
Foundation.
[Link] Contienen tipos que definen varios objetos de
colección estándar, especializados y genéricos.
[Link] Contienen tipos para administrar datos de
Luis Dueñas Pag 14
La Biblia de Visual Basic .NET
configuración, como datos de archivos de
configuración de equipos o aplicaciones. Los
espacios de nombres secundarios contienen tipos
que se emplean para configurar un ensamblado,
escribir instaladores personalizados de
componentes, y admitir un modelo conectable para
agregar o quitar funcionalidad tanto de aplicaciones
cliente como de aplicaciones servidor.
[Link] Contienen clases para tener acceso a datos y
administrarlos desde distintos orígenes. El espacio
de nombres de nivel superior y una serie de
espacios de nombres secundarios forman
conjuntamente la arquitectura [Link] y los
proveedores de datos de [Link]. Por ejemplo,
hay disponibles proveedores para SQL Server,
Oracle, ODBC y OleDB. Otros espacios de nombres
secundarios contienen clases empleadas por Entity
Data Model (EDM) de [Link] y por Servicios de
datos de WCF.
[Link] Contienen tipos que le permiten interactuar con
procesos del sistema, registros de eventos y
contadores de rendimiento. Los espacios de
nombres secundarios contienen tipos para
interactuar con herramientas de análisis del código,
admitir contratos, ampliar la compatibilidad en
tiempo de diseño con la supervisión e
instrumentación de aplicaciones, registrar datos de
eventos mediante el subsistema Seguimiento de
Luis Dueñas Pag 15
La Biblia de Visual Basic .NET
eventos para Windows (ETW), leer registros de
eventos y escribir en ellos y recopilar datos de
rendimiento, y para leer y escribir información de
símbolos de depuración.
[Link] Contiene tipos que admiten funcionalidad básica de
gráficos GDI+. Los espacios de nombres
secundarios admiten funcionalidad avanzada de
gráficos bidimensionales y vectoriales, funcionalidad
avanzada de procesamiento de imágenes, y
servicios tipográficos y relacionados con la
impresión. Un espacio de nombres secundario
también contiene tipos que extienden la lógica y el
dibujo de la interfaz de usuario en tiempo de
diseño.
[Link] Contiene clases que definen información relativa a la
referencia cultural, incluido el idioma, el país o
región, los calendarios utilizados, los modelos de
formato de fecha, divisa y números, y el criterio de
ordenación de las cadenas. Estas clases son útiles
para escribir aplicaciones internacionalizadas.
[Link] Contienen tipos que admiten entrada y salida,
incluida la posibilidad de leer y escribir datos en
flujos de forma sincrónica o asincrónica, comprimir
datos en flujos, crear y usar almacenes aislados,
asignar archivos al espacio de direcciones lógicas de
una aplicación, almacenar varios objetos de datos
en un único contenedor, comunicarse mediante
Luis Dueñas Pag 16
La Biblia de Visual Basic .NET
canalizaciones anónimas o con nombre,
implementar el registro personalizado, y administrar
el flujo de datos hacia y desde puertos serie.
[Link] Contienen tipos que admiten consultas que emplean
Language-Integrated Query (LINQ). Esto incluye
tipos que representan consultas como objetos en
árboles de expresión.
[Link] Contiene clases para reproducir archivos de sonido y
obtener acceso a los sonidos que proporciona el
sistema.
[Link] Contienen tipos que le permiten conectar con colas
de mensajes en la red, así como supervisarlas y
administrarlas, y enviar, recibir o inspeccionar
mensajes. Un espacio de nombres secundario
contiene clases que se pueden usar para ampliar la
compatibilidad en tiempo de diseño de clases de
mensajería.
[Link] Contienen clases que proporcionan una interfaz de
programación sencilla para diversos protocolos de
red, tienen acceso mediante programación y
actualizan valores de configuración para los
espacios de nombres [Link], definen directivas
de caché para recursos web, redactan y envían
correo electrónico, representan encabezados de
Extensiones multipropósito de correo Internet
(MIME), tienen acceso a datos de tráfico de red y a
Luis Dueñas Pag 17
La Biblia de Visual Basic .NET
información de direcciones de red, y tienen acceso a
funcionalidad de red punto a punto. Otros espacios
de nombres secundarios proporcionan una
implementación administrada de la interfaz
Windows Sockets (Winsock) y brindan acceso a
secuencias de red para proteger las comunicaciones
entre hosts.
[Link] Contienen tipos que proporcionan una vista
administrada de los tipos, métodos y campos
cargados, y que pueden crear e invocar tipos de
forma dinámica. Un espacio de nombres secundario
contiene tipos que permiten a un compilador u otra
herramienta emitir metadatos y el lenguaje
intermedio de Microsoft (MSIL).
[Link] Contienen tipos que admiten la interacción de una
aplicación con CLR, y tipos que habilitan
características como almacenamiento en caché de
datos de la aplicación, control avanzado de
excepciones, activación de aplicaciones dentro de
dominios de aplicación, interoperabilidad COM,
aplicaciones distribuidas, serialización y
deserialización, y control de versiones, etc.
[Link] Contienen clases que representan el sistema de
seguridad y los permisos de .NET Framework. Los
espacios de nombres secundarios proporcionan
tipos que controlan el acceso a objetos protegibles y
los auditan, permiten autenticación, ofrecen
Luis Dueñas Pag 18
La Biblia de Visual Basic .NET
servicios criptográficos, controlan el acceso a
operaciones y recursos según una directiva, y
admiten la administración de derechos del contenido
creado por la aplicación.
[Link] Contienen los tipos necesarios para compilar
aplicaciones cliente y de servicio de Windows
Communication Foundation (WCF).
[Link] Contienen tipos que le permiten implementar,
Process instalar y controlar aplicaciones de servicios de
Windows, y extienden la compatibilidad en tiempo
de diseño con aplicaciones de servicios de Windows.
[Link] Contienen tipos que admiten reconocimiento de voz.
[Link] Contienen tipos para la codificación de caracteres y
la manipulación de cadenas. Un espacio de nombres
secundario le permite procesar texto usando
expresiones regulares.
[Link] Contienen tipos que habilitan la programación
multiproceso. Un espacio de nombres secundario
proporciona tipos que simplifican el trabajo de
escribir código simultáneo y asincrónico.
[Link] Contienen tipos que habilitan la comunicación entre
el explorador y el servidor. Los espacios de nombres
secundarios incluyen tipos que admiten
autenticación de formularios de [Link], servicios
Luis Dueñas Pag 19
La Biblia de Visual Basic .NET
de aplicación, almacenamiento en caché de datos
en el servidor, configuración de aplicaciones
[Link], datos dinámicos, controladores HTTP,
serialización de JSON, incorporación de
funcionalidad AJAX a [Link], seguridad de
[Link] y servicios Web.
[Link] Contienen tipos usados en aplicaciones de Windows
Presentation Foundation (WPF), incluidos clientes de
animación, controles de interfaz de usuario, enlace
de datos y conversión de tipos.
[Link] y sus espacios de nombres
secundarios se emplean para desarrollar
aplicaciones de Windows Forms.
[Link] Contienen tipos usados para desarrollar aplicaciones
que emplean Windows Workflow Foundation. Estos
tipos ofrecen compatibilidad en tiempo de diseño y
en tiempo de ejecución con reglas y actividades
para configurar, controlar, hospedar y depurar el
motor en tiempo de ejecución de flujos de trabajo.
[Link] Contienen tipos que admiten el análisis y el
procesamiento del lenguaje XAML.
[Link] Contienen tipos para el procesamiento de XML. Los
espacios de nombres secundarios admiten la
serialización de documentos o secuencias XML,
esquemas XSD, XQuery 1.0 y XPath 2.0, y LINQ a
XML.
Luis Dueñas Pag 20
La Biblia de Visual Basic .NET
1.3. Motor de Ejecución de Lenguaje Común (CLR)
El CLR administra la memoria, la ejecución de subprocesos, la ejecución de
código la comprobación de la seguridad, compilación a código nativo, entre
otros servicios del sistema, es decir todos los servicios que se usan al
ejecutar un programa.
El desarrollador crea una aplicación manejada o administrada en cualquiera
de los Lenguajes .NET de Alto Nivel mencionados como C# o Visual Basic,
luego lo compila con el compilador del lenguaje: [Link] para C#, [Link]
para Visual Basic creándose un ensamblado (Assembly) que se encuentra
en Lenguaje Intermedio de Microsoft (MSIL).
Al querer ejecutar este Assembly el CLR invoca al Compilador Just In Time
que convierte el código MSIL en código nativo el cual se encuentra en
Lenguaje de Bajo Nivel y es este ultimo código que el CLR ejecuta para
comunicarse con el sistema (RAM, CPU, Video, Sistema de Archivos, Bases
de Datos, etc.)
Cuando se inicia la aplicación el CLR se encarga de crear objetos en
memoria mediante el Class Loader y también se encarga de liberar de la
memoria los objetos que no están siendo usados cuando haga falta más
memoria, el encargado de esta tarea es el Garbage Collector.
Otras funciones del CLR son administrar los subprocesos o subtareas, a
veces conocidas como hilos (Threads), controlar las excepciones o errores
en tiempo de ejecución, administrar la seguridad del código .NET
otorgándole los privilegios de acuerdo a reglas o políticas de seguridad,
entre otras funciones implícitas en toda ejecución de una aplicación.
El CLR también administra la seguridad de tipos mediante un Sistema de
Tipos Común (CTS) que obliga a que todos los fabricantes de código .NET
cumplan con las especificaciones de tipos que el CLR obliga, es por eso que
podemos escribir código en un lenguaje .NET como C# y usarlo en una
aplicación Visual Basic y viceversa, lo cual es conocido como Neutralidad
del Lenguaje.
En resumen, el motor en tiempo de ejecución (CLR) ofrece las siguientes
ventajas:
Luis Dueñas Pag 21
La Biblia de Visual Basic .NET
Mejoras en el rendimiento de la aplicación (performance).
Capacidad para utilizar fácilmente componentes desarrollados en otros
lenguajes.
Tipos extensibles que proporciona una biblioteca de clases
Características del lenguaje como herencia, interfaces y sobrecarga
para la programación orientada a objetos.
Compatibilidad con subprocesamiento libre explícito que permite la
creación de aplicaciones multiprocesos escalables.
Compatibilidad con el control de excepciones estructurado.
Compatibilidad con atributos personalizados.
Recolección de elementos no utilizados.
Emplear delegados en lugar de punteros a funciones para mayor
seguridad y protección de tipos.
Luis Dueñas Pag 22
La Biblia de Visual Basic .NET
1.4. Novedades del .NET Framework 4
En esta versión del .NET Framework existen muchas novedades entre las
cuales podemos mencionar:
Mejoras en funciones del entorno del sistema: [Link]
Nuevas propiedades para detectar si el Sistema Operativo es de
64 bits: is64BitOperatingSystem y si el Proceso es de 64 Bits:
is64BitProcess.
Más valores devueltos para las carpetas o folders especiales del
sistema en la enumeración SpecialFolder.
Mejoras en funciones de entrada y salida: [Link]
Nuevos métodos para leer gran cantidad de directorios:
[Link] y para leer gran cantidad de
archivos de uno o más directorios: [Link].
Nuevos métodos para manejar archivos usando todas sus
líneas: [Link], [Link], [Link].
Nuevo método para copiar una secuencia de memoria en otra:
[Link].
La nueva sobre carga de [Link] permite combinar rutas
de accesos de archivos.
Mejora de los algoritmos de compresión de archivos: GZip
Stream y DeflateStream para no aumentar tamaño de los
archivos ya comprimidos y también eliminación de restricción
del tamaño de 4GB.
Compatibilidad con archivos asignados a memoria, lo cual sirve
para editar archivos muy grandes y crear memoria compartida
para la comunicación entre procesos: MemoryMappedFile.
Mejoras en Diagnóstico y Rendimiento: [Link]
Luis Dueñas Pag 23
La Biblia de Visual Basic .NET
Cálculo del uso del procesador y de la memoria por dominio de
la aplicación y no solo por proceso.
Monitoreo y recopilación de estadísticas para todos los dominios
de aplicación con la propiedad [Link].
Administrar excepciones que indican un estado de proceso
dañado mediante el atributo [Link].
HandleProcessCorruptedStateExceptionsAttribute.
Mejora en tratamiento de Cadenas: [Link] y [Link].
StringBuilder
Se ha sobrecargado los métodos: [Link] y [Link].
Nuevo método para verificar si una cadena esta vacía o nula o
con espacios en blanco: [Link].
Nuevo método para limpiar el objeto constructor de cadenas:
[Link].
Mejora en manejo de Colecciones: [Link]
Nueva clase genérica SortedSet que permite ordenar
automáticamente los elementos del conjunto después de una
inserción, eliminación o búsqueda de elementos.
Programación Paralela: [Link]
Paralelismo de datos mediante: [Link] y [Link]
Paralelismo de tareas mediante: [Link], [Link]
New y [Link].
LINQ Paralelo (PLINQ) mediante operadores: AsParallel,
AsSequential, AsOrdered, ForAll, AsUnordered, WithCacellation,
WithDegreeOfParallelism.
Mejoras en Acceso a Datos: [Link]
ADO .NET Entity Framework:
Luis Dueñas Pag 24
La Biblia de Visual Basic .NET
Objetos que ignoran la persistencia
Funciones en consultas LINQ.
Generación código personalizado capa de objeto.
Datos dinámicos:
Validación automática basada en restricciones definidas
en el modelo de datos.
Servicios de Datos de WCF:
Enlace de datos.
Contar las entidades de un conjunto de entidades.
Paginación controlada por servidor.
Proyecciones de consultas.
Proveedores de servicios de datos personalizados.
Transmitir por secuencias recursos binarios
Mejoras en ASP NET: [Link]
Nueva API caché, estado de sesión.
Nuevo administrador precarga de aplicación.
Compatibilidad mejorada con estándares web.
Nuevas características en controles de datos.
Mejora en administración de estados de vista.
Nuevo control Chart para graficos.
Mejoras en MVC.
Datos dinámicos.
Compatibilidad en Microsoft Ajax Library.
Luis Dueñas Pag 25
La Biblia de Visual Basic .NET
Intellisense mejorado para JScript.
Autocompletar HTML y ASP .NET
Mejoras en Windows Presentations Foundation (WPF):
Nuevos controles: Calendar, DataGrid y DatePicker.
VisualStateManager: cambio estados control.
Gráficos y animación admite redondeo diseño
Mejora en la presentación de texto y color.
Enlace en Command de InputBinding, objetos dinámicos y la
propiedad Text.
XBAP admite la comunicación con la página web y la
implementación de plena confianza.
[Link] permite comunicarse con la barra de
tareas de Windows 7.
Mejoras en WPF y Silverlight Designer VS2010.
Mejoras en Windows Communication Foundation (WCF):
Activación basada en la configuración: no svc.
[Link]: direcciones URL sin ex.
Compatibilidad varios enlaces de sitios de IIS.
Servicio enrutamiento: mensajes según contenido.
Compatibilidad con WS-Discovery.
Servicios de flujo trabajo: integra WCF y WWF.
Características de WCF REST:
Caché de servicios Web HTTP.
Compatibilidad con formatos Web HTTP.
Luis Dueñas Pag 26
La Biblia de Visual Basic .NET
Página de ayuda de los servicios Web HTTP.
Control de Errores Web HTTP.
Compatibilidad con JavaScript en dominios: JSON.
Configuración simplificada.
Mejoras en Windows Workflow Foundation (WWF):
Modelo mejorado de actividad de flujo de trabajo.
Opciones completas de actividad composición.
Biblioteca de actividades integrada ampliada.
Modelo explícito de datos de actividad.
Opciones mejoradas de hospedaje, persistencia y seguimiento:
Persistencia explícita mediante la actividad Persist.
Persistencia sin descarga.
Impedir la persistencia mediante zonas sin persistencia.
Uso de transacciones de ambiente del host.
Grabación de información de seguimiento en el registro
de eventos.
Reanudación de flujos de trabajo pendientes usando un
objeto Bookmark.
Mayor facilidad para extender el diseñador de WWF.
Luis Dueñas Pag 27
La Biblia de Visual Basic .NET
2. Visual Studio .NET 2010
Visual Studio .NET es la herramienta de desarrollo Microsoft que utiliza la
plataforma de desarrollo .NET Framework, para crear rápidamente
aplicaciones .NET de todo tipo. Podría crear aplicaciones simples usando el
bloc de notas y un compilador .NET, pero si la aplicación es compleja y
tiene muchas pantallas demoraría demasiado, el Visual Studio le permite
simplificar todo el desarrollo de desarrollo e inclusive las pruebas.
A continuación se muestra la descripción del IDE y las novedades de Visual
Studio 2010 obtenidas del MSDN de Microsoft (ver referencias 6 y 7 al final
del libro).
Luis Dueñas Pag 28
La Biblia de Visual Basic .NET
2.1. Descripción del Entorno Integrado de Desarrollo (IDE)
La gama de productos de Visual Studio comparte un único entorno de
desarrollo integrado (IDE) que se compone de varios elementos: la barra
de menús, la barra de herramientas Estándar, varias ventanas de
herramientas que se acoplan u ocultan automáticamente a la izquierda, en
la parte inferior y a la derecha, así como en el espacio del editor. Las
ventanas de herramientas, menús y barras de herramientas disponibles
dependen del tipo de proyecto o archivo en el que esté trabajando.
Gráfico 1.2: IDE con la configuración de desarrollo general
aplicada
Dependiendo de la configuración aplicada y de las subsiguientes
personalizaciones que haya realizado, variará la colocación de las ventanas
de herramientas y de otros elementos en el IDE. Puede cambiar la
configuración mediante el Import and Export Settings Wizard. Al
seleccionar la opción Restablecer todas las configuraciones, se puede
cambiar el lenguaje de programación predeterminado.
Puede desplazarse y acoplar ventanas con facilidad mediante el rombo de
guía visual u ocultar temporalmente las ventanas utilizando el comando
Ocultar automáticamente.
Luis Dueñas Pag 29
La Biblia de Visual Basic .NET
Puede utilizar el modelo de automatización de Visual Studio para
automatizar y extender el IDE.
Sistema de Proyectos
Las soluciones y los proyectos contienen elementos en forma de
referencias, conexiones de datos, carpetas y archivos necesarios para crear
la aplicación. Un contenedor de tipo solución puede contener varios
proyectos y un contenedor de tipo proyecto normalmente contiene varios
elementos.
El Explorador de Soluciones muestra soluciones, sus proyectos y los
elementos incluidos en dichos proyectos. En el Explorador de soluciones,
puede abrir archivos para editar, agregar nuevos archivos a un proyecto y
ver las propiedades de las soluciones, proyectos y elementos.
Gráfico 1.3: Ventana del Explorador de Soluciones
Editores y Diseñadores
El editor y los diseñadores que utilice dependerán del tipo de archivo o
documento que esté creando. El Editor de texto es el procesador de textos
Luis Dueñas Pag 30
La Biblia de Visual Basic .NET
básico del IDE, mientras que el Editor de código es el editor de código
fuente básico.
Otros editores, como el Editor CSS, el Diseñador HTML y el Diseñador de
páginas Web, comparten muchas de las características del Editor de
código, junto con mejoras específicas en el tipo de código o de marcado
admitido.
Los editores y diseñadores normalmente tienen dos vistas: una vista de
diseño gráfica y la vista de código subyacente o vista de código fuente. La
vista de diseño le permite especificar la ubicación de los controles y otros
elementos en la interfaz de usuario o la página web. Puede arrastrar
controles desde el cuadro de herramientas y colocarlos en la superficie de
diseño.
Gráfico 1.4: Diseñador de Páginas Web vista Diseño
La vista Código fuente muestra el código fuente del archivo o documento.
Esta vista admite ayudas de codificación como IntelliSense, secciones de
código plegables, Refactorización (C#) e inserción de fragmentos de
código. Otras características incluyen el ajuste automático de línea, los
marcadores y la visualización de números de línea, por citar algunos.
Luis Dueñas Pag 31
La Biblia de Visual Basic .NET
Gráfico 1.5: Diseñador de Páginas Web vista Código Fuente
Algunos editores, como el Diseñador de páginas web y el Diseñador XAML,
también proporcionan una vista híbrida que le permite ver la vista del
gráfico y del código de un archivo simultáneamente. Esta vista se llama la
Vista dividida.
Luis Dueñas Pag 32
La Biblia de Visual Basic .NET
Gráfico 1.6: Diseñador de Páginas Web vista Dividida
Herramientas de compilación y depuración
Visual Studio proporciona un sólido conjunto de herramientas de
compilación y depuración. Con las configuraciones de compilación puede
seleccionar los componentes que se van a generar, excluir los que no se
van a generar y determinar cómo se van a generar los proyectos
seleccionados y en qué plataforma. Puede tener configuraciones de
compilación para soluciones y para proyectos.
Cuando genera, está comenzando el proceso de depuración. La
compilación de la aplicación le ayuda a detectar errores de compilación.
Estos errores pueden deberse a una sintaxis incorrecta, a palabras clave
mal escritas o a divergencias entre los tipos. La Resultados (Ventana)
muestra estos tipos de errores.
Luis Dueñas Pag 33
La Biblia de Visual Basic .NET
Gráfico 1.7: Ventana de salida con información de compilación
Después de generar la aplicación, puede utilizar el depurador para detectar
y corregir problemas como errores lógicos y semánticos que se descubren
en tiempo de ejecución. En el modo de interrupción, puede examinar las
variables locales y otros datos pertinentes utilizando herramientas como
Ventanas de variables y la Ventana Memoria.
Gráfico 1.8: Ventana de formulario VB en modo interrupción
Luis Dueñas Pag 34
La Biblia de Visual Basic .NET
Gráfico 1.9: Ventanas de herramientas de depuración
La Ventana Lista de errores muestra errores, advertencias y otros mensajes
relacionados con la depuración.
Luis Dueñas Pag 35
La Biblia de Visual Basic .NET
2.2. Novedades de Visual Studio 2010
A continuación presentamos de forma resumida las novedades de Visual
Studio 2010:
Novedades en Lenguajes
Visual Basic 2010: Continuación de línea implícita, las
propiedades implementadas automáticamente y los
inicializadores de colección.
Visual C# 2010: Tipo dynamic, los argumentos opcionales y con
nombre, la programación de Office mejorada y la varianza.
Visual C++ 2010: Expresiones lambda, el declarador de
referencias de valores R y las palabras clave auto, decltype y
static_assert.
Novedades del Editor de Visual Studio
Comportamiento de acoplamiento mejorado.
Zoom.
Selección de cuadros.
Jerarquía de llamadas.
Navegar a.
Resaltar referncias.
Generar a partir del uso.
Modo de sugerencia de Intellisense.
Novedades en el desarrollo de Office
Desarrollar Soluciones para Microsoft Office 2010.
Mayor compatibilidad con la cinta de opciones en las soluciones
para Microsoft Office 2010.
Luis Dueñas Pag 36
La Biblia de Visual Basic .NET
.NET Framework 4 como destino.
Microsoft Office 2010 incluye el Motor en tiempo de ejecución
de Visual Studio Tools para Office.
Implementar las soluciones de Office para todos los usuarios.
Implementar varias soluciones de Office en un solo paquete.
Realizar acciones adicionales después de la instalación de la
solución de Office.
Novedades en el desarrollo de Aplicaciones de Datos
Conectarse a orígenes de datos
Enlace de datos de arrastrar y colocar para WPF.
Enlace de datos de arrastrar y colocar para Silverlight.
Conectar a datos en varios objetos.
Extender consultas en el control EntityDataSource.
Herramientas de Entity Data Model
Generación de código de capa de objeto personalizado.
Compatibilidad con Model-First.
Compatibilidad con tipos complejos.
Servicio de asignación de nombres.
Funcionalidad mejorada del Explorador de modelos.
Extensibilidad de Entity Designer.
Novedades en el desarrollo con SharePoint
Crear y ejecutar las pruebas unitarias y depurar las aplicaciones
de SharePoint con IntelliTrace. (Requiere Service Pack 1).
Importar, modificar y ampliar paquetes de soluciones (.wsp).
Luis Dueñas Pag 37
La Biblia de Visual Basic .NET
Desarrollar soluciones de SharePoint con plantillas para los
proyectos y elementos de proyecto.
Diseñar formularios de asociación e iniciación para flujos de
trabajo secuenciales y de estados.
Agregar e integrar datos back-end usando modelos de
Conectividad a datos profesionales (BDC).
Crear elementos web y páginas de aplicación de sitios de
SharePoint.
Examinar los sitios de SharePoint con el Explorador de
servidores.
Empezar a depurar las aplicaciones de SharePoint presionando
F5.
Crear y validar paquetes de soluciones.
Ampliar los elementos de proyecto de SharePoint existentes y
agregar menús contextuales.
Novedades en desarrollo de Reportes con Microsoft Reports
Diseñador de informes para el esquema RDL 2008.
Nuevo Asistente para informes.
Mejoras en los controles ReportViewer.
Compatibilidad de AJAX en el control de servidor web de ASP
.NET
Mejoras de programación en los controles ReportViewer.
Luis Dueñas Pag 38
La Biblia de Visual Basic .NET
3. Visual Basic .NET 2010
Visual Basic 2010 es la última versión del lenguaje Visual Basic de Microsoft
que continúa con la facilidad de las versiones anteriores pero agrega nueva
funcionalidad para mejorar el desarrollo.
En esta parte veremos algunas características del Lenguaje, tales como las
estructuras de control de flujo, los tipos de datos, operadores y variables,
además de las novedades de la versión 2010, dicha información es también
obtenida del MSDN de Microsoft (ver referencias 8, 9, 10, 11 y 12 al final
del libro).
3.1. Estructuras de Control de Flujo
Las estructuras de control de flujo se pueden clasificar en:
Estructuras de decisión
Visual Basic permite probar condiciones y realizar diferentes operaciones en
función de los resultados de la prueba. Puede comprobar si una condición
es verdadera o falsa, los distintos valores de una expresión o las diferentes
excepciones que se generan al ejecutar una serie de instrucciones.
En el siguiente ejemplo se muestra una estructura de decisión que prueba
si el valor de una condición es true y emprende distintas acciones en
función del resultado.
Gráfico 1.10: Ejemplo de una estructura de decisión
Luis Dueñas Pag 39
La Biblia de Visual Basic .NET
Construcción If...Then...Else: Permiten probar una o más condiciones y
ejecutar una o más instrucciones en función de cada condición. Puede
probar las condiciones y tomar medidas de las maneras siguientes:
Ejecutar una o más instrucciones si una condición es True.
Ejecutar una o más instrucciones si una condición es False.
Ejecutar algunas instrucciones si una condición es True y otras
si es False.
Probar una condición adicional si una condición anterior es
False.
La estructura de control que proporciona todas estas posibilidades es
Instrucción If...Then.... Puede utilizar una versión de una línea si tiene
simplemente una comprobación y una instrucción para ejecutar. Si
tiene un conjunto más complejo de condiciones y acciones, puede
utilizar la versión de varias líneas.
'Sintaxis de múltiples líneas:
If condición1 [ Then ]
[ instrucciones ]
[ ElseIf condición2 [ Then ]
[instrucciones] ]
[ Else
[instrucciones] ]
End If
'Sintaxis de una simple línea:
If condición Then [instrucción] [ Else [instrucción] ]
Construcción Select...Case: Permite evaluar una expresión una vez y
ejecutar distintos conjuntos de instrucciones basados en diferentes
valores posibles.
Select [ Case ] expression
[ Case listaExpressiones
[instrucciones] ]
[ Case Else
Luis Dueñas Pag 40
La Biblia de Visual Basic .NET
[instrucciones] ]
End Select
Construcción Try...Catch...Finally: Permiten ejecutar un conjunto de
instrucciones en un entorno que conserva el control si una de las
instrucciones provoca una excepción. Puede tomar distintas medidas
para excepciones diferentes. Opcionalmente, puede especificar un
bloque de código que se ejecuta antes de salir de la construcción
Try...Catch...Finally completa, sin tener en cuenta el resultado.
Try
[instrucciones]
[ Exit Try ]
[ Catch [ exception [ As type ] ] [ When expression ]
[instrucciones]
[ Exit Try ] ]
[ Catch ... ]
[ Finally
[instrucciones] ]
End Try
Estructuras de bucles
Las estructuras de bucles de Visual Basic permiten ejecutar una o varias
líneas de código de forma repetitiva. Puede repetir las instrucciones de una
estructura de bucles hasta que una condición sea True, una condición sea
False, un número de veces especificado o una vez para cada objeto de una
colección.
En el siguiente ejemplo se muestra una estructura de bucle que ejecuta un
conjunto de instrucciones hasta que una condición se convierta en
verdadera.
Luis Dueñas Pag 41
La Biblia de Visual Basic .NET
Gráfico 1.11: Ejemplo de una estructura de bucles
Bucles While: La construcción While...End While ejecuta un conjunto de
instrucciones mientras la condición especificada en la instrucción While
sea True.
While condición
[instrucciones]
[ Exit While ]
[instrucciones]
End While
Bucles Do: La construcción Do...Loop le permite probar una condición al
comienzo o al final de una estructura de bucle. También puede
especificar si repite el bucle mientras la condición sigue siendo True o
hasta que se convierta en True.
Do { While | Until } condición
[instrucciones]
[ Exit Do ]
[instrucciones]
Loop
ó
Do
[instrucciones]
[ Exit Do ]
[instrucciones]
Loop { While | Until } condición
Luis Dueñas Pag 42
La Biblia de Visual Basic .NET
Bucles For: La construcción For...Next ejecuta el bucle un número fijo
de veces. Utiliza una variable de control de bucle, también denominada
contador para realizar el seguimiento de las repeticiones. Especifica los
valores de inicio y fin de este contador, y puede especificar
opcionalmente la cantidad en la que se incrementa de una repetición a
la siguiente.
For contador [ As TipoDato ] = inicio To fin [ Step paso ]
[instrucciones]
[ Continue For ]
[instrucciones]
[ Exit For ]
[instrucciones]
Next [contador]
Bucles For Each: La construcción For Each...Next ejecuta un conjunto
de instrucciones una vez para cada elemento de una colección.
Especifica la variable de control de bucle pero no tiene que determinar
los valores de inicio y fin para ella.
For Each elemento [ As TipoDato ] In lista
[instrucciones]
[ Continue For ]
[instrucciones]
[ Exit For ]
[instrucciones]
Next [ elemento ]
Estructuras de control adicionales
Construcción Using...End Using: Establece un bloque de instrucciones
dentro del cual utiliza un recurso como una conexión de SQL. Puede
adquirir el recurso opcionalmente con la instrucción Using. Cuando sale
del bloque Using, Visual Basic dispone automáticamente del recurso
para que esté disponible para otro código. El recurso debe ser local y
ser descartable.
Luis Dueñas Pag 43
La Biblia de Visual Basic .NET
Using { listarecurso | expressionrecurso }
[instrucciones]
End Using
Construcción With...End With: Permite especificar una referencia de
objeto una vez y ejecutar luego una serie de instrucciones que tienen
acceso a sus miembros. Esto puede simplificar su código y mejorar el
rendimiento porque Visual Basic no tiene que restablecer la referencia
para cada instrucción que tiene acceso a él.
With object
[instrucciones]
End With
Luis Dueñas Pag 44
La Biblia de Visual Basic .NET
3.2. Tipos de Datos en Visual Basic
El tipo de datos de un elemento de programación hace referencia al tipo de
datos que puede contener y a cómo se almacenan dichos datos. Los tipos
de datos se aplican a todos los valores que pueden almacenarse en la
memoria del equipo o participar en la evaluación de una expresión. Cada
variable, literal, constante, enumeración, propiedad, parámetro de
procedimiento, argumento de procedimiento y valor devuelto por un
procedimiento tiene un tipo de datos.
Tipos de datos declarados
A menos que utilice la programación sin tipos, debe declarar los tipos de
datos de todos los elementos de programación.
Un elemento de programación se define con una instrucción de declaración
y su tipo de datos se especifica con la cláusula As. La tabla siguiente
muestra las instrucciones utilizadas para declarar diversos elementos.
Elemento de Declaración de tipos de datos
programación
Variable En una Instrucción Dim
Dim amount As Double
Static yourName As String
Public billsPaid As Decimal = 0
Literal Con un carácter de tipo literal
Dim searchChar As Char = "."C
Constante En una Instrucción Const
Const modulus As Single = 4.17825F
Luis Dueñas Pag 45
La Biblia de Visual Basic .NET
Enumeración En una Instrucción Enum
Public Enum colors
Propiedad En una Instrucción Property
Property region() As String
Parámetro de En una Instrucción Sub, Function u Operador
procedimiento Sub addSale(ByVal amount As Double)
Argumento de En el código de llamada; cada argumento es un
procedimiento elemento de programación que ya se ha declarado o
una expresión que contiene los elementos declarados
subString = Left(inputString, 5)
Valor devuelto por En una Instrucción u Operador
procedimiento Function convert(ByVal b As Byte) As String
Resumen de Tipos de datos
En la tabla siguiente se muestran los tipos de datos de Visual Basic .NET,
los tipos compatibles con Common Language Runtime, su asignación de
almacenamiento nominal y sus intervalos de valores.
Tipo de Tipo CLR Asignación de Intervalo de valores
Visual almacenamiento
Basic nominal
Boolean Boolean En función de la True o False
plataforma de
Luis Dueñas Pag 46
La Biblia de Visual Basic .NET
implementación
Byte Byte 1 byte 0 a 255 (sin signo)
Char Char 2 bytes 0 a 65535 (sin signo)
(carácter
individual
)
Fecha DateTime 8 bytes [Link] (medianoche) del 1 de
enero de 0001 a [Link]
p.m. del 31 de diciembre de
9999.
Decimal Decimal 16 bytes 0 a +/-
[Link].[Link]
†
43.950.335 (+/-7,9... E+28)
sin separador decimal; 0 a +/-
7,92281625142643375935439
50335 con 28 posiciones a la
derecha del decimal;
el número distinto de cero más
pequeño es +/-
0,00000000000000000000000
†
00001 (+/-1E-28)
Double Double 8 bytes -1,79769313486231570E+308
(punto a -4,94065645841246544E-
Luis Dueñas Pag 47
La Biblia de Visual Basic .NET
flotante 324 † para los valores
de negativos;
precisión 4,94065645841246544E-324 a
†
doble) 1,79769313486231570E+308
para los valores positivos
Integer Int32 4 bytes -[Link] a
[Link] (con signo)
Long Int64 8 bytes -[Link].854.775.808 a
(entero [Link].854.775.807
largo) (9,2...E+18 †) (con signo)
Objeto Object 4 bytes en Cualquier tipo puede
(clase) plataforma de 32 almacenarse en una variable
bits de tipo Object
8 bytes en
plataforma de 64
bits
SByte SByte 1 byte -128 a 127 (con signo)
Short Int16 2 bytes -32.768 a 32.767 (con signo)
(entero
corto)
Single Single 4 bytes -3,4028235E+38 a -
(punto 1,401298E-45 † para los
Luis Dueñas Pag 48
La Biblia de Visual Basic .NET
flotante valores negativos;
de 1,401298E-45 a
precisión 3,4028235E+38 † para los
sencilla) valores positivos
String String En función de la 0 a 2.000 millones de
(longitud (clase) plataforma de caracteres Unicode aprox.
variable) implementación
UInteger UInt32 4 bytes 0 a [Link] (sin signo)
ULong UInt64 8 bytes 0a
[Link].709.551.615
(1,8...E+19 †) (sin signo)
User- (hereda de En función de la Cada miembro de la estructura
Defined ValueType plataforma de tiene un intervalo de valores
(estructur ) implementación determinado por su tipo de
a) datos y es independiente de
los intervalos de valores
correspondientes a los demás
miembros.
UShort UInt16 2 bytes 0 a 65.535 (sin signo)
Luis Dueñas Pag 49
La Biblia de Visual Basic .NET
Consumo de memoria
Al declarar un tipo de datos básico, no debe suponerse que su consumo de
memoria es igual a su asignación de almacenamiento nominal. Esto se
debe a las consideraciones siguientes:
Asignación de almacenamiento: El CLR puede asignar el
almacenamiento en función de las características actuales de la
plataforma en la que se ejecuta la aplicación. Si la memoria está casi
completa, se pueden empaquetar los elementos declarados de la forma
más estrecha posible. En otros casos, se podrían alinear las direcciones
de memoria a los límites del hardware naturales para optimizar el
rendimiento.
Ancho de plataforma: La asignación de almacenamiento en una
plataforma de 64 bits es diferente a la asignación en una plataforma de
32 bits.
Las mismas consideraciones se aplican a cada miembro de un tipo de datos
compuesto, como una estructura o una matriz. No se pueden sumar
simplemente todas las asignaciones de almacenamiento nominales de los
miembros de tipo. Además, existen otras consideraciones, como las
siguientes:
Sobrecarga. Algunos tipos compuestos tienen requisitos adicionales de
memoria. Por ejemplo, una matriz utiliza memoria adicional para la
matriz en sí y para cada dimensión. En una plataforma de 32 bits, esta
sobrecarga corresponde a 12 bytes y 8 bytes por cada dimensión. En
una plataforma de 64 bits, los requisitos se duplican.
Diseño de almacenamiento. No debe suponerse que el orden de
almacenamiento en la memoria es igual al orden de declaración. Ni
siquiera pueden hacerse predicciones sobre la alineación de bytes,
como un límite de 2 bytes o de 4 bytes. Si define una clase o estructura
y necesita controlar el diseño de almacenamiento de sus miembros,
puede aplicar el atributo StructLayoutAttribute a la clase o estructura.
Una variable Object que haga referencia a un tipo de datos básico o
compuesto, utiliza 4 bytes además de los datos contenidos en el tipo de
datos.
Luis Dueñas Pag 50
La Biblia de Visual Basic .NET
3.3. Operadores y Expresiones en Visual Basic
Un operador es un elemento de código que realiza una operación en uno o
más elementos de código que contienen valores. Los elementos de valor
incluyen variables, constantes, literales, propiedades, valores devueltos de
procedimientos Function y Operator y expresiones.
Una expresión es una serie de elementos de valor combinados con
operadores, que produce un nuevo valor. Los operadores actúan sobre los
elementos de valor realizando cálculos, comparaciones y otras operaciones.
Operadores aritméticos
Operador Operación Ejemplo
+ Suma Dim x As Integer = 67 + 34
- Resta Dim y As Integer = 67 – 34
* Multiplicación Dim x As Double = 50 * 20
Resultado: 1000
/ División decimal Dim y As Double = 50 / 20
Resultado: 2.5
^ Exponenciación Dim x As Double = 5 ^ 2
Resultado: 25
\ División entera Dim x As Integer = 50 / 20
Luis Dueñas Pag 51
La Biblia de Visual Basic .NET
Resultado: 2
Mod Residuo Dim y As Double = 50 Mod 20
Resultado: 10
Operadores de comparación
Operador Operación Ejemplo
= Igualdad 23 = 33 ' False
23 = 23 ' True
<> Desigualdad 23 <> 33 ' True
23 <> 23 ' False
< Menor que 23 < 33 ' True
23 < 23 ' False
> Mayor que 23 > 33 ' False
33 > 23 ' True
<= Menor o igual que 23 <= 33 ' True
33 <= 23 ' False
Luis Dueñas Pag 52
La Biblia de Visual Basic .NET
>= Mayor o igual que 23 >= 33 ' False
23 >= 23 ' True
Operadores de concatenación
Operador Operación Ejemplo
+ Suma 2 números o 1+2=3
cadenas. Los 2
“1” + “2” = “12”
operandos deben ser
del mismo tipo sino se 1 + “2” = Error
genera un error.
& Solo se usa para 1 & 2 = “12”
sumar cadenas.
“1” & “2” = “12”
Realiza una
conversión implícita si 1 & “2” = “12”
uno o los 2 operandos
son números.
Operadores lógicos
Operador Operación Ejemplo
Not Negación lógica. Dim x As Boolean = true
Dim y As Boolean = Not x ' False
Luis Dueñas Pag 53
La Biblia de Visual Basic .NET
And Conjunción lógica. a = 23 > 14 And 11 > 8 ' True
b = 14 > 23 And 11 > 8 ' False
Or Disyunción lógica. c = 23 > 14 Or 8 > 11 ' True
d = 23 > 67 Or 8 > 11 ' False
Xor Exclusión lógica. e = 23 > 67 Xor 11 > 8 ' True
f = 23 > 14 Xor 11 > 8 ' False
g = 14 > 23 Xor 8 > 11 ' False
AndAlso Conjunción lógica con a = 23 < 14 AndAlso 11 > 8 ' False
corto circuito.
Al ser True la primera condición sale
OrElse Disyunción lógica con b = 23 > 14 OrElse 8 > 11 ' True
corto circuito.
Al ser True la primera condición sale
Luis Dueñas Pag 54
La Biblia de Visual Basic .NET
3.4. Variables en Visual Basic
Visual Basic, al igual que la mayoría de los lenguajes de programación, usa
variables para almacenar los valores. Una variable tiene un nombre (la
palabra que se usa para referirse al valor que contiene la variable). Una
variable también tiene un tipo de datos, que determina el tipo de datos que
puede almacenar la variable. Una variable puede representar una matriz si
tiene que almacenar un conjunto indizado de elementos de datos
estrechamente relacionados entre sí.
La inferencia de tipos de variable local permite declarar las variables sin
tener que indicar de forma explícita un tipo de datos. En lugar de ello, el
compilador deduce el tipo de la variable a partir del tipo de la expresión de
inicialización.
Niveles de Declaración de Variables
Valor local y variables miembros
Una variable local es aquella que se declara dentro de un
procedimiento. Una variable miembro es un miembro de un tipo de
Visual Basic; se declara en el nivel de módulo, dentro de una clase,
estructura o módulo, pero no dentro de ningún procedimiento interno
de esa clase, estructura o módulo.
Variables compartidas y de instancias
La categoría de una variable miembro, en una clase o estructura,
depende de que la variable esté o no compartida. Si una variable se
declara con la palabra clave Shared, es una variable compartida, y
existe en una única copia compartida por todas las instancias de la
clase o estructura.
De lo contrario, es una variable de instancia, y se crea una copia
independiente de ella para cada instancia de la clase o estructura. Una
copia determinada de una variable de instancia sólo está disponible en
la instancia para la cual se creó. Es independiente de una copia en
cualquier otra instancia.
Luis Dueñas Pag 55
La Biblia de Visual Basic .NET
Declarar el tipo de dato
La cláusula As de la instrucción de declaración permite definir el tipo de
datos o de objetos de la variable que se está declarando. Se puede
especificar cualquiera de los siguientes tipos para una variable:
Un tipo de datos básico, como Boolean, Long o Decimal.
Un tipo de datos compuesto, como una matriz o una estructura.
Un tipo de objeto o clase, definido en su aplicación o en otra aplicación
Clase de .NET Framework, como Label o TextBox
Un tipo de interfaz, como IComparable o IDisposable
Se pueden declarar varias declarar distintas variables en la misma
instrucción sin necesidad de repetir el tipo de datos. En las instrucciones
siguientes, las variables i, jy k se declaran como tipo Integer, l y m como
Long, y x e y como Single:
Dim i, j, k As Integer
Dim l, m As Long, x, y As Single
Inferencia de tipo de variable local
La inferencia de tipos se usa para determinar los tipos de datos de las
variables locales que se han declarado sin ninguna cláusula As. El
compilador deduce el tipo de la variable a partir del tipo de la expresión de
inicialización. Esto permite declarar variables sin especificar un tipo de
forma explícita. En el ejemplo siguiente, num1 y num2 son con
establecimiento inflexible de tipos como enteros.
Public Sub inferenceExample()
' Usando declaración explícita.
Dim num1 As Integer = 3
' Usando inferencia de tipo variable local.
Luis Dueñas Pag 56
La Biblia de Visual Basic .NET
Dim num2 = 3
End Sub
Declarar características
El período de duración de una variable representa el tiempo durante el cual
la variable está disponible para que pueda ser utilizada. En general, una
variable existe mientras el elemento que lo declara (como un
procedimiento o clase) siga existiendo. En algunos casos es posible
extender la duración de una variable.
El ámbito de una variable está formado por todo código que puede hacer
referencia a la variable sin tener que calificar su nombre. El ámbito de una
variable está determinado por la ubicación en la que se haya declarado la
variable. El código de una región determinada puede utilizar las variables
definidas en dicha región sin necesidad de especificar los nombres de las
variables.
El nivel de acceso de una variable es la extensión de código que tiene
permiso para tener acceso a ella. El modificador de acceso (como Public o
Private) que utiliza en la instrucción Dim es quien determina esto.
Luis Dueñas Pag 57
La Biblia de Visual Basic .NET
3.5. Novedades de Visual Basic 2010
Propiedades auto implementadas
Las propiedades auto implementadas proporcionan una sintaxis abreviada
que permite especificar rápidamente una propiedad de una clase sin tener
que escribir el código Get y Set para la propiedad.
Inicializadores de colección
Los inicializadores de colección proporcionan una sintaxis abreviada que
permite crear una colección y rellenarla con un conjunto inicial de valores.
Los inicializadores de colección son útiles cuando se está creando una
colección a partir de un conjunto de valores conocidos como, por ejemplo,
una lista de opciones de menú o categorías.
Continuación de línea implícita
En muchos casos, la continuación de línea implícita permite continuar una
instrucción en la línea consecutiva siguiente sin utilizar el carácter de
subrayado (_).
Expresiones lambda de múltiples líneas y subrutinas
La compatibilidad con la expresión lambda se ha expandido para admitir las
subrutinas además de las funciones de lambda de múltiples líneas y
subrutinas.
Nueva opción de la línea de comandos para especificar una
versión de lenguaje
Luis Dueñas Pag 58
La Biblia de Visual Basic .NET
La opción /langversion de la línea de comandos hace que el compilador
acepte únicamente la sintaxis que sea válida en la versión especificada de
Visual Basic.
Compatibilidad con la equivalencia de tipos
Ahora se puede implementar una aplicación que contiene información de
tipo incrustada en lugar de información de tipos que se importa desde un
ensamblado de interoperabilidad primario (PIA). Con la información de
tipos incrustada, la aplicación puede utilizar los tipos en un motor en
tiempo de ejecución sin necesidad de una referencia al ensamblado en
tiempo de ejecución. Si se publican varias versiones del ensamblado del
runtime, la aplicación que contiene la información de tipos incrustada
puede funcionar con las diferentes versiones sin que sea necesario volver a
compilarla.
Compatibilidad dinámica
Visual Basic enlaza a los objetos de los lenguajes dinámicos como
IronPython e IronRuby.
Covarianza y contravarianza
La covarianza permite usar un tipo más derivado que el especificado por el
parámetro genérico, mientras que la contravarianza permite utilizar un tipo
menos derivado. Esto permite la conversión implícita de las clases que
implementan interfaces variantes y proporciona mayor flexibilidad a la hora
de hacer coincidir las firmas de método con tipos de delegado variantes. Se
pueden crear interfaces y delegados variantes mediante las nuevas
palabras clave In y Out. .NET Framework también incluye compatibilidad
con la varianza para varios delegados e interfaces genéricos existentes,
incluidos la interfaz IEnumerable(Of T) y los delegados Action(Of T) y
Func(Of TResult).
Luis Dueñas Pag 59
La Biblia de Visual Basic .NET
Navegar a
Se puede usar la característica Navegar a para buscar un símbolo o un
archivo en código fuente. Puede buscar palabras clave incluidas en un
símbolo concatenado mediante notación Camel o caracteres de subrayado
a fin de dividir dicho símbolo en palabras clave.
Resaltar referencias
Al hacer clic en un símbolo en el código fuente, todas las instancias de ese
símbolo se resaltan en el documento.
En muchas estructuras de control, al hacer clic en una palabra clave, se
resaltan todas las palabras clave en la estructura. Por ejemplo, al hacer clic
en If en una construcción If...Then...Else, se resaltan todas las instancias
de If, Then, ElseIf, Else y End If de la construcción.
Para desplazarse al siguiente o anterior símbolo resaltado, puede usar
CTRL+MAYÚS+FLECHA ABAJO o CTRL+MAYÚS+FLECHA ARRIBA.
Generar a partir del uso
La característica Generar a partir del uso permite usar clases y miembros
antes de definirlos. Puede generar un código auxiliar para cualquier clase,
constructor, método, propiedad, campo o enumeración que desee utilizar
pero no ha definido todavía. Puede generar nuevos tipos y miembros sin
salir de su ubicación actual en el código. De este modo, se minimizan las
interrupciones en el flujo de trabajo.
La característica Generar a partir del uso admite estilos de programación
como el desarrollo de pruebas en primer lugar. Para obtener más
información, vea Generar a partir del uso.
Luis Dueñas Pag 60
La Biblia de Visual Basic .NET
Modo de sugerencia de IntelliSense
IntelliSense proporciona ahora dos alternativas para completar las
instrucciones de IntelliSense: el modo de finalización y el modo de
sugerencia. El modo de sugerencia se utiliza cuando las clases y los
miembros se usan antes de definirlos.
Luis Dueñas Pag 61
La Biblia de Visual Basic .NET
Preguntas de Repaso
1. Qué es .NET Framework?
2. Menciona 3 tipos de aplicaciones que se pueden crear en .NET
Framework.
3. Que tecnologías aparecieron con .NET Framework 3?
4. Menciona 5 lenguajes .NET.
5. Cuál es el criterio principal para seleccionar un Lenguaje .NET?
6. Que lenguaje es recomendable para aquellos que no tienen experiencia
con C, Java o la POO.
7. Cuáles son los componentes principales de .NET Framework?
8. Que es la BCL del .NET Framework?
9. Cómo se clasifican los tipos en .NET Framework?
10. Menciona 3 tipos complejos por referencia.
11. Cuál es la principal función de un espacio de nombres (Namespace)?
12. Menciona 5 espacios de nombres de la BCL.
13. Qué es el CLR del .NET Framework?
14. Cómo se llama el programa del CLR que se encarga de liberar
automáticamente la memoria que no esta siendo utilizada?
15. En qué tipo de lenguaje escriben el código los desarrolladores .NET
16. Qué es un ensamblado (Assembly) y en que lenguaje se encuentra?
Luis Dueñas Pag 62
La Biblia de Visual Basic .NET
17. Qué tipo de código ejecuta el CLR y en que lenguaje se encuentra?
18. Menciona 3 funciones del CLR.
19. Cuáles son los nuevos métodos de la clase Environment para verificar
sistemas y procesos de 64 bits?
20. Cuáles son los nuevos métodos de la clase Directory para listar
directorios y archivos?
21. Con qué clase se puede manejar los archivos asignados a memoria?
22. Qué métodos se han agregado para la clase String y StringBuilder
respectivamente para facilitar el manejo de cadenas?
23. Cuál es el espacio de nombres para trabajar con programación
paralela?
24. Menciona 3 mejoras en ASP .NET.
25. Cuáles son los nuevos controles que han aparecido en WPF?
26. Cuál es la ventaja principal de usar el Visual Studio 2010 en el
desarrollo de una Aplicación?
27. Menciona 3 ventanas del IDE de Visual Studio 2010.
28. Menciona 3 novedades del Editor de Visual Studio 2010.
29. Con qué otros productos Microsoft se integra el desarrollo desde Visual
Studio 2010?
30. Cuáles son las estructuras de decisión de Visual Basic .NET?
31. Cuáles son las estructuras de bucles de Visual Basic .NET?
Luis Dueñas Pag 63
La Biblia de Visual Basic .NET
32. Qué estructura adicional de Visual Basic simplifica la sintaxis y el acceso
a un objeto?
33. Menciona 5 tipos de datos simples en Visual Basic.
34. Menciona 5 operadores aritméticos de Visual Basic?
35. Qué operador es más rápido para sumar 2 cadenas: “+” o “&”.
36. Cuáles son los operadores lógicos de corto circuito en Visual Basic?
37. Qué tipo de variable debe usarse en lo posible en Visual Basic?
38. Menciona 3 novedades de Visual Basic 2010.
Luis Dueñas Pag 64
La Biblia de Visual Basic .NET
Capitulo 2: Programando con Visual Basic .NET
2010
En este segundo capítulo veremos cómo usar el lenguaje Visual Basic .NET
2010 para obtener información del entorno, acceder a las carpetas
especiales de Windows, acceder al registro de Windows, trabajar con
procesos o tareas, manejar los recursos de entrada y salida tales como
unidades, directorios, rutas y archivos. También veremos cómo programar
orientado a objetos creando y usando una librería de clases.
Además se verán las diferentes técnicas que hay en .NET para implementar
programación asíncrona tales como Threads, CallBacks, Eventos Asíncronos
y Programación Paralela.
Al final del capítulo se verá el tema de asegurar los datos de la aplicación
mediante la encriptación o el cifrado, ya sea simétrico o asimétrico,
también como realizar comprobaciones mediante resúmenes o valores
hash.
Luis Dueñas Pag 65
La Biblia de Visual Basic .NET
1. Trabajar con el Entorno de Windows y el Sistema
Para trabajar con el entorno de Windows existe una clase llamada
Environment que se encuentra en el espacio de nombres System, la cual
nos brinda información del sistema y si deseamos acceder al registro de
Windows ya sea para leer o escribir podemos usar la clase Registry que
pertenece al espacio de nombres Microsoft.Win32, además podemos
obtener los procesos o tareas ejecutándose en el sistema, abrir y cerrar
tareas mediante la clase Process de [Link].
1.1. Obtener Información del Sistema
La clase Environment tiene algunas propiedades que nos dan información
del sistema, tales como: MachineName, OSVersion, ProcessorCount,
UserDomainName, UserInteractive y UserName.
En .NET Framework 4 la clase Environment tiene 2 nuevas propiedades:
is64BitOperatingSystem y is64BitProcess que dan información sobre
Sistema y Procesos de 62 bits respectivamente.
Iniciamos nuestro primer ejemplo del libro con una aplicación Windows
Forms que muestre información del sistema.
Demo 01
Abra el Visual Studio 2010 y realice los siguientes pasos:
Del menu “File”, seleccionar “New Project”.
En el diálogo seleccionar como lenguaje “Visual Basic” y luego
“Windows”.
Seleccionar la plantilla “Windows Forms Application”.
Escribir como nombre de la aplicación: Demo01 y botón “OK”.
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Luis Dueñas Pag 66
La Biblia de Visual Basic .NET
Objeto Propiedad Valor
Form1 Name frmInfoSistema
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 300, 300
StartPosition CenterScreen
Text Información del Sistema
Label1 Name lblNombrePC
AutoSize True
Location 12,22
Text Nombre de la PC:
TextBox1 Name txtNombrePC
Location 118, 15
ReadOnly True
Size 141, 20
Label2 Name lblVersionSO
AutoSize True
Location 12,61
Text Versión del Sistema:
TextBox2 Name txtVersionSO
Location 118, 54
ReadOnly True
Size 141, 20
Label3 Name lblNroProcesadores
AutoSize True
Location 12,100
Text Nro Procesadores:
TextBox3 Name txtNroProcesadores
Location 118, 93
ReadOnly True
Size 141, 20
Label4 Name lblNombreUsuario
AutoSize True
Location 12,139
Text Nombre Usuario:
TextBox4 Name txtNombreUsuario
Location 118, 132
ReadOnly True
Size 141, 20
Label5 Name lblSistema64Bits
AutoSize True
Luis Dueñas Pag 67
La Biblia de Visual Basic .NET
Location 12,178
Text Sistema 64 Bits:
TextBox5 Name txtSistema64Bits
Location 118, 171
ReadOnly True
Size 141, 20
Label6 Name lblProceso64Bits
AutoSize True
Location 12,217
Text Proceso 64 Bits:
TextBox6 Name txtProceso64Bits
Location 118, 210
ReadOnly True
Size 141, 20
El diseño del formulario debe quedar similar al gráfico 2.1:
Gráfico 2.1: Diseño del formulario de información del sistema
Ingresar al editor de código (cuarto botón del explorador de soluciones)
y escribir el siguiente código.
Private Sub MostrarInformacionSistema(ByVal sender As [Link], ByVal
e As [Link]) Handles [Link]
[Link] = [Link]
[Link] = [Link]
Luis Dueñas Pag 68
La Biblia de Visual Basic .NET
[Link] = [Link]
[Link] = [Link]
[Link] = Environment. is64BitOperatingSystem
[Link] = Environment. is64BitProcess
End Sub
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 2.2: Ejecución del formulario información del sistema
Luis Dueñas Pag 69
La Biblia de Visual Basic .NET
1.2. Obtener Directorios Especiales de Windows
La clase Environment tiene una enumeración llamada SpecialFolders que
tiene una lista con los nombres de todas las carpetas o directorios
especiales de Windows, si deseamos obtener la ruta o ubicación en el
sistema de archivos (File System) de una carpeta se usa el método
GetFolderPath.
A continuación crearemos una aplicación que lista los nombres y rutas de
las carpetas especiales de Windows, las cuales han aumentado con la
versión 4 del .NET Framework.
Demo 02
Crear una aplicación Windows Forms en Visual Basic llamada: Demo02.
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmDirectWindows
Text Información Directorios Window
WindowState Maximized
ListView1 Name lvwDirectorio
Dock Fill
FullRowSelect True
GridLines True
HotTracking True
El diseño del formulario debe quedar similar al gráfico 2.3:
Luis Dueñas Pag 70
La Biblia de Visual Basic .NET
Gráfico 2.3: Diseño del formulario con directorios de Windows
Ingresar al editor de código y escribir el siguiente código.
Private Sub ListarDirectoriosWindows(ByVal sender As [Link], ByVal e
As [Link]) Handles [Link]
With lvwDirectorio
.[Link]("Nombre", 300, [Link])
.[Link]("Ruta", 600, [Link])
.View = [Link]
End With
Dim Tipo As Object = GetType([Link])
Dim Directorios() As String = [Enum].GetNames(Tipo)
Dim Folder As [Link]
Dim Fila As ListViewItem
For Each Directorio As String In Directorios
Folder = [Enum].Parse(Tipo, Directorio)
Fila = [Link](Directorio)
[Link]([Link](Folder))
Next
End Sub
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 71
La Biblia de Visual Basic .NET
Gráfico 2.4: Ejecución del formulario con directorios de
Windows
Luis Dueñas Pag 72
La Biblia de Visual Basic .NET
1.3. Acceder al Registro de Windows
La mayoría de programas de Windows guardan su configuración en el
Registro de Windows, el cual se puede ver usando la utilidad [Link],
desde .NET también podemos acceder a una sección del registro usando la
clase Registry y creando un RegistryKey, luego usamos los métodos
GetSubKeyNames para obtener todas las secciones y OpenSubKey para
abrir una sección, tal como se describe en el siguiente ejemplo.
Demo 03
Crear una aplicación Windows Forms en Visual Basic llamada: Demo03.
Cambiar de nombre al formulario [Link] por [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmRegistroWindows
Text Explorador Registro de Windows
WindowState Maximized
SplitContainer1 Name scRegistro
Dock Fill
TreeView1 Name tvwRegistro
(izquierda) Dock Fill
ListView1 Name lvwRegistro
(derecha) Dock Fill
El diseño del formulario debe quedar similar al gráfico 2.5:
Luis Dueñas Pag 73
La Biblia de Visual Basic .NET
Gráfico 2.5: Diseño del formulario registro de Windows
Ingresar al editor de código y escribir el siguiente código.
Imports Microsoft.Win32
Imports [Link]
<RegistryPermission([Link])> _
Public Class frmRegistroWindows
Private Sub CrearNodos(ByVal nodo As TreeNode, ByVal reg As RegistryKey)
Dim secciones() As String = [Link]
Dim seccion As String
Dim nuevoNodo As TreeNode
Dim nuevoReg As RegistryKey
For Each seccion In secciones
nuevoNodo = [Link](seccion)
nuevoReg = [Link](seccion)
If nuevoReg IsNot Nothing Then
CrearNodos(nuevoNodo, nuevoReg)
End If
Next
End Sub
Private Sub ListarRegistro(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
With lvwRegistro
.[Link]("Nombre", 100, [Link])
Luis Dueñas Pag 74
La Biblia de Visual Basic .NET
.[Link]("Tipo", 100, [Link])
.[Link]("Dato", 100, [Link])
.View = [Link]
End With
Dim nodoPC As TreeNode = [Link]("PC")
Dim nodoHKCU As TreeNode = _
[Link]("HKEY_CURRENT_USER")
Dim reg As RegistryKey = [Link]
CrearNodos(nodoHKCU, reg)
End Sub
Private Function ObtenerRuta(ByVal e As TreeNode) As String
Dim S As String = [Link]
If [Link] > 2 Then
S = ObtenerRuta([Link]) + "\\" + S
End If
Return (S)
End Function
Private Sub MostrarValores(ByVal sender As [Link], ByVal e As _
[Link]) Handles [Link]
[Link]()
If [Link] > 0 Then
Dim reg As RegistryKey = [Link]
Dim seccion As String = ObtenerRuta([Link])
[Link] = seccion
Dim registro As RegistryKey = [Link](seccion)
If registro IsNot Nothing Then
Dim claves() As String = [Link]
Dim clave As String
Dim fila As ListViewItem
For Each clave In claves
fila = [Link](clave)
[Link]([Link](clave).ToString)
[Link]([Link](clave))
Next
End If
End If
End Sub
End Class
Luis Dueñas Pag 75
La Biblia de Visual Basic .NET
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 2.6: Ejecución del formulario registro de Windows
Luis Dueñas Pag 76
La Biblia de Visual Basic .NET
1.4. Trabajar con Procesos o Tareas del Sistema
Para trabajar con procesos o tareas del sistema, se usa la clase Process del
espacio de nombres [Link], la cual tiene métodos como
GetProcesses que devuelve una lista con los nombres de todos los procesos
que se encuentran actualmente en ejecución, también podemos detectar
todos los procesos por nombre de un programa usando el método
GetProcessesByName. Para iniciar el proceso (ejecutar el programa)
podemos usar el método Start y para cerrarlo podemos usar los métodos
Close o Kill, tal como se muestra en el siguiente ejemplo.
Demo 04
Crear una aplicación Windows Forms en Visual Basic llamada: Demo04.
Cambiar de nombre al formulario [Link] por [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmListarTarea
Size 300,300
StartPosition CenterScreen
Text Administrador de Tareas
ListBox1 Name lstTarea
Dock Fill
ContextMenuStrip1 Name mnuTarea
Item1 mnuEjecutarTarea
Item2 mnuCerrarTarea
Timer1 Name tmrRefrescarTarea
Enabled True
Interval 5000
El diseño del primer formulario debe quedar similar al gráfico 2.7:
Luis Dueñas Pag 77
La Biblia de Visual Basic .NET
Gráfico 2.7: Diseño del formulario listar tareas
Agregar otro formulario, del menú “Project” seleccionar “Add Windows
Form”, escribir como nombre: [Link].
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form2 Name frmEjecutarTarea
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 300,150
StartPosition CenterScreen
Text Dialogo de Ejecutar Tarea
Label1 Name lblArchivo
AutoSize True
Location 12, 23
Text Selecciona Archivo de Proceso a
Ejecutar
TextBox1 Name txtArchivo
Location 15,39
Size 236,20
Button1 Name btnMostrarDialogoAbrir
Cursor Hand
Location 253,37
Size 23,23
Luis Dueñas Pag 78
La Biblia de Visual Basic .NET
Text …
Button2 Name btnAceptar
Cursor Hand
DialogResult OK
Location 15,79
Size 75,23
Text Aceptar
Button3 Name btn Cancelar
Cursor Hand
DialogResult Cancel
Location 176,79
Size 75,23
Text Cancelar
El diseño del segundo formulario debe quedar similar al gráfico 2.8:
Gráfico 2.8: Diseño del formulario ejecutar tarea
Ingresar al editor de código y escribir el siguiente código para el primer
formulario.
Imports [Link] 'Process
Public Class frmListarTarea
Private Sub ListarTareas()
[Link]()
Dim oProcesos() As Process = [Link]
Dim oProceso As Process
[Link]()
For Each oProceso In oProcesos
[Link]([Link])
Next
[Link]()
Luis Dueñas Pag 79
La Biblia de Visual Basic .NET
End Sub
Private Sub CargarDatos(ByVal sender As [Link], ByVal e As _
[Link]) Handles [Link]
[Link] = True
ListarTareas()
End Sub
Private Sub EjecutarTarea(ByVal sender As [Link], ByVal e As _
[Link]) Handles [Link]
If [Link] = [Link] _
AndAlso [Link] <> "" Then
[Link]([Link])
ListarTareas()
End If
End Sub
Private Sub CerrarTarea(ByVal sender As Object, ByVal e As _
[Link]) Handles [Link]
Dim oProcesos() As Process = _
[Link]([Link])
If [Link] > 0 Then
Dim oProceso As Process
For Each oProceso In oProcesos
[Link]()
Next
ListarTareas()
End If
End Sub
Private Sub RefrescarTarea(ByVal sender As [Link], ByVal e As _
[Link]) Handles [Link]
ListarTareas()
End Sub
End Class
Ahora escribir el siguiente código para el segundo formulario.
Imports [Link] 'OpenFileDialog
Public Class frmEjecutarTarea
Luis Dueñas Pag 80
La Biblia de Visual Basic .NET
Private Sub MostrarDialogoAbrir(ByVal sender As [Link], ByVal e _
As [Link]) Handles [Link]
Dim ofd As New OpenFileDialog
[Link] = "Selecciona Programa a Ejecutar"
[Link] = "Archivos de programa|*.exe"
If [Link] = [Link] Then
[Link] = [Link]
End If
End Sub
End Class
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 2.9: Ejecución del formulario listar tareas
Gráfico 2.10: Ejecución del formulario ejecutar tarea
Luis Dueñas Pag 81
La Biblia de Visual Basic .NET
2. Manejo de Entrada y Salida
.NET Framework tiene una amplia variedad de clases que permiten
controlar los recursos de entrada y salida, las cuales en su mayoría se
encuentran en el espacio de nombres [Link].
Hay clases que se usan para entrada y salida de archivos como Directory y
DirectortyInfo, DriveInfo, File y FileInfo, FileStream, FileSystemInfo, Path,
DeflateStream, GZipStream y SerialPort.
Otras clases se usan para leer y escribir secuencias o flujos, tales como
BinaryReader y BinaryWriter, StreamReader y StreamWriter, StringReader y
StringWriter, TextReader y TextWriter.
Finalmente, hay clases comunes de secuencias que son usadas para
diversos propósitos como: BufferedStream, CryptoStream, MemoryStream y
NetworkStream.
Para obtener más información sobre este tema ver referencia 13 al final del
libro.
En .NET existen 2 formas de usar un miembro de una clase, creando una
instancia de la clase y llamando al miembro o usando un miembro
compartido, por ejemplo las clases DirectoryInfo, DriveInfo, FileInfo se
tienen que crear objetos para usar sus métodos, pero también podemos
hacerlo directamente a través de las clases con miembros estáticos o
compartidos Directory, File, Path, etc.
2.1 Manejar Unidades, Directorios, Rutas y Archivos
Para manejar unidades debemos usar la clase DriveInfo, para manejar
directorios debemos usar la clase con miembros estáticos Directory o
instanciar la clase DirectoryInfo.
Para manejar Rutas de archivos se usa la clase con miembros estáticos
Path y para obtener información de un Archivo se usa la clase FileInfo.
A continuación presentamos un ejemplo sobre una aplicación que explora
directorios de una cierta unidad seleccionada y a la vez muestra archivos.
Luis Dueñas Pag 82
La Biblia de Visual Basic .NET
Demo 05
Crear una aplicación Windows Forms en Visual Basic llamada: Demo05.
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmExploradorArchivos
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 400, 400
StartPosition CenterScreen
Text Explorador de Archivos
Label1 Name lblUnidad
AutoSize True
Location 12,27
Text Selecciona una Unidad:
ComboBox1 Name cboUnidad
Location 151, 19
Size 231, 21
Label2 Name lblDirectorio
AutoSize True
Location 12,57
Text Lista de Directorios:
ListBox1 Name lstDirectorio
Location 15, 73
Size 367, 95
Label3 Name lblArchivo
AutoSize True
Location 12,182
Text Lista de Archivos:
CheckBox1 Name chkIncluirSubdirectorios
AutoSize True
Location 263, 178
Text Incluir Subdirectorios
ListBox2 Name lstArchivo
Location 15, 198
Size 367, 160
Luis Dueñas Pag 83
La Biblia de Visual Basic .NET
El diseño del formulario debe quedar similar al gráfico 2.11:
Gráfico 2.11: Diseño del formulario Explorador de Archivos
Ingresar al editor de código y escribir el siguiente código.
Imports [Link]
Public Class frmExploradorArchivos
Private Sub ListarUnidades(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim Unidades() As DriveInfo = [Link]()
Dim Unidad As DriveInfo
[Link]()
For Each Unidad In Unidades
[Link]([Link])
Next
End Sub
Private Sub ListarDirectorios(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Luis Dueñas Pag 84
La Biblia de Visual Basic .NET
Try
Dim Directorios As IEnumerable = _
[Link]([Link])
Dim bs As New BindingSource
[Link] = Directorios
[Link] = bs
Catch ex As Exception
[Link]([Link])
End Try
End Sub
Private Sub ListarArchivos(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Try
Dim N As Integer = If([Link], 1, 0)
Dim Archivos As IEnumerable = _
[Link]([Link], "*.*", N)
Dim bs As New BindingSource
[Link] = Nothing
[Link] = Archivos
[Link] = bs
Catch ex As Exception
[Link]([Link])
End Try
End Sub
Private Sub MostrarArchivosSubdirectorios(ByVal sender As [Link],
ByVal e As [Link]) Handles _
[Link]
ListarArchivos(Nothing, Nothing)
End Sub
End Class
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 85
La Biblia de Visual Basic .NET
Gráfico 2.12: Ejecución del formulario Explorador de Archivos
Luis Dueñas Pag 86
La Biblia de Visual Basic .NET
2.2. Leer y Escribir en un Archivo
Para leer y escribir archivos en .NET existen muchas formas, por ejemplo
para leer secuencialmente archivos de texto podemos usar la clase
StreamReader y para escribir se usa la clase StreamWriter. Si deseamos
leer y escribir archivos binarios entonces debemos usar BinaryReader y
BinaryWriter.
La clase FileStream es la clase principal con la cual podemos especificar el
modo de trabajo con el archivo: lectura, escritura, adición; el tipo de
acceso: lectura o escritura y si estará compartido para leer o escribir. Esta
debe usarse en conjunto con las otras clases mencionadas.
En el siguiente ejemplo crearemos una aplicación Chat en la cual si el
archivo que guarda los mensajes esta compartido en un directorio de red,
entonces todos los usuarios podrían ver mensajes de los demás, ya que el
archivo estará disponible para todos.
Demo 06
Crear una aplicación Windows Forms en Visual Basic llamada: Demo06.
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmChat
AcceptButton btnEnviar
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 400, 400
StartPosition CenterScreen
Text NET Chat V1.0
Label1 Name lblUsuario
AutoSize True
Location 24,23
Text Usuario:
TextBox1 Name txtUsuario
Location 86,16
Luis Dueñas Pag 87
La Biblia de Visual Basic .NET
Size 276,20
Label2 Name lblMensaje
AutoSize True
Location 24,60
Text Mensaje:
TextBox2 Name txtMensaje
Location 86,53
Size 276,20
Button1 Name btnEnviar
Cursor Hand
Location 159,79
Size 75,23
Text Enviar
TextBox3 Name txtPanel
Location 12,106
Multiline True
ScrollBars Vertical
Size 370,257
El diseño del formulario debe quedar similar al gráfico 2.13:
Gráfico 2.13: Diseño del formulario Chat
Luis Dueñas Pag 88
La Biblia de Visual Basic .NET
Ingresar al editor de código y escribir el siguiente código.
Imports [Link]
Public Class frmChat
Private Archivo As String = "[Link]"
Private WithEvents tmrRefrescar As New Timer
Private Sub MostrarMensajes()
If [Link](Archivo) Then
Using fs As New FileStream(Archivo, [Link], [Link],
[Link])
Using sr As New StreamReader(fs)
[Link] = [Link]
End Using
End Using
End If
[Link] = [Link]
[Link]()
End Sub
Private Sub EnviarMensaje(ByVal sender As [Link], ByVal e As _
[Link]) Handles [Link]
Using fs As New FileStream(Archivo, [Link], [Link],
[Link])
Using sw As New StreamWriter(fs)
[Link]("Fecha y Hora: {0}", [Link])
[Link]("Usuario: {0}", [Link])
[Link]("Dice: {0}", [Link])
[Link](New String("_", 50))
End Using
End Using
MostrarMensajes()
End Sub
Private Sub IniciarTimer(ByVal sender As [Link], ByVal e As
[Link]) Handles [Link]
[Link] = [Link]
[Link] = 5000
[Link] = True
[Link]()
Luis Dueñas Pag 89
La Biblia de Visual Basic .NET
End Sub
Private Sub tmrRefrescar_Tick(ByVal sender As Object, ByVal e As
[Link]) Handles [Link]
MostrarMensajes()
End Sub
End Class
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 2.14: Ejecución del formulario Chat
Luis Dueñas Pag 90
La Biblia de Visual Basic .NET
2.3. Dividir y Unir Archivos
En muchas ocasiones se necesita partir un archivo muy grande en varios
archivos más pequeños por ejemplo para enviarlos por mail y en caso
contrario al recibir los archivos separados debemos unirlos en uno solo.
Para dividir el archivo necesitamos averiguar su tamaño usando la
propiedad Length de la clase FileInfo, luego calculamos la cantidad de
partes en que se va a dividir e iniciamos la lectura del archivo escribiéndolo
en un directorio con el nombre del archivo los diferentes archivos obtenidos
usando para ambos casos la clase FileStream.
Finalmente, para unir todos los archivos del directorio se debe crear un
flujo de escritura e ir leyendo todos los archivos y escribirlos en dicho flujo
también con la clase FileStream.
Además en este ejemplo se hace uso de la clase Path para devolver el
nombre del directorio: GetDirectoryName, el nombre del archivo con y sin
extensión: GetFileName y GetFileNameWithoutExtension.
Demo 07
Crear una aplicación Windows Forms en Visual Basic llamada: Demo07.
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmDivideUne
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 300, 300
StartPosition CenterScreen
Text Ultitario que divide y une archiv.
GroupBox1 Name grpDividir
Location 12,12
Size 268,124
Text Dividir Archivos
Label1 Name lblArchivo
Luis Dueñas Pag 91
La Biblia de Visual Basic .NET
AutoSize True
Location 6,22
Text Selecciona el Archivo a Dividir
TextBox1 Name txtArchivo
Location 6,38
Size 236,20
Button1 Name btnAbrir
Cursor Hand
Location 242,38
Size 21,23
Text …
Label2 Name lblTamaño
AutoSize True
Location 6,77
Text Tamaño del Bloque
TextBox3 Name txtTamaño
Location 9,93
Size 59,20
Label3 Name lblKB
AutoSize True
Location 74,96
Text KB
Button2 Name btnDividir
Cursor Hand
Enabled False
Location 158,93
Size 75,23
Text Dividir
GroupBox2 Name grpUnir
Location 12,151
Size 268, 101
Text Unir Archivos
Label4 Name lblDirectorio
AutoSize True
Location 6,22
Text Selecciona el Directorio a Unir
Archivos
TextBox4 Name txtDirectorio
Location 6,38
Size 236,20
Button3 Name btnDirectorio
Cursor Hand
Luis Dueñas Pag 92
La Biblia de Visual Basic .NET
Location 242,38
Size 21,23
Text …
Button4 Name btnUnir
Cursor Hand
Enabled False
Location 82,64
Size 75,23
Text Unir
El diseño del formulario debe quedar similar al gráfico 2.15:
Gráfico 2.15: Diseño del formulario que divide y une archivos
Ingresar al editor de código y escribir el siguiente código.
Imports [Link] 'FileInfo, File, Path
Public Class frmDivideUne
Private Sub MostrarDialogoAbrir(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim ofd As New OpenFileDialog
With ofd
.Title = "Selecciona el Archivo a dividir"
.Filter = "Todos los archivos|*.*"
If .ShowDialog = [Link] Then
Luis Dueñas Pag 93
La Biblia de Visual Basic .NET
[Link] = .FileName
End If
End With
End Sub
Private Sub ValidarDigitos(ByVal sender As Object, _
ByVal e As [Link]) _
Handles txtTamañ[Link]
[Link] = Not ([Link]([Link]) Or [Link] = _
[Link])
End Sub
Private Sub HabilitarBotonDividir(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link], _
txtTamañ[Link]
[Link] = ([Link] <> "" AndAlso _
txtTamañ[Link] <> "")
End Sub
Private Sub DividirArchivo(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim fi As New FileInfo([Link])
Dim TT As Long = [Link]
Dim TB As Long = [Link](txtTamañ[Link]) * 1024
If TT > TB Then
Dim NB As Byte = TT \ TB
Dim TUB As Long = TT Mod TB
Dim I, J As Integer
Dim Carpeta As String = _
[Link]([Link])
Dim Ruta As String = [Link]([Link])
Dim Directorio As String = Ruta & "\" & Carpeta
[Link](Directorio)
Dim Archivo As String = Directorio & "\" & _
[Link]([Link])
Dim Buffer(TB) As Byte
Using fsR As New FileStream([Link], [Link], _
[Link], [Link])
For I = 0 To NB - 1
Using fsW As New FileStream(Directorio & "\" & _
Luis Dueñas Pag 94
La Biblia de Visual Basic .NET
[Link](Archivo) & _
[Link](3, "0"), [Link], [Link], _
[Link])
For J = 0 To TB - 1
[Link]([Link])
Next
End Using
Next
If TUB <> 0 Then
Using fsW As New FileStream(Directorio & "\" & _
[Link](Archivo) & _
[Link](3, "0"), [Link], [Link], _
[Link])
For J = 0 To TUB - 1
[Link]([Link])
Next
End Using
End If
End Using
[Link]("Archivos fueron divididos", "Aviso", _
[Link], [Link])
Else
[Link]("Tamaño del Bloque es mayor al Archivo", "Aviso",
[Link], [Link])
End If
End Sub
Private Sub SeleccionarDirectorio(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim fbd As New FolderBrowserDialog
[Link] = "C:\Lduenas\NET\LibroVB2010\"
If [Link] = [Link] Then
[Link] = [Link]
End If
End Sub
Private Sub HabilitarBotonUnir(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link] = [Link] <> ""
End Sub
Luis Dueñas Pag 95
La Biblia de Visual Basic .NET
Private Sub UnirArchivos(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim Directorio As String = [Link]
Dim Archivos() As String = [Link](Directorio)
Dim fi As FileInfo
Dim Archivo As String = [Link](Directorio) & "\" & _
[Link](Directorio) & ".txt"
Using fsW As New FileStream(Archivo, [Link], [Link],
[Link])
Dim I As Integer
For I = 0 To [Link] - 1
Using fsR As New FileStream(Archivos(I), [Link], _
[Link], [Link])
fi = New FileInfo(Archivos(I))
Dim Buffer([Link] - 1) As Byte
[Link](Buffer, 0, [Link])
[Link](Buffer, 0, [Link])
End Using
Next
End Using
[Link]("Archivos fueron unidos", "Aviso", _
[Link], [Link])
End Sub
End Class
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 96
La Biblia de Visual Basic .NET
Gráfico 2.16: Ejecución del formulario que divide y une
archivos
Luis Dueñas Pag 97
La Biblia de Visual Basic .NET
2.4. Comprimir y Descomprimir un Archivo
En ocasiones necesitamos comprimir y descomprimir archivos, .NET
Framework tiene el espacio de nombres [Link] en el cual
se encuentran 2 clases que permiten implementar esta funcionalidad:
DeflateStream y GZipStream.
La clase DeflateStream implementa el algoritmo de compresión y
descompresión de archivos sin pérdidas que es una combinación de 2
algoritmos: LZ77 Y Huffman, mientras que la clase GZipStream implementa
el algoritmo gzip que realiza una comprobación para detectar daños en los
datos. Este último algoritmo es mas popular que el primero siendo usado
por algunos utilitarios de compresión como WinZip y WinRar.
La programación o el uso de ambas clases es similar en .NET, para
comprimir un archivo debemos leer el archivo en una secuencia de bytes
(Buffer) y luego escribir la secuencia comprimida usando el método Write
de la clase DeflateStream o GZipStream en un flujo de salida o archivo
destino.
Para descomprimir debemos ir descomprimiendo por bloques y grabando
cada bloque descomprimido en un archivo de salida hasta que no se logre
leer nada en el archivo de origen o comprimido.
A continuación presentamos un ejemplo que permite comprimir y
descomprimir un archivo usando la clase DeflateStream.
Demo 08
Crear una aplicación Windows Forms en Visual Basic llamada: Demo08.
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmCompresion
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 300,150
Luis Dueñas Pag 98
La Biblia de Visual Basic .NET
StartPosition CenterScreen
Text Comprimir y Descomprimir
Archivo
Label1 Name lblArchivo
AutoSize True
Location 19, 20
Text Seleccione el Archivo a Procesar
TextBox1 Name txtArchivo
Location 22,36
Size 231,20
Button1 Name btnAbrir
Cursor Hand
Location 253,34
Size 23,23
Text …
Button2 Name btnComprimir
Cursor Hand
Location 22,73
Size 75,23
Text Comprimir
Button3 Name btnDescomprimir
Cursor Hand
Location 192,73
Size 88,23
Text Descomprimir
El diseño del formulario debe quedar similar al gráfico 2.17:
Gráfico 2.17: Diseño del formulario que comprime un archivo
Ingresar al editor de código y escribir el siguiente código.
Imports [Link] 'File, FileStream
Imports [Link] 'DeflateStream
Luis Dueñas Pag 99
La Biblia de Visual Basic .NET
Public Class frmCompresion
Private Sub MostrarDialogoAbrir(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim ofd As New OpenFileDialog
[Link] = "Selecciona el archivo a procesar"
[Link] = "Todos los archivos|*.*"
If [Link] = [Link] Then
[Link] = [Link]
End If
End Sub
Private Sub ComprimirArchivo(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim Buffer() As Byte = [Link]([Link])
Dim Archivo As String = [Link]("{0}.cmp", [Link])
Using fsDestino As New FileStream(Archivo, [Link], _
[Link], [Link])
Using ds As New DeflateStream(fsDestino, _
[Link])
[Link](Buffer, 0, [Link])
End Using
End Using
[Link]("Archivo fue comprimido")
End Sub
Private Sub DescomprimirArchivo(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim Buffer(100) As Byte
Dim Archivo As String = [Link]([Link]
- [Link]([Link]).Length)
Using fsOrigen As New FileStream([Link], [Link], _
[Link], [Link])
Using fsDestino As New FileStream(Archivo, [Link], _
[Link], [Link])
Using ds As New DeflateStream(fsOrigen, _
[Link])
Dim BytesDescomprimidos As Integer
Do While True
BytesDescomprimidos = [Link](Buffer, 0, [Link])
Luis Dueñas Pag 100
La Biblia de Visual Basic .NET
If BytesDescomprimidos > 0 Then
[Link](Buffer, 0, BytesDescomprimidos)
Else
Exit Do
End If
Loop
End Using
End Using
End Using
[Link]("Archivo fue descomprimido")
End Sub
End Class
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 2.18: Ejecución del formulario que comprime archivo
Luis Dueñas Pag 101
La Biblia de Visual Basic .NET
3. Programación Orientada a Objetos (POO)
En este tema veremos cómo programar usando objetos en Visual Basic
.NET, primero revisaremos los conceptos básicos de la Programación
Orientada a Objetos (POO) y el Modelo de Desarrollo Distribuido (MDD),
luego veremos la diferencia de cómo es una aplicación tradicional sin POO
ni MDD y luego implementaremos POO y MDD mediante la creación de
Librerías de Clases especializadas en servicios para usarlas en una
aplicación.
3.1 Introducción a la POO y MDD
Según el MSDN: Un objeto es una combinación de código y datos que
puede tratarse como una unidad. Un objeto puede ser una porción de una
aplicación, como un control o un formulario. Una aplicación entera también
puede ser un objeto.
Cuando se crea una aplicación en Visual Basic, se trabaja constantemente
con objetos. Se pueden usar los objetos proporcionados por Visual Basic,
como controles, formularios y objetos de acceso a datos. También se
pueden usar los objetos de otras aplicaciones en la aplicación de Visual
Basic. Incluso pueden crearse objetos propios y agregarles propiedades y
métodos adicionales. Los objetos actúan como bloques de creación
prefabricados para programas: permiten escribir una porción de código y
utilizarla una y otra vez. Para más información ver referencia 14 al final del
libro.
Capas o Servicio Lógicos
En toda aplicación siempre existen servicios lógicos los cuales podemos
clasificarlos en:
1. Servicios de Usuario
1.1. Interface de Usuario (IU): CUI (Interface de Usuario Carácter) y GUI
(Interface de Usuario Grafica)
Luis Dueñas Pag 102
La Biblia de Visual Basic .NET
- Aplicación Windows
- Aplicación Web
- Librería de Controles Windows
- Librería de Controles Web
- Librería de Formularios Windows
1.2. Procesamiento de la Interface de Usuario
- Librería de Código de Usuario General
- Librería de Código de Windows
- Librería de Código de Web
2. Servicios del Negocio o Empresariales
2.1. Entidades del Negocio
- Librería de Entidades del Negocio
2.2. Reglas del Negocio
- Librería de Reglas del Negocio
3. Servicios de Datos
3.1. Acceso a Datos
- Librería Acceso a Datos General:
Ej: ADO NET, SQLHelper, OracleHelper, EntLib, MyBatis, NHibernate
- Librería de Acceso a Datos Ap:
Ej: Base de Datos del Negocio
3.2. Agentes de Servicios
- Librería de Agentes de Servicio
Luis Dueñas Pag 103
La Biblia de Visual Basic .NET
Ej: Otras Bases de Datos, ActiveDirectory, Mails, Web Services, etc.
Tradicionalmente todos estos servicios se han escrito en la misma
aplicación, pero si separamos el código en capas se le conoce como
Modelo de Desarrollo Distribuido (MDD) y es muy útil para reusar
código y crear aplicaciones empresariales escalables y mantenibles.
A continuación vamos a crear una Aplicación Windows que calcule el área
de un triangulo en función a sus lados usando el Modelo de Programación
Tradicional y luego en los siguientes temas veremos cómo distribuirla en
capas.
Demo 09
Crear una aplicación Windows Forms en Visual Basic llamada: Demo09.
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmTriangulo
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 300,280
StartPosition CenterScreen
Text Calculo del Area del Triángulo
Label1 Name lblLado1
AutoSize True
Location 26, 35
Text Lado 1:
TextBox1 Name txtLado1
Location 108,28
Size 43,20
Label2 Name lblLado2
AutoSize True
Location 26, 73
Text Lado 2:
TextBox2 Name txtLado2
Location 108,66
Size 43,20
Luis Dueñas Pag 104
La Biblia de Visual Basic .NET
Label3 Name lblLado3
AutoSize True
Location 26, 109
Text Lado 3:
TextBox3 Name txtLado3
Location 108,102
Size 43,20
Label4 Name lblSemiperimetro
AutoSize True
Location 26, 147
Text Semiperimetro:
TextBox4 Name txtSemiperimetro
Location 108,140
ReadOnly True
Size 43,20
Label5 Name lblArea
AutoSize True
Location 26, 187
Text Area:
TextBox5 Name txtArea
Location 108,180
ReadOnly True
Size 43,20
PictureBox1 Name picTriangulo
BorderStyte Fixed3D
Image [Link]
Location 171,26
Size 98,95
SizeMode StretchImage
Button1 Name btnCalcular
Cursor Hand
Location 183,137
Size 75,23
Text Calcular
Button2 Name btnNuevo
Cursor Hand
Location 183,177
Size 75,23
Text Nuevo
El diseño del formulario debe quedar similar al gráfico 2.19:
Luis Dueñas Pag 105
La Biblia de Visual Basic .NET
Gráfico 2.19: Diseño del formulario que calcula el área del
triángulo
Ingresar al editor de código y escribir el siguiente código.
Imports [Link] 'FileStream, StreamWriter
Public Class frmTriangulo
Private Sub CalculaArea(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If [Link] <> "" AndAlso [Link] <> "" AndAlso _
[Link] <> "" Then
Dim Lado1 As Integer = [Link]([Link])
Dim Lado2 As Integer = [Link]([Link])
Dim Lado3 As Integer = [Link]([Link])
If Lado1 + Lado2 >= Lado3 AndAlso Lado2 + Lado3 >= Lado1 _
AndAlso Lado1 + Lado3 >= Lado2 Then
Dim SP As Decimal = (Lado1 + Lado2 + Lado3) / 2
Dim Area As Decimal = [Link](SP * (SP - Lado1) * _
(SP - Lado2) * (SP - Lado3))
[Link] = [Link]
[Link] = [Link]
Using fs As New FileStream("[Link]", [Link], _
[Link], [Link])
Using sw As New StreamWriter(fs)
[Link]("{0},{1},{2},{3},{4}", Lado1, Lado2, Lado3, _
SP, Area)
Luis Dueñas Pag 106
La Biblia de Visual Basic .NET
End Using
End Using
Else
[Link]("Los Lados No forman un Triangulo")
End If
Else
[Link]("Falta ingresar un Lado")
End If
End Sub
Private Sub LimpiarDatos(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link]()
[Link]()
[Link]()
[Link]()
[Link]()
[Link]()
End Sub
End Class
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 2.20: Ejecución del formulario que calcula el área del
triángulo
Luis Dueñas Pag 107
La Biblia de Visual Basic .NET
3.2. Creando Bibliotecas de Clases
A continuación vamos a crear varias bibliotecas de clases para distribuir el
código en capas o niveles lógicos, de la siguiente forma: el Demo 10 tendrá
la Librería de Código de Usuario para Windows, el Demo 11 la Librería de
Entidad del Negocio, el Demo12 la Librería de Acceso a Datos y el Demo13
la Librería de Reglas del Negocio.
Creando la Librería de Código de Usuario
Demo 10
Del menú “File”, seleccionar “New Project” y luego “Class Library”.
Escribir como nombre físico al proyecto: Demo10.
Cambiar de nombre a la clase de [Link] a [Link].
Del menú “Project” seleccionar “Add References” y luego “System.
[Link]”.
Escribir el siguiente código:
Imports [Link] 'Control, MessageBox
Namespace LibUserCodeWinForms
Public Class ucFormulario
Public Shared Sub LimpiarControles(ByVal contenedor As Object)
Dim X As Control
For Each X In [Link]
If TypeOf X Is TextBox Then CType(X, TextBox).Clear()
If TypeOf X Is CheckBox Then _
CType(X, CheckBox).Checked = False
If TypeOf X Is RadioButton Then _
CType(X, RadioButton).Checked = False
If TypeOf X Is ComboBox Then _
CType(X, ComboBox).SelectedIndex = 0
If TypeOf X Is ListBox Then CType(X, ListBox).SelectedIndex = 0
If TypeOf X Is DateTimePicker Then _
Luis Dueñas Pag 108
La Biblia de Visual Basic .NET
CType(X, DateTimePicker).Value = Now
Next
End Sub
Public Shared Sub MostrarMensaje(ByVal Mensaje As String, _
ByVal txt As TextBox)
Mensaje = [Link]("Ingresa {0}", Mensaje)
[Link](Mensaje, "Aviso", [Link], _
[Link])
[Link]()
End Sub
End Class
End Namespace
Del menú “Project” seleccionar “Demo10 Properties”, luego borrar
Demo10 del “Root namespace”.
Nota: Por defecto el espacio de nombres (Namespace) de todo
ensamblado (Assembly) es el nombre del proyecto, por ejemplo Demo10,
pero si por código se crea un Namespace entonces este se agrega al inicial,
es por eso que eliminamos el inicial para definir uno.
Del menú “Build” seleccionar “Build Demo10”.
Nota: Una librería o biblioteca de clases No se puede ejecutar con F5, lo
que debemos hacer es compilarla (se creará un archivo con extensión dll).
Luis Dueñas Pag 109
La Biblia de Visual Basic .NET
Creando la Librería de Entidades del Negocio
Demo 11
Del menú “File”, seleccionar “New Project” y luego “Class Library”.
Escribir como nombre físico al proyecto: Demo11.
Cambiar de nombre a la clase de [Link] a [Link].
Escribir el siguiente código:
Namespace LibBusinessEntity
Public Class beTriangulo
Private _Lado1 As Integer
Private _Lado2 As Integer
Private _Lado3 As Integer
Private _SemiPerimetro As Decimal
Private _Area As Decimal
Public Property Lado1() As Integer
Get
Return (_Lado1)
End Get
Set(ByVal value As Integer)
_Lado1 = value
End Set
End Property
Public Property Lado2() As Integer
Get
Return (_Lado2)
End Get
Set(ByVal value As Integer)
_Lado2 = value
End Set
End Property
Public Property Lado3() As Integer
Get
Luis Dueñas Pag 110
La Biblia de Visual Basic .NET
Return (_Lado3)
End Get
Set(ByVal value As Integer)
_Lado3 = value
End Set
End Property
Public Property SemiPerimetro() As Decimal
Get
Return (_SemiPerimetro)
End Get
Set(ByVal value As Decimal)
_SemiPerimetro = value
End Set
End Property
Public Property Area() As Decimal
Get
Return (_Area)
End Get
Set(ByVal value As Decimal)
_Area = value
End Set
End Property
End Class
End Namespace
Del menú “Project” seleccionar “Demo11 Properties”, luego borrar
Demo11 del “Root namespace”.
Del menú “Build” seleccionar “Build Demo11” y crear la dll.
Luis Dueñas Pag 111
La Biblia de Visual Basic .NET
Creando la Librería de Acceso a Datos
Demo 12
Del menú “File”, seleccionar “New Project” y luego “Class Library”.
Escribir como nombre físico al proyecto: Demo12.
Hacer una referencia a la librería de entidad de negocio creada en el
Demo 11: menú “Project”, “Add References”, ficha “Browse” y
seleccionar el archivo [Link].
Nota: El archivo dll se encuentra en la carpeta del proyecto dentro de la
carpeta Release que se encuentra dentro de la carpeta Bin.
Cambiar de nombre a la clase de [Link] a [Link].
Escribir el siguiente código:
Imports LibBusinessEntity 'beTriangulo
Imports [Link] 'FileStream, StreamWriter
Namespace LibDataAccess
Public Class daTriangulo
Public Sub GrabarArchivo(ByVal obeTriangulo As beTriangulo, _
ByVal Archivo As String)
Using fs As New FileStream(Archivo, [Link], _
[Link], [Link])
Using sw As New StreamWriter(fs)
[Link]("{0},{1},{2},{3},{4}", obeTriangulo.Lado1, _
obeTriangulo.Lado2, obeTriangulo.Lado3, _
[Link], [Link])
End Using
End Using
End Sub
End Class
End Namespace
Luis Dueñas Pag 112
La Biblia de Visual Basic .NET
Del menú “Project” seleccionar “Demo12 Properties”, luego borrar
Demo12 del “Root namespace”.
Del menú “Build” seleccionar “Build Demo12” y crear la dll.
Creando la Librería de Reglas del Negocio
Demo 13
Del menú “File”, seleccionar “New Project” y luego “Class Library”.
Escribir como nombre físico al proyecto: Demo13.
Hacer una referencia a la librería de entidad de negocio creada en el
Demo 11: menú “Project”, “Add References”, ficha “Browse” y
seleccionar el archivo [Link].
También hacer referencia a la librería de acceso a datos creada en el
Demo 12: menú “Project”, “Add References”, ficha “Browse” y
seleccionar el archivo [Link].
Cambiar de nombre a la clase de [Link] a [Link].
Escribir el siguiente código:
Imports LibBusinessEntity
Imports LibDataAccess
Namespace LibBusinessRules
Public Class brTriangulo
Public Function EsTriangulo(ByVal obeTriangulo As beTriangulo) _
As Boolean
Dim exito As Boolean = obeTriangulo.Lado1 + _
obeTriangulo.Lado2 >= obeTriangulo.Lado3 _
AndAlso obeTriangulo.Lado2 + obeTriangulo.Lado3 >=
obeTriangulo.Lado1 AndAlso obeTriangulo.Lado1 +
obeTriangulo.Lado3 >= obeTriangulo.Lado2
Return (exito)
End Function
Luis Dueñas Pag 113
La Biblia de Visual Basic .NET
Public Function CalcularSemiPerimetro(ByVal obeTriangulo As
beTriangulo) As Decimal
Dim SP As Decimal = (obeTriangulo.Lado1 + obeTriangulo.Lado2 + _
obeTriangulo.Lado3) / 2
Return (SP)
End Function
Public Function CalcularArea(ByVal obeTriangulo As beTriangulo) _
As Decimal
Dim Area As Decimal = [Link]([Link] * _
([Link] - obeTriangulo.Lado1) * _
([Link] - obeTriangulo.Lado2) * _
([Link] - obeTriangulo.Lado3))
Return (Area)
End Function
Public Sub GrabarArchivo(ByVal obeTriangulo As beTriangulo, _
ByVal Archivo As String)
Dim odaTriangulo As New daTriangulo
[Link](obeTriangulo, Archivo)
End Sub
End Class
End Namespace
Del menú “Project” seleccionar “Demo13 Properties”, luego borrar
Demo13 del “Root namespace”.
Del menú “Build” seleccionar “Build Demo13” y crear la dll.
Luis Dueñas Pag 114
La Biblia de Visual Basic .NET
3.3. Creando una Aplicación que use las Bibliotecas de
Clases
Finalmente, crearemos la aplicación que use las librerías creadas
anteriormente, esta tiene que referenciar solo a las librerías de usuarios y
las de negocios pero no puede directamente trabajar con la librería de
datos, ya que está se encapsulo a través de la librería de reglas de
negocio.
Demo 14
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Escribir como nombre físico al proyecto: Demo14.
Hacer una referencia a la librería de código de usuario para Windows
creada en el Demo 10: menú “Project”, “Add References”, ficha
“Browse” y seleccionar el archivo [Link].
También hacer referencia a la librería de entidades de negocio creada
en el Demo 11: menú “Project”, “Add References”, ficha “Browse” y
seleccionar el archivo [Link].
También hacer referencia a la librería de reglas de negocio creada en el
Demo 13: menú “Project”, “Add References”, ficha “Browse” y
seleccionar el archivo [Link].
Eliminar el formulario Form1 dando clic derecho y seleccionar “Delete”.
Agregar el formulario creado en el Demo09, clic derecho al proyecto,
menú “Add”, “Existing Item”, seleccionar “[Link]”
Borrar el código existente y escribir lo siguiente:
Imports LibBusinessEntity
Imports LibBusinessRules
Imports LibUserCodeWinForms
Public Class frmTriangulo
Luis Dueñas Pag 115
La Biblia de Visual Basic .NET
Private Sub CalculaArea(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If [Link] <> "" Then
If [Link] <> "" Then
If [Link] <> "" Then
Dim obeTriangulo As New beTriangulo
With obeTriangulo
.Lado1 = [Link]([Link])
.Lado2 = [Link]([Link])
.Lado3 = [Link]([Link])
End With
Dim obrTriangulo As New brTriangulo
With obrTriangulo
If .EsTriangulo(obeTriangulo) Then
[Link] = _
.CalcularSemiPerimetro(obeTriangulo)
[Link] = .CalcularArea(obeTriangulo)
[Link] = _
[Link]
[Link] = [Link]
.GrabarArchivo(obeTriangulo, "[Link]")
Else
[Link]("Los Lados No forman un Triangulo")
End If
End With
Else
[Link]("Lado 3", txtLado1)
End If
Else
[Link]("Lado 2", txtLado1)
End If
Else
[Link]("Lado 1", txtLado1)
End If
End Sub
Private Sub LimpiarDatos(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link](Me)
[Link]()
Luis Dueñas Pag 116
La Biblia de Visual Basic .NET
End Sub
End Class
Configurar el formulario de inicio de la aplicación, clic derecho al
proyecto, seleccionar “Properties”, luego ficha “Application”, en la
sección “Startup Form” cambiar Form1 por frmTriangulo y cerrar la
ventana.
Grabar y ejecutar la aplicación.
Nota: La ventana que se mostrará será la misma de la figura 2.20.
Luis Dueñas Pag 117
La Biblia de Visual Basic .NET
4. Programación Asíncrona y Paralelismo
Cuando ejecutamos varias tareas en una aplicación estas se ejecutan en
forma secuencial o síncrona, teniendo la desventaja que si la tarea demora
demasiado la aplicación cliente queda colgada hasta que se termine de
procesar dicha tarea.
Para resolver este problema existen técnicas de programación asíncrona
que nos permiten ejecutar tareas en simultaneo sin que la aplicación se
detenga o se pause, por ejemplo al mostrar gran cantidad de líneas de
texto de un archivo o al leer y mostrar miles de registros de una base de
datos.
En .NET Framework existen varias técnicas para implementar programación
asíncrona, tales como:
Métodos asíncronos mediante IAsyncResult
Programación asíncrona mediante Delegados
Programación asíncrona mediante el Modelo Basado en Eventos
Programación paralela
Para ver más información sobre este tema consultar la referencia 15 al final
del libro.
.NET tiene muchas clases que permiten implementar las diferentes técnicas
de programación asíncrona mencionadas, entre las cuales tenemos:
Thread, ThreadPool, Delegate, Tasks, etc. La mayoría se encuentran en el
espacio de nombres [Link].
4.1 Threads
La clase Thread se usa para manejar subtareas y puede ser útil para iniciar
una subtarea en segundo plano e ir mostrando progresivamente los
resultados, por ejemplo leer un archivo de texto e ir mostrando sus líneas
en una Lista.
Luis Dueñas Pag 118
La Biblia de Visual Basic .NET
Esta clase tiene métodos como Start que inician la ejecución de un
subproceso, luego podemos pausar usando el método Suspend y reanudar
este usando el método Resume, si deseamos cancelar el subproceso
iniciado usaremos el método Abort.
A continuación veremos diferentes ejemplos del uso de la clase Thread, el
primero de ellos el Demo 15 usa un solo Thread, el Demo 16 usa 2
Threads dependientes y el Demo17 usa un grupo de Thread o ThreadPool.
Thread Simple
Demo 15
Crear una aplicación Windows Forms en Visual Basic llamada: Demo15.
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmLectorArchivo
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 400,400
StartPosition CenterScreen
Text Lectura Asíncrona de Archivos
de Texto
Label1 Name lblNombre
AutoSize True
Location 15, 21
Text Selecciona el Archivo de Texto a
Abrir
TextBox1 Name txtNombre
Location 13,37
ReadOnly True
Size 326,20
Button1 Name btnAbrir
Cursor Hand
Location 341,37
Luis Dueñas Pag 119
La Biblia de Visual Basic .NET
Size 31,23
Text …
ListBox1 Name lstArchivo
Location 13,63
Size 359,264
Button2 Name btnLeer
Cursor Hand
Location 13,333
Size 75,23
Text Leer
Button3 Name btnCancelar
Cursor Hand
Location 297,333
Size 75,23
Text Cancelar
El diseño del formulario debe quedar similar al gráfico 2.21:
Gráfico 2.21: Diseño del formulario que lee archivos
asíncronamente
Ingresar al editor de código y escribir el siguiente código.
Luis Dueñas Pag 120
La Biblia de Visual Basic .NET
Imports [Link] 'StreamReader
Imports [Link] 'StringBuilder, Encoding
Imports [Link] 'Thread
Public Class frmLectorArchivo
Private objHilo As Thread
Private Sub LeerArchivo()
[Link] = "Detener"
[Link] = True
Using sr As New StreamReader([Link], [Link])
Do While Not [Link]
[Link]([Link])
Loop
End Using 'Close y Dispose
[Link] = "Leer"
[Link] = False
End Sub
Private Sub MostrarDialogoAbrir(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim ofd As New OpenFileDialog 'Dialogo de Abrir de Windows
[Link] = "Selecciona el archivo a abrir"
[Link] = "Archivos de texto|*.txt"
If [Link]() = [Link] Then
[Link] = [Link]
[Link]()
End If
End Sub
Private Sub LeerArchivoPorLinea(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If [Link] = "Leer" Then
objHilo = New Thread(AddressOf LeerArchivo)
[Link]()
Else
If [Link] = "Detener" Then
[Link]()
[Link] = "Continuar"
[Link] = False
Luis Dueñas Pag 121
La Biblia de Visual Basic .NET
Else
[Link]()
[Link] = "Detener"
[Link] = True
End If
End If
End Sub
Private Sub ConfigurarSubproceso(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
CheckForIllegalCrossThreadCalls = False
End Sub
Private Sub CancelarSubproceso(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link]()
[Link] = False
[Link]()
[Link]()
[Link] = "Leer"
End Sub
Private Sub HabilitarBoton(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link] = ([Link] <> "")
End Sub
End Class
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 122
La Biblia de Visual Basic .NET
Gráfico 2.22: Ejecución del formulario que lee archivos
asíncronamente
Luis Dueñas Pag 123
La Biblia de Visual Basic .NET
Threads Dependientes
Demo 16
Crear una aplicación Windows Forms en Visual Basic llamada: Demo16.
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmLectorArchivo
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 400,400
StartPosition CenterScreen
Text Lectura Asíncrona de Archivos
de Texto
Label1 Name lblNombre
AutoSize True
Location 15, 21
Text Selecciona el Archivo de Texto a
Abrir
TextBox1 Name txtNombre
Location 13,37
ReadOnly True
Size 326,20
Button1 Name btnAbrir
Cursor Hand
Location 341,37
Size 31,23
Text …
ListBox1 Name lstArchivo
Location 13,63
Size 359,238
Button2 Name btnLeer
Cursor Hand
Location 13,333
Size 75,23
Text Leer
ProgressBar1 Name pbrArchivo
Luis Dueñas Pag 124
La Biblia de Visual Basic .NET
Dock Bottom
El diseño del formulario debe quedar similar al gráfico 2.23:
Gráfico 2.23: Diseño del formulario que lee archivos
asíncronamente con barra de progreso
Ingresar al editor de código y escribir el siguiente código.
Imports [Link] 'StreamReader
Imports [Link] 'StringBuilder, Encoding
Imports [Link] 'Thread
Public Class frmLectorArchivo
Private objHiloContar As Thread
Private objHiloLeer As Thread
Private CL As Long
Private Sub ContarLineasArchivo()
CL = 0
Using sr As New StreamReader([Link], _
[Link])
Luis Dueñas Pag 125
La Biblia de Visual Basic .NET
Do While Not [Link]
[Link]()
CL = CL + 1
Loop
End Using
End Sub
Private Sub LeerArchivo()
Dim B As Long = CL \ [Link]
Dim C As Long 'Contador
[Link] = False
Using sr As New StreamReader([Link], [Link])
Do While Not [Link]
[Link]([Link])
If C Mod B = 0 Then
If [Link] < [Link] Then
[Link] += 1
End If
End If
C=C+1
Loop
End Using 'Close y Dispose
[Link] = True
End Sub
Private Sub MostrarDialogoAbrir(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim ofd As New OpenFileDialog 'Dialogo de Abrir de Windows
[Link] = "Selecciona el archivo a abrir"
[Link] = "Archivos de texto|*.txt"
If [Link]() = [Link] Then
[Link] = [Link]
[Link]()
End If
End Sub
Private Sub LeerArchivoPorLinea(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
objHiloContar = New Thread(AddressOf ContarLineasArchivo)
[Link]()
Luis Dueñas Pag 126
La Biblia de Visual Basic .NET
[Link]()
objHiloLeer = New Thread(AddressOf LeerArchivo)
[Link]()
End Sub
Private Sub ConfigurarSubproceso(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
CheckForIllegalCrossThreadCalls = False
End Sub
Private Sub HabilitarBoton(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link] = ([Link] <> "")
End Sub
End Class
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 2.24: Ejecución del formulario que lee archivos
asíncronamente con barra de progreso
Luis Dueñas Pag 127
La Biblia de Visual Basic .NET
ThreadPool
Demo 17
Crear una aplicación Windows Forms en Visual Basic llamada: Demo17.
Cambiar de nombre al formulario de [Link] a frmContadorPalabras
.vb
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmContadorPalabras
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 400,400
StartPosition CenterScreen
Text Contador de Palabras Asíncrono
Label1 Name lblArchivo
AutoSize True
Location 11, 14
Text Selecciona un Archivo de Texto
TextBox1 Name txtArchivo
Location 12,30
ReadOnly True
Size 332,20
Button1 Name btnAbrir
Cursor Hand
Location 346,27
Size 25,23
Text …
ListBox1 Name lstArchivo
Location 12,56
Size 359,95
Label2 Name lblPalabra
AutoSize True
Location 12, 165
Text Palabra a Buscar:
TextBox2 Name txtPalabra
Location 109,162
Size 176,20
Luis Dueñas Pag 128
La Biblia de Visual Basic .NET
Button2 Name btnBuscar
Cursor Hand
Location 296,160
Size 75,23
Text Buscar
ListView1 Name lvwResultado
FullRowSelect True
GridLines True
HotTracking True
Location 12,189
Size 356,167
El diseño del formulario debe quedar similar al gráfico 2.25:
Gráfico 2.25: Diseño del formulario contador de palabras
asíncrono
Ingresar al editor de código y escribir el siguiente código.
Imports [Link] 'File, FileStream, StreamReader
Imports [Link] 'ThreadPool
Public Class frmContadorPalabras
Luis Dueñas Pag 129
La Biblia de Visual Basic .NET
Private Sub ContarPalabras(ByVal Archivo As String)
Dim CLP As Integer = 0
If [Link](Archivo) Then
Using fs As New FileStream(Archivo, [Link], _
[Link], [Link])
Using sr As New StreamReader(fs)
Do While Not [Link]
If [Link] _
([Link]) Then
CLP += 1
End If
Loop
End Using
End Using
Dim Fila As ListViewItem = [Link](Archivo)
[Link](CLP)
[Link]([Link])
End If
End Sub
Private Sub CrearColumnasListView(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
With [Link]
.Add("Archivo", 200, [Link])
.Add("Total", 60, [Link])
.Add("IdThread", 80, [Link])
End With
[Link] = [Link]
CheckForIllegalCrossThreadCalls = False
End Sub
Private Sub btnAbrir_Click(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim ofd As New OpenFileDialog 'Dialogo de Abrir
[Link] = "Seleccione archivo de texto a añadir"
[Link] = "Archivos de texto|*.txt"
If [Link] = [Link] Then
[Link] = [Link]
[Link]([Link])
[Link] = 0
Luis Dueñas Pag 130
La Biblia de Visual Basic .NET
End If
End Sub
Private Sub HabilitarBotonBuscar(ByVal sender As [Link], _
ByVal e As [Link]) Handles _
[Link], [Link]
[Link] = ([Link] > 0 AndAlso _
[Link] <> "")
End Sub
Private Sub Buscar(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim I As Integer
For I = 0 To [Link] - 1
[Link](AddressOf _
ContarPalabras, [Link](I))
Next
End Sub
End Class
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 131
La Biblia de Visual Basic .NET
Gráfico 2.26: Ejecución del formulario contador de palabras
asíncrono
Luis Dueñas Pag 132
La Biblia de Visual Basic .NET
4.2. Eventos Asíncronos
El modelo de programación asíncrono basado en eventos permite
implementar de manera simple el subprocesamiento y algunas clases de
.NET Framework tienen dicho soporte como los Servicios Web y los
Servicios WCF.
A continuación veremos 2 ejemplos: uno que es un Servicio WCF que
ejecuta una consulta de datos la cual tiene una pausa de 10 segundos para
demorar la consulta y el otro es una aplicación Windows que consume
dicho servicio pero en forma asíncrona usando el modelo de eventos.
Demo 18
Del menú “File”, seleccionar “New Web Site” y luego “WCF Service”.
Crear un Servicio WCF en Visual Basic llamado: Demo18.
Cambiar de nombre a la interface de [Link] a [Link]
Borrar el código mostrado y escribir el siguiente código:
Namespace ServicioWCF
<ServiceContract()> _
Public Interface IEmpleado
<OperationContract()> _
Function ListarEmpleados() As DataSet
End Interface
End Namespace
Cambiar de nombre a la clase de [Link] a [Link]
Borrar el código mostrado y escribir el siguiente código:
Imports [Link] 'DataSet
Imports [Link] 'SqlConnection, SqlDataAdapter
Namespace ServicioWCF
Public Class Empleado
Implements [Link]
Luis Dueñas Pag 133
La Biblia de Visual Basic .NET
Public Function ListarEmpleados() As DataSet _
Implements [Link]
Dim dst As New DataSet
Using con As New SqlConnection("uid=sa;pwd=123456; _
data source=Lduenas\MCTS;initial catalog=Northwind")
[Link]()
Dim dap As New SqlDataAdapter("WaitFor Delay '[Link]'; _
Select EmployeeID,LastName,FirstName From Employees", con)
[Link](dst, "Empleados")
End Using '[Link]
Return (dst)
End Function
End Class
End Namespace
Nota: La cadena de conexión debe ser modificada de acuerdo al usuario
(uid) y clave (pwd) de SQL que se hubiera creado, además cambiar el
nombre del servidor (data source).
Del menú “Project” seleccionar “Demo18 Properties”, luego borrar
Demo18 del “Root namespace”.
Clic derecho sobre el archivo [Link] y seleccionar “View
Markup”, cambiar el código a lo siguiente
<%@ ServiceHost Language="VB" Debug="true"
Service="[Link]" CodeBehind="[Link]" %>
Clic derecho sobre el archivo [Link] y seleccionar “View in
Browser”.
Luis Dueñas Pag 134
La Biblia de Visual Basic .NET
Gráfico 2.27: Ejecución del Servicio WCF de Empleado
Clic al enlace que contiene el archivo wsdl y copiar la dirección (URL).
Luis Dueñas Pag 135
La Biblia de Visual Basic .NET
Demo 19
Abrir otro Visual Studio para crear la aplicación de prueba.
Nota: No puede cerrar el otro proyecto del Servicio WCF ya que debe estar
ejecutándose para poder consumirlo desde la aplicación.
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo19.
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmListaEmpleado
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 400,300
StartPosition CenterScreen
Text Lista Empleados desde el
Servicio WCF
DataGridView1 Name dgvEmpleado
Dock Fill
ReadOnly True
SelectionMode FullRowSelect
El diseño del formulario debe quedar similar al gráfico 2.28:
Luis Dueñas Pag 136
La Biblia de Visual Basic .NET
Gráfico 2.28: Diseño del formulario que lista empleados desde
un Servicio WCF asíncrono
Hacer una referencia al Servicio WCF, clic derecho al proyecto Demo19
y seleccionando “Add Service Reference”.
En la ventana pegar la dirección del wsdl del Servicio WCF
anteriormente creado, similar a la figura mostrada.
Luis Dueñas Pag 137
La Biblia de Visual Basic .NET
Gráfico 2.29: Ventana de Adicionar Referencia a un Servicio
Escribir un espacio de nombres para el servicio, por ejemplo Servicio
WCF y clic en el botón “Advanced”, se mostrará una ventana similar al
gráfico 2.30.
En la ventana de configuración del servicio, activar la casilla “Generar
operaciones asíncronas”.
Luis Dueñas Pag 138
La Biblia de Visual Basic .NET
Gráfico 2.30: Ventana de Configurar la Referencia al Servicio
Escribir el siguiente código en el formulario:
Public Class frmListaEmpleado
Private dst As New DataSet
Private WithEvents oEmpleado As New [Link]
Private Sub IniciarLlamadaAsincrona(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
[Link]()
End Sub
Private Sub FinalizarLlamadaAsincrona(ByVal sender As Object, _
ByVal e As [Link]) Handles _
[Link]
dst = [Link]
Dim mi As New MethodInvoker(AddressOf MostrarResultados)
[Link](mi)
End Sub
Luis Dueñas Pag 139
La Biblia de Visual Basic .NET
Private Sub MostrarResultados()
[Link] = [Link](0)
End Sub
End Class
Grabar y ejecutar la aplicación.
Gráfico 2.31: Ejecución del formulario que lista empleados
desde un Servicio WCF asíncrono
Nota: Observar como aparece el formulario y se puede continuar
trabajando con él mientras se está ejecutando la llamada al Servicio WCF
hasta que pasado 10 segundos se lista los datos en la grilla.
Luis Dueñas Pag 140
La Biblia de Visual Basic .NET
4.3. Delegados CallBacks
La forma más sencilla de implementar la programación asíncrona es usar el
Modelo de Eventos, pero no todas las clases de .NET Framework soportan
este modelo de eventos, para esto la solución es implementar los
delegados CallBacks.
La mayoría de desarrolladores profesionales usan el Modelo de Desarrollo
Distribuido (MDD) y tienen escrito mucho código en Librerías .NET que son
usadas por aplicativos Windows, Web, WPF, etc. Si al llamar a un método
de una clase de una librería desde una aplicación, si esta llamada se
demora dejaría colgada a la aplicación.
Para resolver este problema debemos implementar los delegados CallBacks
que consisten en crear una función delegado con la misma firma que la del
método a llamar, luego creamos un objeto de tipo delegado que apunte al
método. Usaremos el método BeginInvoke de este objeto para iniciar la
llamada asíncrona y el método EndInvoke para finalizar la llamada desde el
procedimiento de regreso o CallBack.
A continuación crearemos un par de ejemplos para demostrar los
delegados CallBack, el Demo 20 que será una Librería de Datos con un
método que demore 10 segundos y luego liste los empleados desde una
base de datos y el Demo21 que es la aplicación que consume la librería en
forma asíncrona usando un delegado CallBack.
Luis Dueñas Pag 141
La Biblia de Visual Basic .NET
Demo 20
Del menú “File”, seleccionar “New Project” y luego “Class Library”.
Escribir como nombre físico al proyecto: Demo20.
Cambiar de nombre a la clase de [Link] a [Link].
Escribir el siguiente código:
Imports [Link] 'DataSet
Imports [Link] 'SqlConnection, SqlDataAdapter
Namespace LibreriaDatos
Public Class daEmpleado
Public Function ListarEmpleados() As DataSet
Dim dst As New DataSet
Using con As New SqlConnection("uid=sa;pwd=123456; _
data source=Lduenas\MCTS;initial catalog=Northwind")
[Link]()
Dim dap As New SqlDataAdapter("WaitFor Delay '[Link]'; _
Select EmployeeID,LastName,FirstName From Employees", con)
[Link](dst, "Empleados")
End Using '[Link]
Return (dst)
End Function
End Class
End Namespace
Del menú “Project” seleccionar “Demo20 Properties”, luego borrar
Demo20 del “Root namespace”.
Del menú “Build” seleccionar “Build Demo20” para crear la dll.
Luis Dueñas Pag 142
La Biblia de Visual Basic .NET
Demo 21
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo21.
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmListaEmpleado
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 400,300
StartPosition CenterScreen
Text Lista Empleados desde la
Librería de Datos
DataGridView1 Name dgvEmpleado
Dock Fill
ReadOnly True
SelectionMode FullRowSelect
El diseño del formulario debe quedar similar al gráfico 2.32:
Luis Dueñas Pag 143
La Biblia de Visual Basic .NET
Gráfico 2.32: Diseño del formulario que lista empleados desde
la librería de datos asíncrona
Hacer una referencia a la librería de clases creada anteriormente, del
menú “Project”, seleccionar “Add References”, ficha “Browse” y luego
ubicar el archivo [Link]
Escribir el siguiente código en el formulario:
Public Class frmListaEmpleado
Private dst As New DataSet
Private odaEmpleado As New [Link]
Delegate Function DelegadoListarEmpleados() As DataSet
Private oDelegado As New DelegadoListarEmpleados _
(AddressOf [Link])
Private Sub IniciarLlamadaAsincrona(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
Dim acb As New AsyncCallback(AddressOf FinalizarLlamadaAsincrona)
[Link](acb, Nothing)
End Sub
Private Sub FinalizarLlamadaAsincrona(ByVal iar As IAsyncResult)
dst = [Link](iar)
Dim mi As New MethodInvoker(AddressOf MostrarResultados)
[Link](mi)
End Sub
Luis Dueñas Pag 144
La Biblia de Visual Basic .NET
Private Sub MostrarResultados()
[Link] = [Link](0)
End Sub
End Class
Grabar y ejecutar la aplicación.
Gráfico 2.33: Ejecución del formulario que lista empleados
desde la librería de datos asíncrona
Luis Dueñas Pag 145
La Biblia de Visual Basic .NET
4.4. Programación Paralela
La programación paralela permite aprovechar los computadores con varios
procesadores o núcleos de procesamiento, permitiendo crear subtareas en
diferentes procesadores en vez de hacerlo en uno solo. Actualmente, la
mayoría de PCs disponen de más de un procesador y es importante tomar
ventaja de esta característica desde nuestras aplicaciones.
Anteriormente, era difícil programar código para manejar varios
procesadores, pero con .NET Framework 4 se ha incorporado la Librería de
Procesamiento de Tareas en paralelo más conocida como la TPL.
Existen 2 formas de implementar la programación paralela en .NET:
Paralelismo de Datos y Paralelismo de Tareas. También Microsoft ha
extendido la programación paralela en LINQ al cual se le conoce como
PLINQ. El gráfico mostrado a continuación resume la arquitectura de la
programación paralela en .NET Framework 4.
Gráfico 2.34: Arquitectura de programación paralela en .NET
Para conocer más sobre este tema ver la referencia 16 al final del libro. A
continuación presentamos un ejemplo sobre Paralelismo de Datos y el otro
sobre Paralelismo de Tareas.
Luis Dueñas Pag 146
La Biblia de Visual Basic .NET
Paralelismo de Datos
El paralelismo de datos hace referencia a los escenarios en los que la
misma operación se realiza simultáneamente (es decir, en paralelo) en
elementos de una colección o matriz de origen. Varias sobrecargas de los
métodos ForEach y For admiten el paralelismo de los datos. En las
operaciones paralelas de datos, se crean particiones de la colección de
origen para que varios subprocesos puedan funcionar simultáneamente en
segmentos diferentes.
TPL admite el paralelismo de datos a través de la clase System.
[Link]. Esta clase proporciona las implementaciones
paralelas basadas en método de los bucles For y For Each en Visual Basic.
Se escribe la lógica del bucle para un bucle [Link] o [Link]
de forma muy similar a como se escribiría un bucle secuencial. No tiene
que crear los subprocesos ni poner en la cola los elementos de trabajo.
En el siguiente ejemplo se muestra un bucle For en paralelo que permite
crear 1000 gráficos de círculos con fondos degradados generados al azar.
Demo 22
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo22.
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmGraficoCirculos
Size 300,300
StartPosition CenterScreen
Text Crear Gráfico de Círculos
WindowState MaximizedBox
Button1 Name btnCrearCirculos
Location 12, 12
Size 75, 23
Text Crear
Luis Dueñas Pag 147
La Biblia de Visual Basic .NET
El diseño del formulario debe quedar similar al gráfico 2.35:
Gráfico 2.35: Diseño del formulario Crear Círculos
Escribir el siguiente código en el formulario:
Imports [Link].Drawing2D
Imports [Link]
Imports [Link]
Public Class frmGrafico
Private oAzar As New Random
Private Function GenerarColorAzar() As Color
[Link](10)
Dim R, G, B As Integer
R = [Link](255)
G = [Link](255)
B = [Link](255)
Return ([Link](R, G, B))
End Function
Private Sub CrearCirculo(ByVal N As Integer)
Dim X, Y As Integer
Dim rec As Rectangle
Dim deg As LinearGradientBrush
Luis Dueñas Pag 148
La Biblia de Visual Basic .NET
X = [Link]([Link])
[Link](10)
Y = [Link]([Link])
rec = New Rectangle(X, Y, 50, 50)
deg = New LinearGradientBrush(rec, _
GenerarColorAzar, GenerarColorAzar, _
[Link])
[Link](deg, rec)
[Link]([Link], _
New Font("Courier New", 10), [Link], _
X + 15, Y + 15)
End Sub
Private Sub CrearCirculos(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link](1, 1000, Sub(I)
CrearCirculo(I)
End Sub)
End Sub
End Class
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 149
La Biblia de Visual Basic .NET
Gráfico 2.36: Ejecución del formulario Crear Círculos
Luis Dueñas Pag 150
La Biblia de Visual Basic .NET
Paralelismo de Tareas
El paralelismo de tareas hace referencia a la ejecución simultánea de una o
varias tareas independientes. Una tarea representa una operación
asincrónica y, en ciertos aspectos, se asemeja a la creación de un nuevo
subproceso o elemento de trabajo ThreadPool, pero con un nivel de
abstracción mayor. Las tareas proporcionan dos ventajas fundamentales:
1. Un uso más eficaz y más escalable de los recursos del sistema.
2. Un mayor control mediante programación del que se puede conseguir
con un subproceso o un elemento de trabajo.
Demo 23
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo23.
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmListaEmpleado
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 400,300
StartPosition CenterScreen
Text Lista Empleados usando Tarea
Paralela
DataGridView1 Name dgvEmpleado
Dock Fill
ReadOnly True
SelectionMode FullRowSelect
El diseño del formulario debe quedar similar al gráfico 2.37:
Luis Dueñas Pag 151
La Biblia de Visual Basic .NET
Gráfico 2.37: Diseño del formulario Lista Empleados
Escribir el siguiente código en el formulario:
Imports [Link]
Imports [Link]
Imports [Link]
Public Class frmListaEmpleado
Public Function ListarEmpleados() As DataSet
Dim dst As New DataSet
Using con As New SqlConnection("uid=sa;pwd=123456; _
data source=Lduenas\MCTS;initial catalog=Northwind")
[Link]()
Dim dap As New SqlDataAdapter("WaitFor Delay '[Link]'; _
Select EmployeeID,LastName,FirstName From Employees", con)
[Link](dst, "Empleados")
End Using '[Link]
Return (dst)
End Function
Private Sub CargarDatos(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim dst As Task(Of DataSet) = [Link](Function()
ListarEmpleados())
[Link]()
[Link] = [Link](0)
Luis Dueñas Pag 152
La Biblia de Visual Basic .NET
End Sub
End Class
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 2.38: Ejecución del formulario Lista Empleados
Luis Dueñas Pag 153
La Biblia de Visual Basic .NET
5. Criptografía o Cifrado de Datos
La Criptografía o Cifrado de Datos permiten asegurar los datos de una
aplicación cuando estos son sensitivos, es decir, cuando no se quiere que
se vea su contenido, por ejemplo una planilla de sueldos. Sobre todo ahora
con Internet es fácil que los datos sean interceptados por terceros, para lo
cual debemos usar el cifrado o encriptación.
.NET Framework proporciona el espacio de nombres [Link].
Cryptography que contiene muchas clases que nos ayudan a realizar las
principales tareas criptográficas como: cifrado simétrico, cifrado asimétrico,
firmas criptográficas y valores hash criptográficos.
La diferencia entre el cifrado simétrico y el asimétrico, es que, el cifrado
simétrico, usa la misma clave para encriptar y desencriptar los datos,
mientras que el asimétrico, usa 2 claves: una pública y otra privada, las
cuales tienen una relación matemática.
Para obtener más información sobre este tema ver la referencia 17 al final
del libro.
5.1 Cifrado Simétrico por Caracter
Este tipo de cifrado es el más fácil de implementar y el menos seguro, ya
que solo basta transformar cada carácter de la data original por uno nuevo
mediante una transformación simple, por ejemplo, si a cada código de un
caracter le sumamos un número lo estaremos cifrando y si le restamos el
mismo número lo estaremos descifrando, tal como se muestra en el
siguiente ejemplo.
Demo 24
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo24.
Cambiar de nombre al formulario de [Link] a [Link]
Luis Dueñas Pag 154
La Biblia de Visual Basic .NET
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmCifradoTexto
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 300,300
StartPosition CenterScreen
Text Cifrado Simétrico por Carácter
TextBox1 Name txtArchivo
Location 12,12
MultiLine True
ScrollBars Vertical
Size 268,211
Button1 Name btnGrabar
Cursor Hand
Location 12,238
Size 75,23
Text Grabar
Button2 Name btnAbrir
Cursor Hand
Location 205,238
Size 75,23
Text Abrir
El diseño del formulario debe quedar similar al gráfico 2.39:
Luis Dueñas Pag 155
La Biblia de Visual Basic .NET
Gráfico 2.39: Diseño del formulario cifrado simétrico por caracter
Ingresar al editor de código y escribir el siguiente código.
Imports [Link] 'FileStream
Public Class frmCifradoTexto
Private Sub GrabarArchivo(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim sfd As New SaveFileDialog 'Dialogo de Guardar
[Link] = "Selecciona el archivo a guardar"
[Link] = "Archivos de texto|*.txt"
If [Link] = [Link] Then
Using fs As New FileStream([Link], [Link], _
[Link], [Link])
Dim I As Integer
Dim C As String
Dim N As Byte
For I = 0 To [Link] - 1
C = [Link](I, 1)
N = Asc(C)
If N < 245 Then [Link](N + 10)
Next
End Using
[Link] = [Link]
Luis Dueñas Pag 156
La Biblia de Visual Basic .NET
End If
End Sub
Private Sub AbrirArchivo(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim ofd As New OpenFileDialog 'Dialogo de Abrir
[Link] = "Selecciona el archivo a abrir"
[Link] = "Archivos de texto|*.txt"
If [Link] = [Link] Then
Using fs As New FileStream([Link], [Link], _
[Link], [Link])
Dim I As Integer
Dim C As String
Dim N As Byte
Dim S As String = ""
Dim fi As New FileInfo([Link])
For I = 0 To [Link] - 1
N = [Link]
C = Chr(N - 10)
S=S+C
Next
[Link] = S
End Using
[Link] = [Link]
End If
End Sub
End Class
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 157
La Biblia de Visual Basic .NET
Gráfico 2.40: Ejecución del formulario cifrado simétrico por
caracter
Luis Dueñas Pag 158
La Biblia de Visual Basic .NET
5.2. Cifrado Simétrico por Bloques
El cifrado simétrico por bloques o cifrado de clave secreta es aquel que usa
la misma clave para encriptar o cifrar y para desencriptar o descifrar. Este
es muy rápido y se usa en gran cantidad de datos. Entre los más populares
tenemos el DES, TripleDES, Estandar de Cifrado Avanazado (CA), etc.
Todos los algoritmos de cifrado simétrico usan un vector de inicialización de
datos (IV) y una clave secreta (PK), lo que los diferencia son el tamaño de
ambos, mientras más grande son serán más seguros (más difíciles de
descifrar).
A continuación veremos un ejemplo del uso del cifrado simétrico en .NET
Framework, clases como: SymmetricAlgorithm, DESCryptoServiceProvider,
TripleDESCryptoServiceProvider y RijndaelManaged.
Demo 25
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo25.
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmCifradoTexto
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 300,300
StartPosition CenterScreen
Text Cifrado Simétrico por Bloques
Label1 Name lblClave
AutoSize True
Location 15, 16
Text Clave:
TextBox1 Name txtClave
Location 59,12
Luis Dueñas Pag 159
La Biblia de Visual Basic .NET
Size 221,20
RadioButton1 Name rbDES
AutoSize True
Location 12,38
Text DES
RadioButton2 Name rbTripleDES
AutoSize True
Location 77,38
Text Triple DES
RadioButton3 Name rbRijnhdael
AutoSize True
Location 168,38
Text Rijnhdael
TextBox2 Name txtArchivo
Location 12,61
MultiLine True
ScrollBars Vertical
Size 268,162
Button1 Name btnGrabar
Cursor Hand
Location 12,238
Size 75,23
Text Grabar
Button2 Name btnAbrir
Cursor Hand
Location 205,238
Size 75,23
Text Abrir
El diseño del formulario debe quedar similar al gráfico 2.41:
Luis Dueñas Pag 160
La Biblia de Visual Basic .NET
Gráfico 2.41: Diseño del formulario cifrado simétrico por bloques
Ingresar al editor de código y escribir el siguiente código.
Imports [Link] 'FileStream, CryptoStream
Imports [Link] 'SymmetricAlgorithm
Imports [Link] 'Encoding
Public Class frmCifradoTexto
Private sa As SymmetricAlgorithm
Private clave() As Byte
Private vectorInicio() As Byte
Private Data() As Byte
Private Sub GrabarArchivo(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim sfd As New SaveFileDialog 'Dialogo de Guardar
[Link] = "Selecciona el archivo a guardar"
[Link] = "Archivos de texto|*.txt"
If [Link] = [Link] Then
Try
clave = [Link] _
([Link]([Link], "*"))
Data = [Link]([Link])
[Link] = clave
Using fs As New FileStream([Link], _
Luis Dueñas Pag 161
La Biblia de Visual Basic .NET
[Link], [Link], [Link])
Using cs As New CryptoStream(fs, [Link], _
[Link])
[Link](Data, 0, [Link])
End Using
End Using
[Link] = [Link]
Catch ex As Exception
[Link]("Ocurrio un error al grabar")
End Try
End If
End Sub
Private Sub AbrirArchivo(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim ofd As New OpenFileDialog 'Dialogo de Abrir
[Link] = "Selecciona el archivo a abrir"
[Link] = "Archivos de texto|*.txt"
If [Link] = [Link] Then
Try
clave = [Link] _
([Link]([Link], "*"))
Data = [Link]([Link])
[Link] = clave
Using ms As New MemoryStream
Using cs As New CryptoStream(ms, [Link], _
[Link])
[Link](Data, 0, [Link])
End Using
[Link] = [Link]([Link]())
End Using
[Link] = [Link]
Catch ex As Exception
[Link]("Clave No coincide")
End Try
End If
End Sub
Private Sub IniciarAlgoritmoSimetrico(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link], _
Luis Dueñas Pag 162
La Biblia de Visual Basic .NET
[Link], [Link]
If [Link] Then
sa = New DESCryptoServiceProvider
ElseIf [Link] Then
sa = New TripleDESCryptoServiceProvider
ElseIf [Link] Then
sa = New RijndaelManaged
End If
Dim frase As String = "Mi mama"
vectorInicio = [Link] _
([Link]([Link], "*"))
[Link] = vectorInicio
[Link] = [Link]
[Link] = [Link]("Tamaño Clave: {0} - Tamaño IV: {1}", _
[Link], [Link])
End Sub
End Class
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 2.42: Ejecución del formulario cifrado simétrico por
bloques
Luis Dueñas Pag 163
La Biblia de Visual Basic .NET
5.3. Valores Hash Criptográficos
Un valor hash es una representación numérica de un conjunto de datos y
se usa para asegurar la integridad de los mensajes, es decir, comprobar
que no fueron alterados.
Si a un mensaje de texto le aplicamos un algoritmo hash para obtener un
valor hash o resumen y luego enviamos el mensaje con el resumen,
cuando llegue a su destinatario para verificar que no fue alterado
nuevamente se aplica el algoritmo y se obtiene otro resumen, si no
coincide con el inicial significa que este fue alterado.
En vez de comparar cada byte de un archivo grande solo podemos
comparar los resúmenes o valores hash generados para verificar archivos.
En .NET existen varias clases que implementan algoritmos hash, tales
como: HMACSHA1, MACTripleDES, MD5CryptoServiceProvider, RIPEMD160,
SHA1Managed, SHA256Managed, SHA384Managed y SHA512Managed.
A continuación crearemos una aplicación Windows que compare 2 archivos
de texto para saber si son iguales o no, usando comparación completa y
también valores hash.
Demo 26
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo26.
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmVerificarArchivos
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 400,460
StartPosition CenterScreen
Text Verificación de Archivos de
Luis Dueñas Pag 164
La Biblia de Visual Basic .NET
Texto con Valores Hash
Label1 Name lblArchivoOrigen
AutoSize True
Location 12, 10
Text Selecciona el Archivo Origen a
verificar
TextBox1 Name txtArchivoOrigen
Location 12,28
ReadOnly True
Size 340,20
Button1 Name btnAbrirArchivoOrigen
Cursor Hand
Location 352,26
Size 28,23
Text …
TextBox2 Name txtDataOrigen
Location 12,55
MultiLine True
ScroolBars Vertical
Size 368,98
Label2 Name lblResumenOrigen
AutoSize True
Location 12,169
Text Resumen Origen:
TextBox3 Name txtResumenOrigen
Location 110,162
ReadOnly True
Size 189,20
Button2 Name btnCrearResumenOrigen
Cursor Hand
Location 305,164
Size 75,23
Text Resumir
Label3 Name lblArchivoDestino
AutoSize True
Location 12,195
Text Selecciona el Archivo Destino a
verificar
TextBox4 Name txtArchivoDestino
Location 12,213
ReadOnly True
Size 340,20
Luis Dueñas Pag 165
La Biblia de Visual Basic .NET
Button3 Name btnAbrirArchivoDestino
Cursor Hand
Location 352,211
Size 28,23
Text …
TextBox5 Name txtDataDestino
Location 12,240
MultiLine True
ScroolBars Vertical
Size 368,98
Label4 Name lblResumenDestino
AutoSize True
Location 12,360
Text Resumen Destino:
TextBox6 Name txtResumenDestino
Location 110,353
ReadOnly True
Size 189,20
Button4 Name btnCrearResumenDestino
Cursor Hand
Location 305,355
Size 75,23
Text Resumir
Button5 Name btnCompararTodo
Cursor Hand
Location 12,391
Size 121,23
Text Comparar Todo
Button6 Name btnCompararResumen
Cursor Hand
Location 259,391
Size 121,23
Text Comparar Resumen
El diseño del formulario debe quedar similar al gráfico 2.43:
Luis Dueñas Pag 166
La Biblia de Visual Basic .NET
Gráfico 2.43: Diseño del formulario verificación valores hash
Ingresar al editor de código y escribir el siguiente código.
Imports [Link] 'FileStream, StreamReader
Imports [Link] 'Encoding
Imports [Link] 'SHA1Managed
Public Class frmVerificarArchivos
Private Sub Abrir(ByVal txtArchivo As TextBox, ByVal txtData As TextBox)
Dim ofd As New OpenFileDialog 'Dialogo de Abrir
With ofd
.Title = "Abrir Archivo de Texto"
.Filter = "Archivo de texto|*.txt"
If .ShowDialog = [Link] Then
Using fs As New FileStream(.FileName, [Link], _
[Link], [Link])
Using sr As New StreamReader(fs, [Link])
[Link] = .FileName
Luis Dueñas Pag 167
La Biblia de Visual Basic .NET
[Link] = [Link]
End Using
End Using
End If
End With
End Sub
Private Sub Resumir(ByVal txtData As TextBox, _
ByVal txtResumen As TextBox)
Dim sha1 As New SHA1Managed
Dim Data() As Byte = [Link]([Link])
Dim Resumen() As Byte = [Link](Data)
[Link] = [Link](Resumen)
End Sub
Private Sub AbrirArchivoOrigen(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Abrir(txtArchivoOrigen, txtDataOrigen)
End Sub
Private Sub AbrirArchivoDestino(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Abrir(txtArchivoDestino, txtDataDestino)
End Sub
Private Sub CompararTodo(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If [Link] = [Link] Then
Dim TiempoInicio As DateTime = Now
Dim I As Integer
Dim strDataOrigen As String = [Link]
Dim strDataDestino As String = [Link]
Dim iguales As Boolean = True
For I = 0 To [Link] - 1
If [Link](I, 1) <> _
[Link](I, 1) Then
iguales = False
Exit For
End If
Next
Luis Dueñas Pag 168
La Biblia de Visual Basic .NET
Dim TiempoFin As DateTime = Now
Dim TiempoDemorado As TimeSpan = _
[Link](TiempoInicio)
If iguales Then
[Link]("Archivos son iguales", _
[Link], [Link], _
[Link])
Else
[Link]("Archivos No son iguales, por contenido
distinto", _
[Link], [Link], _
[Link])
End If
Else
[Link]("Archivos No son iguales, por tamaño distinto",
"Aviso", _
[Link], [Link])
End If
End Sub
Private Sub CrearResumenOrigen(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Resumir(txtDataOrigen, txtResumenOrigen)
End Sub
Private Sub CrearResumenDestino(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Resumir(txtDataDestino, txtResumenDestino)
End Sub
Private Sub CompararResumen(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If [Link] = [Link] Then
Dim TiempoInicio As DateTime = Now
Dim iguales As Boolean = ([Link] = _
[Link])
Dim TiempoFin As DateTime = Now
Dim TiempoDemorado As TimeSpan = _
[Link](TiempoInicio)
If iguales Then
Luis Dueñas Pag 169
La Biblia de Visual Basic .NET
[Link]("Archivos son iguales", _
[Link], _
[Link], [Link])
Else
[Link]("Archivos No son iguales, por contenido
distinto", _
[Link], [Link], _
[Link])
End If
Else
[Link]("Archivos No son iguales, por tamaño distinto", _
"Aviso", [Link], [Link])
End If
End Sub
End Class
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 2.44: Ejecución del formulario verificación valores hash
Luis Dueñas Pag 170
La Biblia de Visual Basic .NET
Preguntas de Repaso
1. Cómo se llama la clase de .NET que obtiene información del entorno o
sistema?
2. Cuáles son las 2 nuevas propiedades de la clase Environment para
trabajar con sistemas y procesos de 64 bits?
3. Con qué propiedad de la clase Environment se obtiene el nombre de la
PC?
4. Cómo se llama la Enumeración de la clase Environment que tiene los
nombres de los directorios especiales de Windows.
5. Con qué método de la clase Environment obtenemos la ruta de un
directorio especial?
6. Para qué se usa el Registro de Windows?
7. En qué espacio de nombres se encuentra la clase Registry que accede
al registro de Windows.
8. Cómo se llama la clase de .NET que permite trabajar con una entrada o
clave del registro de Windows.
9. Menciona 2 métodos de la clase RegistryKey.
10. Cómo se llama la clase de .NET que permite trabajar con procesos o
tareas del sistema y en que espacio de nombres se encuentra?
11. Con qué método de la clase Process se obtienen todos los procesos que
se encuentran actualmente en ejecución?
12. Con qué método de la clase Process se puede ejecutar un programa o
aplicación?
Luis Dueñas Pag 171
La Biblia de Visual Basic .NET
13. Cómo se llama el espacio de nombres que permite manejar la entrada y
salida?
14. Menciona 3 clases que permitan manejar entrada y salida?
15. Menciona 3 clases que permitan manejar secuencias o flujos?
16. Cuál es la diferencia entre una clase instanciable y otra con miembros
compartidos?
17. Cuáles son los 2 métodos nuevos de la clase Directory en .NET 4?
18. Con qué clases en .NET se puede leer y escribir archivos
secuencialmente?
19. Qué clase de entrada y salida debemos usar para indicar el modo de
apertura de un archivo, el nivel de acceso y si estará compartido para
lectura y/o escritura?
20. Con qué clase obtenemos información sobre un archivo, por ejemplo su
tamaño?
21. Qué clase de .NET Framework debemos usar para obtener la ruta de un
archivo, su nombre o extensión?
22. Cuál es la diferencia de los algoritmos de compresión Deflate y Gzip?
23. Menciona 2 métodos de la clase DeflateStream.
24. Cuáles son los servicios lógicos en los que puede clasificarse toda
aplicación.
25. Cómo se dividen los Servicios de Negocio o Servicios Empresariales?
26. Qué tipo de miembros contiene una clase Entidad del Negocio?
27. Qué tipo de miembros contiene una clase Regla del Negocio?
Luis Dueñas Pag 172
La Biblia de Visual Basic .NET
28. Qué extensión genera un proyecto de tipo Librería de Clases?
29. Para que se usan las técnicas de programación asíncrona?
30. Menciona 3 técnicas de programación asíncrona.
31. Cuando se usa la clase Thread?
32. Menciona 3 métodos de la clase Thread.
33. Qué método de la clase Thread debe usarse para que la subtarea actual
espere antes de ejecutar otra subtarea cuando hay dependencia de
subtareas?
34. Con qué clase y método implementamos agrupación de subtareas para
ahorrar la cantidad de hilos creados en memoria cuando son muchas
llamadas?
35. Cuál es la forma mas simple de implementar llamadas asíncronas a un
servicio web?
36. Para que se usan los delegados CallBacks?
37. Qué es la programación paralela?
38. En qué consiste el paralelismo de datos y cómo se implementa en NET?
39. En qué consiste el paralelismo de tareas y cómo se implementa en
NET?
40. Cual es el espacio de nombres de .Net que se usa para implementar las
tareas criptográficas?
41. Menciona las 4 principales tareas criptográficas.
42. Que és el cifrado simétrico o de clave secreta?
Luis Dueñas Pag 173
La Biblia de Visual Basic .NET
43. Menciona 3 clases de .Net que implementen cifrado simétrico?
44. Cuales son los 2 arreglos de bytes que se usan en el cifrado simétrico
por bloques para cifrar y descifrar la data?
45. Cuál es el uso de los Valores Hash Criptográficos?
46. Menciona 3 clases que implementen algoritmos Hash cifrados?
Luis Dueñas Pag 174
La Biblia de Visual Basic .NET
Capitulo 3: Accediendo a Datos con ADO .NET
Inicaremos este capítulo con una breve introducción al acceso a datos en
ADO .NET en la cual veremos su arquitectura, es decir sus componentes
básicos que son los proveedores de datos y el DataSet.
Luego veremos como trabajar en forma conectada para acceder a
diferentes orígenes de datos como MS SQL Server, MS Access, MS Excel y
DBF; luego como ejecutar comandos de selección de un valor, una fila,
varias filas y varios conjuntos de filas; después aprenderemos como
realizar mantenimiento de datos en forma conectada mediante comandos
de actualización.
Después veremos como trabajar en forma desconectada usando DataSet,
es decir como crear tablas, relaciones y vistas; como operar sobre los
datos: filtrar, ordenar y buscar; también como hacer mantenimiento
desconectado y enviar los cambios al origen de datos.
En la cuarta parte veremos como trabajar en forma desconectada, pero
usando listas de objetos en vez de DataSet, ya que consumen menos
memoria y también permiten realizar todas las operaciones en forma
desconectada: tales como filtro, ordenación y búsqueda. Además
aprenderemos como crear un mantenimiento con objetos.
Finalmente, revisaremos LINQ para consultar datos de un DataSet, de una
tabla SQL y de una lista de objetos, es decir: LINQ a DataSet, LINQ a SQL
y LINQ a Entidades.
Luis Dueñas Pag 175
La Biblia de Visual Basic .NET
1. Trabajando en Forma Conectada
En este tema trataremos sobre como trabajar en forma conectada, es
decir, realizar operaciones en línea o directamente sobre la base de datos,
para lo cual la conexión debe estar abierta antes de realizar la operación,
pero antes revisaremos los fundamentos del acceso a datos con ADO .NET,
en especial veremos su arquitectura.
1.1. Introducción al Acceso a Datos con ADO .NET
ADO .NET es el Modelo de Programación de Datos de Microsoft que se usa
para acceder a diferentes orígenes de datos desde .NET Framework, es el
sucesor de ADO (ActiveX Data Objects); anteriormente otros modelos
usados fueron RDO (Remote Data Objects) y DAO (Data Access Objects).
La arquitectura de ADO .NET se divide en 2 componentes:
Los Proveedores de Datos de .NET Framework: Permite conectarse a un
origen de datos y manejar datos solo lectura, a través de clases como
Connection, Command, DataAdapter y DataReader. Se divide en:
Proveedores Nativos: Acceden a un origen de datos especifico
como MS SQL Server (SQLClient) y Oracle (OracleClient).
Proveedores Generales: Acceden a diferentes orígenes de datos,
a esta categoría pertenecen OLEDB y ODBC, que pueden
acceder a MS Excel, MS Access, DBF, DB2, Sybase, Informix,
etc.
El DataSet: Es el repositorio desconectado, que es independiente del
origen de datos y permite manejar la data en forma local y también
enviar de regreso los cambios al origen de datos.
A continuación presentamos el grafico 3.1 con la arquitectura de ADO .NET
que incluye estos 2 componentes y sus principales clases relacionadas.
Luis Dueñas Pag 176
La Biblia de Visual Basic .NET
Gráfico 3.1: Arquitectura de ADO .NET
ADO .NET también se relaciona con otras tecnologías de datos tales como
LINQ, Entity Framework, WCF Data Services y XML. Para ver más
información sobre ADO .NET ver la referencia 18 al final del libro.
Luis Dueñas Pag 177
La Biblia de Visual Basic .NET
1.2. Conectarse a un Origen de Datos
El primer paso para conectarse a un origen de datos es conocer bien la
cadena de conexión que debemos usar y esta depende del origen de datos
o base de datos a la cual deseamos acceder.
Conectarse a una Base de Datos de SQL Server
Para conectarse a una Base de Datos de MS SQL Server debemos usar el
espacio de nombres [Link] el cual contiene las clases
SQLConnection para manejar la conexión a la Base de Datos: abrir y cerrar;
SQLCommand para ejecutar comandos o instrucciones SQL: Select, Insert,
Update o Delete y SQLDataReader para almacenar en una fila los datos que
se obtengan de una base de datos.
La cadena de conexión (propiedad ConnectionString) para SQL Server
consta de varias partes que podemos dividirla en:
Información de autenticación: Esta depende del tipo de seguridad, que
puede ser de 2 tipos:
Seguridad de Window: Si la seguridad es Integrada o de
Windows (Single Sign On) usar lo siguiente:
Integrated security=yes|true|SSPI;
Trusted_connection=yes|true|SSPI;
Seguridad de SQL Server y Windows: Si la seguridad es mixta se
puede usar la cadena anterior o un usuario de SQL Server:
user id=usuario;password=clave
uid=usuario;pwd=clave
Información de Base de Datos: Esta depende del número de instancias
o instalaciones que se hayan hecho en el servidor:
Una sola instancia: Si solo hay una instancia instalada usar:
Luis Dueñas Pag 178
La Biblia de Visual Basic .NET
server=nombre_servidor;database=base_datos
Varias instancias: Si hay varias instancias instaladas en el mismo
servidor usar lo siguiente:
data source=nombre_servidor\ nombre_instancia;initial
catalog=base_datos
A continuación presentamos un ejemplo simple de cómo conectarse a la
base de datos Northwind de un servidor SQL Server llamado Lduenas que
tiene una instancia llama MCTS con el usuario sa cuya clave es del 1 al 6.
Nota: En la mayoría de ejemplos del libro vamos a usar la base de datos
Northwind, por tanto la cadena de conexión será la misma. Esta debe ser
cambiada de acuerdo a los datos de su servidor y de preferencia hay que
crear un nuevo usuario que no se el sa.
Demo 27
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo27.
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmConexionSQL
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 400,300
StartPosition CenterScreen
Text Conectarse a SQL Server
DataGridView1 Name dgvEmpleado
Dock Fill
ReadOnly True
SelectionMode FullRowSelect
Luis Dueñas Pag 179
La Biblia de Visual Basic .NET
El diseño del formulario debe quedar similar al gráfico 3.2:
Gráfico 3.2: Diseño del formulario para conectarse a SQL Server
Ingresar al editor de código y escribir el siguiente código.
Imports [Link] 'SqlConnection, SqlCommand, SqlDataReader
Public Class frmConexionSQL
Private Sub ListarEmpleados(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
'Definir un objeto intermediario para enlace de datos
Dim bs As New BindingSource
'Definir la conexion al SQL Server instalado en la PC
Using con As New SqlConnection _
("uid=sa;pwd=123456;data source=Lduenas\MCTS;initial
catalog=Northwind")
'Abrir la conexion
[Link]()
'Definir el comando con el Select a ejecutar sobre la conexion
Dim cmd As New SqlCommand _
("Select EmployeeID,LastName,FirstName From Employees", con)
'Definir y crear el DataReader al ejecutar el comando
Dim drd As SqlDataReader = [Link]
'Enlazar el DataReader al intermediario
[Link] = drd
'Cerrar el DataReader
Luis Dueñas Pag 180
La Biblia de Visual Basic .NET
[Link]()
End Using 'Se cierra la conexion automaticamente
'Enlazar el intermediario a la grilla
[Link] = bs
End Sub
End Class
Nota: En el código anterior, se ha tenido que crear un BindingSource ya
que el DataReader no es enlazable al control DataGridView, en cambio el
BindingSource si es enlazable.
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 3.3: Ejecución del formulario para conectarse a SQL Server
Luis Dueñas Pag 181
La Biblia de Visual Basic .NET
Conectarse a una Base de Datos de MS Access
Para conectarse a una Base de Datos de MS Access usar el espacio de
nombres [Link] el cual contiene clases similares al SQLClient
pero inician con el prefijo Oledb, tales como: OledbConnection,
OledbCommand y OledbDataReader.
La cadena de conexión para una base de datos de MS Access es la
siguiente: “provider=[Link].4.0;data source=base_datos.mdb”
Si la base de datos tuviera clave hay que aumentar el usuario y la clave a
la cadena de conexión.
A continuación crearemos una aplicación que nos permita visualizar
cualquier archivo de base de datos MS Access, listando sus tablas y al
seleccionar una tabla mostrar una lista con sus campos y la data que esta
contiene. Esta aplicación nos será útil para examinar archivos de base de
datos cuando el programa MS Access no este instalado en una PC.
Demo 28
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo28.
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmVisorAccess
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 500,500
StartPosition CenterScreen
Text Visor de Base de Datos MS
Access
Label1 Name lblArchivo
AutoSize True
Location 12, 11
Luis Dueñas Pag 182
La Biblia de Visual Basic .NET
Text Selecciona un Archivo de Base
de Datos MS Access
TextBox1 Name txtArchivo
Location 13,28
ReadOnly True
Size 444,20
Button1 Name btnAbrir
Cursor Hand
Location 456,25
Size 25,23
Text …
ListBox1 Name lstTabla
Location 12,59
Size 230,134
ListBox2 Name lstCampo
Location 250,59
Size 230,134
DataGridView1 Name dgvData
Location 12,199
ReadOnly True
SelectionMode FullRowSelect
Size 468,262
El diseño del formulario debe quedar similar al gráfico 3.4:
Luis Dueñas Pag 183
La Biblia de Visual Basic .NET
Gráfico 3.4: Diseño del formulario Visor MS Access
Ingresar al editor de código y escribir el siguiente código.
Imports [Link] 'OledbConnection, OledbCommand, _
OledbDataReader
Imports [Link]
Public Class frmVisorAccess
Private con As New OleDbConnection
Private Sub ListarTablas(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim ofd As New OpenFileDialog
[Link] = "Selecciona un archivo de base de datos MS Access"
[Link] = "Archivos de MS Access|*.mdb"
If [Link] = [Link] Then
[Link] = [Link]
Luis Dueñas Pag 184
La Biblia de Visual Basic .NET
con = New OleDbConnection _
([Link]("provider=[Link].4.0;Data Source={0}", _
[Link]))
[Link]()
[Link]()
Dim Rest(3) As String
Rest(3) = "Table"
Dim Tabla As DataTable = [Link]("Tables", Rest)
[Link] = Tabla
[Link] = "Table_Name"
End If
End Sub
Private Sub ListarCampos(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim cmd As New OleDbCommand _
([Link]("Select * From [{0}]", [Link](2)), con)
Dim drd As OleDbDataReader = [Link]
[Link]()
[Link]()
For I As Integer = 0 To [Link] - 1
[Link]([Link](I))
Next
[Link]()
[Link] = 0
Dim bs As New BindingSource
[Link] = drd
[Link] = bs
End Sub
End Class
Advertencia: El código anterior no esta programado para base de datos
MS Access con contraseña o clave, para ello tiene que modificarse la
cadena de conexión.
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 185
La Biblia de Visual Basic .NET
Gráfico 3.5: Ejecución del formulario Visor MS Access
Luis Dueñas Pag 186
La Biblia de Visual Basic .NET
Conectarse a un Archivo de MS Excel
Para conectarse a un Archivo de MS Excel también se usa el espacio de
nombres [Link], al igual que MS Access usa el mismo
proveedor que es Microsoft Jet pero al final se configura en propiedades
extendidas Excel 8.0.
La cadena de conexión para un archivo de MS Excel es la siguiente:
“provider=[Link].4.0;data source=archivo_excel.xls;extended
properties=Excel 8.0”.
Siguiendo la idea del ejemplo anterior, crearemos ahora una aplicación que
permita ver cualquier archivo de MS Excel, listando las hojas de cálculo que
tiene el archivo y al seleccionar una hoja mostrando sus campos y la data
de la hoja.
Demo 29
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo29.
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmVisorExcel
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 500,500
StartPosition CenterScreen
Text Visor de Archivos de MS Excel
Label1 Name lblArchivo
AutoSize True
Location 12, 11
Text Selecciona un Archivo de MS
Excel
TextBox1 Name txtArchivo
Luis Dueñas Pag 187
La Biblia de Visual Basic .NET
Location 13,28
ReadOnly True
Size 444,20
Button1 Name btnAbrir
Cursor Hand
Location 456,25
Size 25,23
Text …
ListBox1 Name lstTabla
Location 12,59
Size 230,134
ListBox2 Name lstCampo
Location 250,59
Size 230,134
DataGridView1 Name dgvData
Location 12,199
ReadOnly True
SelectionMode FullRowSelect
Size 468,262
El diseño del formulario debe quedar similar al gráfico 3.6:
Luis Dueñas Pag 188
La Biblia de Visual Basic .NET
Gráfico 3.6: Diseño del formulario Visor MS Excel
Ingresar al editor de código y escribir el siguiente código.
Imports [Link] 'OledbConnection, OledbCommand, _
OledbDataReader
Imports [Link]
Public Class frmVisorAccess
Private con As New OleDbConnection
Private Sub ListarTablas(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim ofd As New OpenFileDialog
[Link] = "Selecciona un archivo de MS Excel"
[Link] = "Archivos de MS Excel|*.xls"
If [Link] = [Link] Then
[Link] = [Link]
Luis Dueñas Pag 189
La Biblia de Visual Basic .NET
con = New OleDbConnection _
([Link]("provider=[Link].4.0;Data Source={0};
extended properties=Excel 8.0", [Link]))
[Link]()
[Link]()
Dim Rest(3) As String
Rest(3) = "Table"
Dim Tabla As DataTable = [Link]("Tables", Rest)
[Link] = Tabla
[Link] = "Table_Name"
End If
End Sub
Private Sub ListarCampos(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim cmd As New OleDbCommand _
([Link]("Select * From [{0}]", [Link](2)), con)
Dim drd As OleDbDataReader = [Link]
[Link]()
[Link]()
For I As Integer = 0 To [Link] - 1
[Link]([Link](I))
Next
[Link]()
[Link] = 0
Dim bs As New BindingSource
[Link] = drd
[Link] = bs
End Sub
End Class
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 190
La Biblia de Visual Basic .NET
Gráfico 3.7: Ejecución del formulario Visor MS Excel
Luis Dueñas Pag 191
La Biblia de Visual Basic .NET
Conectarse a un Archivo DBF
Los archivos de bases de datos (DBF) es un formato antiguo usado por
muchas empresas que contienen solo una tabla que puede estar indexada.
A veces es necesario obtener datos de este tipo de formato para lo cual
también tenemos que usar el espacio de nombres [Link].
La cadena de conexión para un archivo DBF de DBase, FoxBase, Clipper,
etc, es la siguiente: “provider=[Link].4.0;data source=
ruta_archivo_dbf;extended properties=Dbase III”.
Al momento de especificar el comando Select ira el nombre del archivo
(físico) como nombre de tabla (lógico).
Advertencia: El nombre del archivo DBF no debe tener más de 8
caracteres, de lo contrario se originaría un error al acceder al archivo.
A continuación veremos como leer los datos del archivo [Link] provisto
por el INEI (Instituto Nacional de Estadística e Informática) que contiene
los distritos de las diferentes provincias de los departamentos del Perú en
una sola tabla o archivo. Para descargar el archivo ver la referencia 19 al
final del libro.
Ademas de leer datos del DBF también el ejemplo nos muestra como copiar
los datos hacia SQL Server en forma masiva usando la clase SqlBulkCopy
que es muy eficiente para copiar gran cantidad de datos en vez de insertar
fila x fila que consume muchos recursos y demora demasiado.
Nota: Es necesario para realizar la copia masiva que se haya creado la
tabla Ubigeo en la base de datos Northwind con 4 campos: CodDpto
char(2), CodProv char(2), CodDist char(2) y Nombre varchar(200).
Demo 30
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo30.
Cambiar de nombre al formulario de [Link] a [Link]
Luis Dueñas Pag 192
La Biblia de Visual Basic .NET
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmConexionDBF
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 570,400
StartPosition CenterScreen
Text Conexión a DBF y Copia a SQL
Server
DataGridView1 Name dgvUbigeo
AutoSizeColumnsM AllCells
Location 3,3
ReadOnly True
SelectionMode FullRowSelect
Size 561,346
Button1 Name btnCopiarA_SQL
Cursor Hand
Location 477,351
Size 87, 23
Text Copiar a SQL
El diseño del formulario debe quedar similar al gráfico 3.8:
Luis Dueñas Pag 193
La Biblia de Visual Basic .NET
Gráfico 3.8: Diseño del formulario conexión a DBF y copia a SQL
Ingresar al editor de código y escribir el siguiente código.
Imports [Link] 'Origen: DBF
Imports [Link] 'Destino: SQL Server
Public Class frmConexionDBF
Private Tabla As New DataTable
Private Sub ListarUbigeo(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Using con As New OleDbConnection _
("provider=[Link].4.0; data source=
C:\Lduenas\NET\LibroVB2010;extended properties=Dbase III")
[Link]()
Dim dap As New OleDbDataAdapter("Select * From Ubigeo", con)
[Link](Tabla)
End Using
[Link] = Tabla
End Sub
Luis Dueñas Pag 194
La Biblia de Visual Basic .NET
Private Sub CopiarA_SQL(ByVal sender As [Link], _
ByVal e As [Link]) Handles btnCopiarA_SQL.Click
Dim TiempoInicio As DateTime = Now
Using con As New SqlConnection _
("uid=sa;pwd=123456;data source=Lduenas\MCTS;
database=Northwind")
[Link]()
Dim bc As New SqlBulkCopy(con)
[Link] = "Ubigeo"
[Link](Tabla)
End Using
Dim TiempoFin As DateTime = Now
Dim Duracion As TimeSpan = [Link](TiempoInicio)
[Link]([Link])
End Sub
End Class
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 3.9: Ejecución del formulario conexión a DBF y copia a SQL
Luis Dueñas Pag 195
La Biblia de Visual Basic .NET
En esta primera parte solo hemos visto como conectarse a MS SQL Server,
MS Access, MS Excel y DBF. Para ver más información de cómo conectarse
a cualquier otros origenes de datos ver la referencia 20 al final del libro.
Luis Dueñas Pag 196
La Biblia de Visual Basic .NET
1.3. Ejecutando Comandos de Selección
En esta segunda parte aprenderemos como ejecutar comandos que
devuelvan datos de una base de datos SQL Server, para lo cual usaremos
las clases: SqlConnection, SqlCommand y SqlDataReader.
Primero veremos como traer un solo dato mediante el método
ExecuteScalar de la clase SqlCommand, luego como traer una fila con el
método ExecuteReader usando el parámetro [Link],
finalmente como traer varias filas usando el parámetro commandBehaviour.
Singleresult y traer varios conjuntos de filas usando el método
ExecuteReader sin parametros.
Ejecutar comandos de Selección que devuelvan un solo valor
Si deseamos ejecutar un comando o instrucción SQL Select que devuelve
un simple valor, que puede ser una cadena, un número o cualquier tipo de
dato, se usa el método ExecuteScalar de la clase SqlCommand.
A continuación un ejemplo que devuelve el nombre completo del empleado
ingresando su código.
Demo 31
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo31.
Cambiar de nombre al formulario de [Link] a frmConsultaEmpleado
.vb
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmConsultaEmpleado
AcceptButton btnConsultar
FormBorderStyle FixedSingle
Luis Dueñas Pag 197
La Biblia de Visual Basic .NET
MaximizeBox False
MinimizeBox False
Size 300,150
StartPosition CenterScreen
Text Consulta de Empleado x Código
Label1 Name lblCodigo
AutoSize True
Location 12, 33
Text Código:
TextBox1 Name txtCodigo
Location 70,26
MaxLength 2
Size 42,20
Button1 Name btnConsultar
Cursor Hand
Enabled False
Location 196,28
Size 75,23
Text Consultar
Label2 Name lblNombre
AutoSize True
Location 12, 68
Text Nombre:
TextBox2 Name txtNombre
Location 70, 61
ReadOnly True
Size 201,20
El diseño del formulario debe quedar similar al gráfico 3.10:
Gráfico 3.10: Diseño del formulario Consulta Empleado
Ingresar al editor de código y escribir el siguiente código.
Luis Dueñas Pag 198
La Biblia de Visual Basic .NET
Imports [Link] 'SqlConnection, SqlCommand
Public Class frmConsultaEmpleado
Private Sub Validarigitos(ByVal sender As Object, _
ByVal e As [Link]) _
Handles [Link]
[Link] = Not ([Link]([Link]) Or _
[Link] = [Link])
End Sub
Private Sub HabilitarBoton(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link] = ([Link] <> "")
End Sub
Private Sub ConsultarNombre(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
Using con As New SqlConnection("uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind")
[Link]()
Dim SQL As String = [Link] _
("Select LastName + ' ' + FirstName From Employees Where
EmployeeID={0}", [Link])
Dim cmd As New SqlCommand(SQL, con)
Dim oNombre As Object = [Link]
If oNombre IsNot Nothing Then
[Link] = CType(oNombre, String)
Else
[Link]()
[Link]("Código No existe")
End If
End Using
End Sub
End Class
Nota: En el código anterior No es necesario controlar el nulo ya que el
campo Apellido y Nombre del Empleado es obligatorio.
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 199
La Biblia de Visual Basic .NET
Gráfico 3.11: Ejecución del formulario Consulta Empleado
Luis Dueñas Pag 200
La Biblia de Visual Basic .NET
Ejecutar comandos de Selección que devuelvan una fila
Si deseamos ejecutar un comando o instrucción SQL Select que devuelve
un registro o una fila, se usa el método ExecuteReader de la clase
SqlCommand seguido del parámetro [Link].
A continuación un ejemplo que devuelve el apellido, nombre, fecha de
nacimiento y la foto del empleado ingresando su código.
Nota: La tabla Employees de la BD Northwind tiene un campo Photo de
tipo Image pero los registros ingresados son Bitmaps, para ver la foto hay
que ingresar nuevos registros agregando arreglo de bytes. En el ejemplo se
ha agregado una foto para el registro 102.
Demo 32
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo32.
Cambiar de nombre al formulario de [Link] a frmConsultaEmpleado
.vb
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmConsultaEmpleado
AcceptButton btnConsultar
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 300,300
StartPosition CenterScreen
Text Consulta de Empleado x Código
Label1 Name lblCodigo
AutoSize True
Location 21, 28
Text Código:
TextBox1 Name txtCodigo
Luis Dueñas Pag 201
La Biblia de Visual Basic .NET
Location 95,21
MaxLength 3
Size 34,20
Button1 Name btnConsultar
Cursor Hand
Enabled False
Location 178,19
Size 75,23
Text Consultar
Label2 Name lblApellido
AutoSize True
Location 21,57
Text Apellido:
TextBox2 Name txtApellido
Location 95, 50
ReadOnly True
Size 158,20
Label3 Name lblNombre
AutoSize True
Location 21,86
Text Nombre:
TextBox3 Name txtNombre
Location 95, 79
ReadOnly True
Size 158,20
Label4 Name lblFechaNac
AutoSize True
Location 21, 115
Text Fecha Nac:
TextBox4 Name txtFechaNac
Location 95, 108
ReadOnly True
Size 79,20
PictureBox1 Name picFoto
BorderStyle Fixed3D
Location 95, 134
Size 156, 118
SizeMode StretchImage
El diseño del formulario debe quedar similar al gráfico 3.12:
Luis Dueñas Pag 202
La Biblia de Visual Basic .NET
Gráfico 3.12: Diseño del formulario Consulta Empleado
Ingresar al editor de código y escribir el siguiente código.
Imports [Link] 'SqlConnection, SqlCommand, SqlDataReader
Imports [Link] 'File
Public Class frmConsultaEmpleado
Dim Curriculum() As Byte
Private Sub ValidarDigitos(ByVal sender As Object, _
ByVal e As [Link]) _
Handles [Link]
[Link] = Not ([Link]([Link]) Or _
[Link] = [Link])
End Sub
Private Sub HabilitarBoton(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link] = ([Link] <> "")
End Sub
Private Sub ConsultarEmpleado(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
Using con As New SqlConnection _
("uid=sa;pwd=123456;data source=Lduenas\MCTS;
initial catalog=Northwind")
Luis Dueñas Pag 203
La Biblia de Visual Basic .NET
[Link]()
Dim SQL As String = [Link] _
("Select LastName,FirstName,BirthDate,Photo From Employees
Where EmployeeID={0}", [Link])
Dim cmd As New SqlCommand(SQL, con)
Dim drd As SqlDataReader = _
[Link]([Link])
If drd IsNot Nothing Then
If [Link] Then
[Link]()
[Link] = [Link](0)
[Link] = [Link](1)
[Link] = If([Link](2), "", _
[Link](2).ToString("d"))
Dim Foto() As Byte = If([Link](3), Nothing, _
[Link](3))
If Foto IsNot Nothing AndAlso [Link] > 0 Then
Dim ms As New MemoryStream(Foto)
Try
[Link] = [Link](ms)
Catch ex As Exception
[Link] = Nothing
End Try
Else
[Link] = Nothing
End If
Else
[Link]()
[Link]()
[Link]()
[Link] = Nothing
[Link]("Código No existe")
End If
End If
End Using
End Sub
End Class
Nota: En el código anterior Si es necesario controlar los nulos ya que los
campos Fecha de Nacimiento (BirthDate) y Foto (Photo) del Empleado
Luis Dueñas Pag 204
La Biblia de Visual Basic .NET
soportan nulos y se pueden caer si se muestra en el TextBox y el
PictureBox y no tienen valores. Para controlar los nulos se esta usando el
método IsDbNull del DataReader.
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 3.13: Ejecución del formulario Consulta Empleado
Luis Dueñas Pag 205
La Biblia de Visual Basic .NET
Ejecutar comandos de Selección que devuelvan varias filas
Para ejecutar un comando o instrucción SQL Select que devuelve varios
registros o filas, se usa el método ExecuteReader de la clase SqlCommand
seguido del parámetro [Link].
A continuación un ejemplo que devuelve el apellido, nombre, fecha de
nacimiento y la foto del empleado ingresando su código.
Demo 33
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo33.
Cambiar de nombre al formulario de [Link] a frmProductosx
[Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmProductosxProveedor
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 350,300
StartPosition CenterScreen
Text Consulta de Productos x
Proveedor
ImageList1 Name ilsProveedor
Images Agregar 4 imágenes
SplitContainer1 Name scConsulta
Dock Fill
TreeView1 Name tvwProveedor
(izquierda) Dock Fill
ListView1 Name lvwProducto
(derecha) Dock Fill
FullRowSelect True
GridLines True
HotTracking True
Luis Dueñas Pag 206
La Biblia de Visual Basic .NET
El diseño del formulario debe quedar similar al gráfico 3.14:
Gráfico 3.14: Diseño del formulario Consulta de Productos x
Proveedor
Ingresar al editor de código y escribir el siguiente código.
Imports [Link] 'SqlConnection, SqlCommand, SqlDataReader
Public Class frmProductosxProveedor
Private strConexion As String = _
"uid=sa;pwd=123456;data source=Lduenas\MCTS;initial
catalog=Northwind"
Private Sub ListarProveedores(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
'Configurar el TreeView
Dim nodoRaiz As TreeNode = _
[Link]("P", "Proveedor", 0, 1)
Using con As New SqlConnection(strConexion)
[Link]()
Dim cmd As New SqlCommand _
("Select SupplierID,CompanyName From Suppliers Order By 2", con)
Dim drd As SqlDataReader = _
[Link]([Link])
If drd IsNot Nothing Then
Luis Dueñas Pag 207
La Biblia de Visual Basic .NET
Dim pos_Codigo As Integer = [Link]("SupplierID")
Dim pos_Nombre As Integer = [Link]("CompanyName")
Do While [Link]
[Link](drd.GetInt32(pos_Codigo).ToString, _
[Link](pos_Nombre), 2, 3)
Loop
End If
End Using
'Configurar el ListView
With lvwProducto
.[Link]("Codigo", 60, [Link])
.[Link]("Nombre", 200, [Link])
.[Link]("Precio", 60, [Link])
.[Link]("Stock", 60, [Link])
.View = [Link]
End With
End Sub
Private Sub ListarProductosxProveedor(ByVal sender As [Link], _
ByVal e As [Link]) _
Handles [Link]
[Link]()
If [Link] = 1 Then
Using con As New SqlConnection(strConexion)
[Link]()
Dim SQL As String = [Link] _
("Select ProductID,ProductName,IsNull(UnitPrice,0) As
Precio,IsNull(UnitsInStock,0) As Stock From Products Where
SupplierID={0} Order By 1", [Link])
Dim cmd As New SqlCommand(SQL, con)
Dim drd As SqlDataReader = _
[Link]([Link])
If drd IsNot Nothing Then
Dim Fila As ListViewItem
Do While [Link]
Fila = [Link](drd.GetInt32(0))
[Link]([Link](1))
[Link]([Link](2).ToString("n2"))
[Link](drd.GetInt16(3))
Loop
Luis Dueñas Pag 208
La Biblia de Visual Basic .NET
[Link]()
End If
End Using
End If
End Sub
End Class
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 3.15: Ejecución del formulario Consulta de Productos x
Proveedor
Luis Dueñas Pag 209
La Biblia de Visual Basic .NET
Ejecutar comandos de Selección que devuelvan varios conjuntos
de filas
Muchas veces es necesario cargar varias tablas en una aplicación, y
tradicionalmente ejecutamos varios comandos o instrucciones SQL para
realizar este cometido, sin embargo, con un solo comando con varios Select
o un procedimiento almacenado que tenga varios Select se puede realizar
lo mismo.
Para ejecutar un comando o instrucción SQL Select que devuelve varios
conjuntos de registros o filas, se usa el método ExecuteReader de la clase
SqlCommand sin parámetros, por defecto se obtiene el primer Select, para
obtener el siguiente conjunto de registros se usa el método NextResult del
DataReader.
A continuación un ejemplo que consulta 5 tablas de la base de datos
Northwind: Productos, Empleados, Clientes, Proveedores y Categorias
usando un solo comando y un solo DataReader (fila).
Demo 34
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo34.
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmConsultaTablas
Size 400,300
Text Consulta de Tablas
WindowState Maximized
TabControl1 Name tabConsulta
Dock Fill
TabPage1 Productos
TabPage2 Empleados
TabPage3 Clientes
Luis Dueñas Pag 210
La Biblia de Visual Basic .NET
TabPage4 Proveedores
TabPage5 Categorias
DataGridView1 Container TabPage1
Name dgvProducto
Dock Fill
ReadOnly True
SelectionMode FullRowSelect
DataGridView2 Container TabPage2
Name dgvEmpleado
Dock Fill
ReadOnly True
SelectionMode FullRowSelect
DataGridView3 Container TabPage3
Name dgvCliente
Dock Fill
ReadOnly True
SelectionMode FullRowSelect
DataGridView4 Container TabPage4
Name dgvProveedor
Dock Fill
ReadOnly True
SelectionMode FullRowSelect
DataGridView5 Container TabPage5
Name dgvCategoria
Dock Fill
ReadOnly True
SelectionMode FullRowSelect
El diseño del formulario debe quedar similar al gráfico 3.16:
Luis Dueñas Pag 211
La Biblia de Visual Basic .NET
Gráfico 3.16: Diseño del formulario Consulta de Tablas
Ingresar al editor de código y escribir el siguiente código.
Imports [Link] 'SqlConnection, SqlCommand, SqlDataReader
Public Class frmConsultaTablas
Private Sub CargarDatos(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim bs1 As New BindingSource
Dim bs2 As New BindingSource
Dim bs3 As New BindingSource
Dim bs4 As New BindingSource
Dim bs5 As New BindingSource
Using con As New SqlConnection _
("uid=sa;pwd=123456;data source=Lduenas\MCTS;initial
catalog=Northwind")
[Link]()
Dim cmd As New SqlCommand("Select * From Products;
Select * From Employees; Select * From Customers;
Select * From Suppliers; Select * From Categories", con)
Dim drd As SqlDataReader = [Link]
[Link] = drd
[Link]()
[Link] = drd
[Link]()
Luis Dueñas Pag 212
La Biblia de Visual Basic .NET
[Link] = drd
[Link]()
[Link] = drd
[Link]()
[Link] = drd
[Link]()
End Using
[Link] = bs1
[Link] = bs2
[Link] = bs3
[Link] = bs4
[Link] = bs5
End Sub
End Class
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 3.17: Ejecución del formulario Consulta de Tablas
Luis Dueñas Pag 213
La Biblia de Visual Basic .NET
1.4. Realizando un Mantenimiento Conectado
En esta tercera parte aprenderemos como ejecutar comandos que inserten,
actualizen y eliminen datos mediante el método ExecuteNonQuery de la
clase Command. Este método devuelve un número que indica la cantidad
de registros afectados.
A continuación, crearemos un mantenimiento de la tabla Empleados, es
decir veremos como adicionar, actualizar y eliminar registros en dicha
tabla.
Demo 35
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo35.
Cambiar de nombre al formulario de [Link] a frmMantenimiento
[Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmMantenimientoEmpleado
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 400,400
StartPosition CenterScreen
Text Mantenimiento de Empleados
Conectado
Label1 Name lblCodigo
AutoSize True
Location 26, 33
Text Código:
TextBox1 Name txtCodigo
Location 100,26
ReadOnly True
Size 47,20
Luis Dueñas Pag 214
La Biblia de Visual Basic .NET
Label2 Name lblApellido
AutoSize True
Location 26, 59
Text Apellido:
TextBox2 Name txtApellido
Location 100,52
Size 178,20
Label3 Name lblNombre
AutoSize True
Location 26, 85
Text Nombre:
TextBox3 Name txtNombre
Location 100,78
Size 178,20
Label4 Name lblFechaNac
AutoSize True
Location 26, 111
Text Fecha Nac:
DateTimePicker1 Name dtpFechaNac
Format Short
Location 100,105
Size 88,20
Button1 Name btnNuevo
Cursor Hand
Location 297, 22
Size 75, 23
Text Nuevo
Button2 Name btnAdicionar
Cursor Hand
Location 297, 22
Size 75, 50
Text Adicionar
Button3 Name btnActualizar
Cursor Hand
Location 297, 78
Size 75, 23
Text Actualizar
Button4 Name btnEliminar
Cursor Hand
Location 297, 106
Size 75, 23
Text Eliminar
Luis Dueñas Pag 215
La Biblia de Visual Basic .NET
DataGridView1 Name dgvEmpleado
Location 13, 151
MultiSelect False
ReadOnly True
SelectionMode FullRowSelect
Size 367, 210
El diseño del formulario debe quedar similar al gráfico 3.18:
Gráfico 3.18: Diseño del formulario Mantenimiento de Empleados
Ingresar al editor de código y escribir el siguiente código.
Imports [Link] 'SqlConnection, SqlCommand, SqlDataReader
Imports [Link].Drawing2D 'LinearGradientBrush
Public Class frmMantenimientoEmpleado
Private strConexion As String = _
"uid=sa;pwd=123456;data source=Lduenas\MCTS;
initial catalog=Northwind"
Private bs As New BindingSource
Private N As Integer
Luis Dueñas Pag 216
La Biblia de Visual Basic .NET
Private Sub DibujarRecuadro(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
Dim recData As New Rectangle(15, 10, 270, 130)
Dim degData As New LinearGradientBrush _
(recData, [Link], [Link], _
[Link])
[Link](degData, recData)
Dim recBoton As New Rectangle(290, 10, 90, 130)
Dim degBoton As New LinearGradientBrush _
(recBoton, [Link], [Link], _
[Link])
[Link](degBoton, recBoton)
End Sub
Private Sub PersonalizarGrilla()
[Link](0).HeaderText = "ID"
[Link](0).Width = 40
[Link](1).HeaderText = "Apellido"
[Link](1).Width = 80
[Link](2).HeaderText = "Nombre"
[Link](2).Width = 80
[Link](3).HeaderText = "Fecha Nac"
[Link](3).Width = 100
End Sub
Private Sub ListarEmpleados(ByVal con As SqlConnection)
Dim cmd As New SqlCommand _
("Select EmployeeID,LastName,FirstName,BirthDate From Employees
Order By 1", con)
Dim drd As SqlDataReader = _
[Link]([Link])
[Link] = drd
[Link] = bs
[Link]()
End Sub
Private Sub CargarDatos(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Using con As New SqlConnection(strConexion)
Try
Luis Dueñas Pag 217
La Biblia de Visual Basic .NET
[Link]()
ListarEmpleados(con)
Catch ex As SqlException
[Link]("No se pudo conectar a la BD")
Catch ex As Exception
[Link]([Link])
End Try
End Using
PersonalizarGrilla()
End Sub
Private Sub MostrarDatos(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
With [Link]
[Link] = .Cells(0).Value
[Link] = .Cells(1).Value
[Link] = .Cells(2).Value
[Link] = .Cells(3).Value
End With
End Sub
Private Sub Nuevo(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link]()
[Link]()
[Link]()
[Link] = Now
End Sub
Private Sub AdicionarEmpleado(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If [Link] <> "" Then
If [Link] <> "" Then
Dim Diferencia As TimeSpan = _
[Link]([Link])
If [Link] > 0 Then
Using con As New SqlConnection(strConexion)
Try
[Link]()
Dim cmd As New SqlCommand _
Luis Dueñas Pag 218
La Biblia de Visual Basic .NET
("Insert Into Employees(LastName,FirstName,BirthDate)
Values(@Apellido,@Nombre,@FechaNac)", con)
[Link]("@Apellido", [Link],
20).Value = [Link]
[Link]("@Nombre", [Link],
10).Value = [Link]
[Link]("@FechaNac",
[Link]).Value = [Link]
N = [Link]
ListarEmpleados(con)
[Link] = [Link] - 1
If N > 0 Then
[Link]("Empleado Adicionado", "Aviso", _
[Link], [Link])
Else
[Link]("Empleado No se pudo Adicionar",
"Error", [Link], [Link])
End If
Catch ex As SqlException
[Link]("No se pudo realizar la operación")
Catch ex As Exception
[Link]([Link])
End Try
End Using
Else
[Link]("La Fecha de Nacimiento debe ser menor a hoy")
[Link]()
End If
Else
[Link]("Falta ingresar el Nombre", "Aviso", _
[Link], [Link])
[Link]()
End If
Else
[Link]("Falta ingresar el Apellido", "Aviso", _
[Link], [Link])
[Link]()
End If
End Sub
Luis Dueñas Pag 219
La Biblia de Visual Basic .NET
Private Sub ActualizarEmpleado(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If [Link] <> "" Then
If [Link] <> "" Then
Dim Diferencia As TimeSpan = _
[Link]([Link])
If [Link] > 0 Then
Using con As New SqlConnection(strConexion)
Try
[Link]()
Dim cmd As New SqlCommand("Update Employees Set
LastName=@Apellido,FirstName=@Nombre,BirthDate=
@FechaNac Where EmployeeID=@Codigo", con)
[Link]("@Codigo", [Link]).Value =
[Link]([Link])
[Link]("@Apellido", [Link],
20).Value = [Link]
[Link]("@Nombre", [Link],
10).Value = [Link]
[Link]("@FechaNac",
[Link]).Value = [Link]
N = [Link]
ListarEmpleados(con)
If N > 0 Then
[Link]("Empleado Actualizado", "Aviso", _
[Link], [Link])
Else
[Link]("Empleado No se pudo Actualizar
porque fue eliminado", _
"Error", [Link], [Link])
End If
Catch ex As SqlException
[Link]("No se pudo realizar la operación")
Catch ex As Exception
[Link]([Link])
End Try
End Using
Else
[Link]("La Fecha de Nacimiento debe ser menor a hoy")
[Link]()
Luis Dueñas Pag 220
La Biblia de Visual Basic .NET
End If
Else
[Link]("Falta ingresar el Nombre", "Aviso", _
[Link], [Link])
[Link]()
End If
Else
[Link]("Falta ingresar el Apellido", "Aviso", _
[Link], [Link])
[Link]()
End If
End Sub
Private Sub EliminarEmpleado(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If [Link] <> "" Then
If [Link]("Estas seguro de eliminarlo", "Aviso", _
[Link], [Link]) = _
[Link] Then
Using con As New SqlConnection(strConexion)
Try
[Link]()
Dim cmd As New SqlCommand("Delete From Employees
Where EmployeeID=@Codigo", con)
[Link]("@Codigo", [Link]).Value = _
[Link]([Link])
N = [Link]
ListarEmpleados(con)
If N > 0 Then
[Link]("Empleado Eliminado", "Aviso", _
[Link], [Link])
Else
[Link]("Empleado No se pudo Eliminar", _
"Error", [Link], [Link])
End If
Catch ex As SqlException
[Link]("No se pudo realizar la operación")
Catch ex As Exception
[Link]([Link])
End Try
Luis Dueñas Pag 221
La Biblia de Visual Basic .NET
End Using
End If
Else
[Link]("Falta seleccionar el Empleado", "Aviso", _
[Link], [Link])
End If
End Sub
End Class
Nota: En el código anterior en vez de usar 2 contenedores para agrupar
los datos del empleado y los botones como por ejemplo los controles
GroupBox o panel se ha dibujado ambos rectángulos con un degradado.
Importante: En cuanto a rendimiento es mejor dibujar un rectángulo que
usar un contenedor.
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 3.19: Ejecución del formulario Mantenimiento de
Empleados Conectado
Luis Dueñas Pag 222
La Biblia de Visual Basic .NET
2. Trabajando en Forma Desconectada con DataSet
El DataSet es una representación en memoria de los datos el cual consta
de tablas y relaciones, tal como se muestra en la siguiente figura.
Gráfico 3.20: Modelo de objetos del DataSet
En esta parte veremos como trabajar en forma desconectada usando el
DataSet. Primero debemos entender porqué y cuando trabajar en forma
desconectada y luego como crear un DataSet, con tablas, relaciones y
vistas para manejar los datos.
No siempre debemos ejecutar todas las consultas en línea contra la base
de datos ya que si existen muchos usuarios y si la red presenta problemas
de ancho de banda la consulta demoraría demasiado sobre todo para
Internet.
Si la data que deseamos consultar no es demasiada y no cambia
constantemente, es preferible trabajar en forma desconectada, es decir,
realizar las consultas localmente, puede ser en un DataSet o en una Lista
de Objetos.
Por ejemplo para consultar los datos de los empleados, clientes o
proveedores no es común que estos datos cambien a cada momento,
Luis Dueñas Pag 223
La Biblia de Visual Basic .NET
también si consultamos el ubigeo o departamento, provincia y distrito, no
es necesario al seleccionar un departamento ir a la base de datos para
traer las provincias ni tampoco al elegir la provincia ir a la base de datos
para traer los distritos, sino que podemos cargar las 3 tablas en memoria y
hacer las consultas locales ya que dicha data cambia después de tiempo.
Para más información sobre el DataSet ver la referencia 21 al final del libro.
A continuación veremos como trabajar en forma desconectada usando
DataSet y en el siguiente tema lo haremos con listas de objetos.
2.1. Trabajando con Tablas y Relaciones
Un DataSet tiene como elementos tablas (DataTables) y relaciones (Data
Relations). Las tablas son los repositorios de datos y las relaciones los
vínculos entre ellas. Una tabla de un DataSet se puede crear en forma
independiente o se puede crear a partir de una base de datos.
El DataSet puede tener varias tablas de diferentes bases de datos e
inclusive pueden estar relacionadas entre ellas para favorecer la integridad
de los datos, además una tabla puede tener varias relaciones.
A continuación presentamos un ejemplo que lista las ordenes de un cliente
en forma desconectada usando tablas relacionadas y creando vistas para
cada fila de la tabla padre.
Demo 36
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo36.
Cambiar de nombre al formulario de [Link] a frmConsultaOrdenes
[Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Luis Dueñas Pag 224
La Biblia de Visual Basic .NET
Objeto Propiedad Valor
Form1 Name frmConsultaOrdenesCliente
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 580,400
StartPosition CenterScreen
Text Consulta de Ordenes x Cliente
DataGridView1 Name dgvCliente
AutoSizeColumnsM AllCells
Location 3, 3
MultiSelect False
ReadOnly True
SelectionMode FullRowSelect
Size 566, 180
DataGridView1 Name dgvOrden
AutoSizeColumnsM AllCells
Location 3, 189
MultiSelect False
ReadOnly True
SelectionMode FullRowSelect
Size 566, 180
El diseño del formulario debe quedar similar al gráfico 3.21:
Luis Dueñas Pag 225
La Biblia de Visual Basic .NET
Gráfico 3.21: Diseño del formulario Consulta de Ordenes x Cliente
Ingresar al editor de código y escribir el siguiente código.
Imports [Link] 'DataSet, DataRelation
Imports [Link] 'SqlConnection, SqlDataAdapter
Public Class frmConsultaOrdenesCliente
'Definir el Repositorio para las 2 tablas
Private dst As New DataSet
Private Sub ListarOrdenesCliente(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Using con As New SqlConnection("uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind")
'Abrir la conexión a SQL Server
[Link]()
'Definir la intruccion SQL a ejecutar
Dim dap As New SqlDataAdapter("Select CustomerId,CompanyName,
Address From Customers;Select OrderID,CustomerID,OrderDate From
Orders", con)
'Ejecutar la instruccion SQL y crear 2 tablas
[Link](dst)
'Definir una relacion entre las 2 tablas
Dim drn As New DataRelation("Relacion", _
Luis Dueñas Pag 226
La Biblia de Visual Basic .NET
[Link](0).Columns(0), [Link](1).Columns(1))
'Agregar la relacion al DataSet
[Link](drn)
End Using
'Enlazar la grilla a la tabla de Clientes
[Link] = [Link](0)
End Sub
Private Sub FiltrarOrdenesxCliente(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
'Filtrar Ordenes creando una vista de las filas relacionadas
[Link] = [Link](0).DefaultView _
([Link]).CreateChildView("Relacion")
End Sub
End Class
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 3.22: Ejecución del formulario Consulta de Ordenes x
Cliente
Luis Dueñas Pag 227
La Biblia de Visual Basic .NET
2.2. Trabajando con Vistas
Las vistas son cursores de solo lectura obtenidos a partir de una tabla y se
usan para filtrar, ordenar y buscar registros, entre otros usos. La clase
.NET que representa a una vista es el DataView y solo se puede crear una
vista mediante la propiedad DefaultView de una tabla.
Filtrar Registros
Esta operación consiste en seleccionar solo los registros que cumplan una
condición o filtro de selección y se realiza mediante la propiedad RowFilter
de la clase DataView.
Una vez aplicado el filtro, si deseamos obtener nuevamente toda la data, es
decir quitar el filtro aplicado, solo basta configurar la propiedad RowFilter
en una cadena vacia.
A continuación presentamos un ejemplo que permite filtrar los productos
por código o por nombre del producto, si no se escribe nada se muestran
todos los productos.
Demo 37
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo37.
Cambiar de nombre al formulario de [Link] a frmConsulta
[Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmConsultaProducto
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Luis Dueñas Pag 228
La Biblia de Visual Basic .NET
Size 400,400
StartPosition CenterScreen
Text Consulta de Productos
Label1 Name lblTitulo
AutoSize True
Location 23, 14
Text Filtrar Por:
RadioButton1 Name rbCodigo
AutoSize True
Location 23, 38
Text Codigo
TextBox1 Name txtCodigo
Location 87, 37
ReadOnly True
Size 58, 20
RadioButton2 Name rbNombre
AutoSize True
Location 23, 64
Text Nombre
TextBox2 Name txtNombre
Location 87, 63
ReadOnly True
Size 262, 20
DataGridView1 Name dgvProducto
AutoSizeColumnsM AllCells
Location 1, 106
ReadOnly True
SelectionMode FullRowSelect
Size 392, 261
El diseño del formulario debe quedar similar al gráfico 3.23:
Luis Dueñas Pag 229
La Biblia de Visual Basic .NET
Gráfico 3.23: Diseño del formulario Consulta de Productos
Ingresar al editor de código y escribir el siguiente código.
Imports [Link] 'DataSet, DataView
Imports [Link] 'SqlConnection, SqlDataAdapter
Imports [Link].Drawing2D 'LinearGradientBrush
Public Class frmConsultaProducto
Private dv As DataView 'Vista de Productos
Private Sub DibujarRecuadro(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
Dim recData As New Rectangle(10, 10, 370, 90)
Dim degData As New LinearGradientBrush _
(recData, [Link], [Link], _
[Link])
[Link](degData, recData)
End Sub
Private Sub ListarProductos(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim dst As New DataSet
Luis Dueñas Pag 230
La Biblia de Visual Basic .NET
Using con As New SqlConnection("uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind")
[Link]()
Dim dap As New SqlDataAdapter _
("Select ProductID,ProductName,UnitPrice From Products", con)
[Link](dst, "Productos")
End Using
dv = [Link](0).DefaultView
[Link] = dv
End Sub
Private Sub HabilitarCodigo(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If [Link] Then
[Link] = False
[Link] = True
[Link]()
End If
End Sub
Private Sub HabilitarNombre(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
If [Link] Then
[Link] = True
[Link] = False
[Link]()
End If
End Sub
Private Sub FiltrarPorCodigo(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If [Link] <> "" Then
[Link] = [Link] _
("ProductID={0}", [Link])
Else
[Link] = ""
End If
End Sub
Private Sub FiltrarPorNombre(ByVal sender As [Link], _
Luis Dueñas Pag 231
La Biblia de Visual Basic .NET
ByVal e As [Link]) Handles [Link]
If [Link] <> "" Then
[Link] = [Link] _
("ProductName Like '%{0}%'", [Link])
Else
[Link] = ""
End If
End Sub
End Class
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 3.24: Ejecución del formulario Consulta de Productos
Luis Dueñas Pag 232
La Biblia de Visual Basic .NET
Ordenar y Buscar Registros
Si la data que queremos consultar es demasiada mejor seria filtrar los
registros, pero si la data no es mucha, entonces, podemos ubicarnos sobre
el registro buscado.
Para buscar registros se usa el método Find de la clase DataView, pero
necesita que la data esté ordenada por una o más columnas y esto se
realiza con la propiedad Sort del DataView.
Advertencia: Si se llama al método Find del DataView sin antes haber
ordenado la data usando la propiedad Sort del DataView se generará una
excepción o error en tiempo de ejecución.
Demo 38
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo38.
Cambiar de nombre al formulario de [Link] a frmConsulta
[Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmConsultaProducto
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 400,400
StartPosition CenterScreen
Text Consulta de Productos
Label1 Name lblTitulo
AutoSize True
Location 23, 14
Text Buscar Por:
RadioButton1 Name rbCodigo
AutoSize True
Luis Dueñas Pag 233
La Biblia de Visual Basic .NET
Location 23, 38
Text Codigo
TextBox1 Name txtCodigo
Location 87, 37
ReadOnly True
Size 58, 20
RadioButton2 Name rbNombre
AutoSize True
Location 23, 64
Text Nombre
TextBox2 Name txtNombre
Location 87, 63
ReadOnly True
Size 262, 20
DataGridView1 Name dgvProducto
AutoSizeColumnsM AllCells
Location 1, 106
ReadOnly True
SelectionMode FullRowSelect
Size 392, 261
El diseño del formulario debe quedar similar al gráfico 3.25:
Luis Dueñas Pag 234
La Biblia de Visual Basic .NET
Gráfico 3.25: Diseño del formulario Consulta de Productos
Ingresar al editor de código y escribir el siguiente código.
Imports [Link] 'DataSet, DataView
Imports [Link] 'SqlConnection, SqlDataAdapter
Imports [Link].Drawing2D 'LinearGradientBrush
Public Class frmConsultaProducto
Private dv As DataView 'Vista de Productos
Private bs As New BindingSource
Private Sub DibujarRecuadro(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
Dim recData As New Rectangle(10, 10, 370, 90)
Dim degData As New LinearGradientBrush _
(recData, [Link], [Link], _
[Link])
[Link](degData, recData)
End Sub
Private Sub QuitarOrdenDataGridView()
Luis Dueñas Pag 235
La Biblia de Visual Basic .NET
Dim I As Integer
For I = 0 To [Link] - 1
[Link](I).SortMode = _
[Link]
Next
End Sub
Private Sub ListarProductos(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim dst As New DataSet
Using con As New SqlConnection("uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind")
[Link]()
Dim dap As New SqlDataAdapter _
("Select ProductID,ProductName,UnitPrice From Products", con)
[Link](dst, "Productos")
End Using
dv = [Link](0).DefaultView
[Link] = dv
[Link] = bs
QuitarOrdenDataGridView()
End Sub
Private Sub HabilitarCodigo(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If [Link] Then
[Link] = "ProductID"
[Link] = False
[Link] = True
[Link]()
End If
End Sub
Private Sub HabilitarNombre(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
If [Link] Then
[Link] = "ProductName"
[Link] = True
[Link] = False
[Link]()
Luis Dueñas Pag 236
La Biblia de Visual Basic .NET
End If
End Sub
Private Sub BuscarPorCodigo(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If [Link] <> "" Then
Dim pos As Integer = [Link]([Link])
If pos > -1 Then
[Link] = pos
End If
End If
End Sub
Private Sub BuscarPorNombre(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If [Link] <> "" Then
Dim Criterio As String = [Link] _
("ProductName Like '{0}%'", [Link])
Dim dr() As DataRow = [Link](Criterio)
If [Link] > 0 Then
Dim pos As Integer = [Link](dr(0)(1))
If pos > -1 Then [Link] = pos
End If
End If
End Sub
End Class
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 237
La Biblia de Visual Basic .NET
Gráfico 3.26: Ejecución del formulario Consulta de Productos
Luis Dueñas Pag 238
La Biblia de Visual Basic .NET
2.3. Mantenimiento Desconectado con DataSet
En esta parte veremos como realizar modificaciones a las tablas del
DataSet: adicionar, actualizar y eliminar registros; y luego como enviar
dichos cambios realizados de regreso a la base de datos.
Para adicionar un registro primero se toma la estructura de un registro de
la tabla y se crea una fila usando el método NewRow del DataTable, luego
se llena de datos la fila y se agrega este objeto a la colección de filas
(Rows) del DataTable.
Para actualizar un registro se obtiene el registro actual y se modifican los
datos directamente.
Para eliminar un registro existen 2 formas: usar el método Remove del
DataTable o el método Delete del DataRow, la diferencia es que el Remove
marca el registro pero no lo borra de la tabla para después enviar dicha
eliminación a la base de datos; en cambio, el Delete lo elimina de la tabla y
ya no se puede enviar la eliminación a la base de datos.
Para obtener los cambios que se vienen realizando en un DataSet o un
DataTable se usa el método GetChanges que por defecto obtienene los
registros modificados y adicionados a la(s) tabla(s). Este tiene un
parámetro que indica que tipo de cambios puedes visualizar.
Finalmente, para enviar los cambios realizados: adiciones, actualizaciones y
eliminaciones a la(s) tabla(s) se usa el método Update del DataAdapter,
pero debe haberse configurado las propiedades: InsertCommand,
UpdateCommand y DeleteCommand del DataAdapter con la instrucción
SQL a ejecutar y con los parámetros respectivos para cada instrucción.
Advertencia: Si se llama al método Update del DataAdapter sin existir los
Insert, Update y Select respectivos se generará una excepción o error en
tiempo de ejecución.
Nota: Existe una forma de crear automáticamente los InsertCommand,
UpdateCommand y DeleteCommand del DataAdapter basados en su
SelectCommmand, usando para ello la clase CommandBuilder y pasando
como parámetro en el constructor el DataAdapter.
Luis Dueñas Pag 239
La Biblia de Visual Basic .NET
A continuación veremos un ejemplo donde apliquemos todo lo comentado
para realizar un mantenimiento desconectado sobre la tabla empleados y
donde podamos enviar los cambios por lotes hacia la base de datos.
Demo 39
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo39.
Cambiar de nombre al formulario de [Link] a frmMantenimiento
[Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmMantenimientoEmpleado
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 400,430
StartPosition CenterScreen
Text Mantenimiento de Empleados
Desconectado
Label1 Name lblCodigo
AutoSize True
Location 26, 33
Text Código:
TextBox1 Name txtCodigo
Location 100,26
ReadOnly True
Size 47,20
Label2 Name lblApellido
AutoSize True
Location 26, 59
Text Apellido:
TextBox2 Name txtApellido
Location 100,52
Size 178,20
Label3 Name lblNombre
Luis Dueñas Pag 240
La Biblia de Visual Basic .NET
AutoSize True
Location 26, 85
Text Nombre:
TextBox3 Name txtNombre
Location 100,78
Size 178,20
Label4 Name lblFechaNac
AutoSize True
Location 26, 111
Text Fecha Nac:
DateTimePicker1 Name dtpFechaNac
Format Short
Location 100,105
Size 88,20
Button1 Name btnNuevo
Cursor Hand
Location 297, 22
Size 75, 23
Text Nuevo
Button2 Name btnAdicionar
Cursor Hand
Location 297, 22
Size 75, 50
Text Adicionar
Button3 Name btnActualizar
Cursor Hand
Location 297, 78
Size 75, 23
Text Actualizar
Button4 Name btnEliminar
Cursor Hand
Location 297, 106
Size 75, 23
Text Eliminar
DataGridView1 Name dgvEmpleado
Location 13, 151
MultiSelect False
ReadOnly True
SelectionMode FullRowSelect
Size 367, 210
Button5 Name btnVerCambios
Cursor Hand
Luis Dueñas Pag 241
La Biblia de Visual Basic .NET
Location 12, 369
Size 100, 23
Text Ver Cambios
Button6 Name btnGrabarCambios
Cursor Hand
Location 280, 369
Size 100, 23
Text Grabar Cambios
El diseño del formulario debe quedar similar al gráfico 3.27:
Gráfico 3.27: Diseño del formulario Mantenimiento de Empleados
Desconectado
Ingresar al editor de código y escribir el siguiente código.
Imports [Link] 'DataSet, DataTable
Imports [Link] 'SqlConnection, SqlDataAdapter,
SqlCommandBuilder
Imports [Link].Drawing2D 'LinearGradientBrush
Luis Dueñas Pag 242
La Biblia de Visual Basic .NET
Public Class frmMantenimientoEmpleado
Private strConexion As String = _
"uid=sa;pwd=123456;data source=Lduenas\MCTS;initial
catalog=Northwind"
Private dtb As New DataTable
Private con As SqlConnection
Private dap As New SqlDataAdapter _
("Select EmployeeID,LastName,FirstName,BirthDate From Employees", con)
Private bs As New BindingSource
Private Sub DibujarRecuadro(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
Dim recData As New Rectangle(15, 10, 270, 130)
Dim degData As New LinearGradientBrush _
(recData, [Link], [Link], _
[Link])
[Link](degData, recData)
Dim recBoton As New Rectangle(290, 10, 90, 130)
Dim degBoton As New LinearGradientBrush _
(recBoton, [Link], [Link], _
[Link])
[Link](degBoton, recBoton)
End Sub
Private Sub QuitarOrdenDataGridView()
Dim I As Integer
For I = 0 To [Link] - 1
[Link](I).SortMode = _
[Link]
Next
End Sub
Private Sub PersonalizarGrilla()
[Link](0).HeaderText = "ID"
[Link](0).Width = 40
[Link](1).HeaderText = "Apellido"
[Link](1).Width = 80
[Link](2).HeaderText = "Nombre"
[Link](2).Width = 80
[Link](3).HeaderText = "Fecha Nac"
Luis Dueñas Pag 243
La Biblia de Visual Basic .NET
[Link](3).Width = 100
QuitarOrdenDataGridView()
End Sub
Private Sub ListarEmpleados()
If [Link] > 0 Then [Link]()
[Link] = con
[Link](dtb)
[Link] = dtb
[Link] = bs
PersonalizarGrilla()
End Sub
Private Sub CargarDatos(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
con = New SqlConnection(strConexion)
[Link]()
ListarEmpleados()
Dim sbd As New SqlCommandBuilder(dap)
[Link]()
End Sub
Private Sub MostrarDatos(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
With [Link]
[Link] = .Cells(0).Value
[Link] = .Cells(1).Value
[Link] = .Cells(2).Value
[Link] = .Cells(3).Value
End With
End Sub
Private Sub Nuevo(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link] = [Link]([Link] - 1)(0) + 1
[Link]()
[Link]()
[Link] = Now
[Link]()
End Sub
Luis Dueñas Pag 244
La Biblia de Visual Basic .NET
Private Sub AdicionarEmpleado(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If [Link] <> "" Then
If [Link] <> "" Then
Dim Diferencia As TimeSpan = _
[Link]([Link])
If [Link] > 0 Then
Dim Fila As DataRow = [Link]
Fila(0) = [Link]
Fila(1) = [Link]
Fila(2) = [Link]
Fila(3) = [Link]
[Link](Fila)
[Link] = [Link] - 1
Else
[Link]("La Fecha de Nacimiento debe ser menor a
hoy")
[Link]()
End If
Else
[Link]("Falta ingresar el Nombre", "Aviso", _
[Link], [Link])
[Link]()
End If
Else
[Link]("Falta ingresar el Apellido", "Aviso", _
[Link], [Link])
[Link]()
End If
End Sub
Private Sub ActualizarEmpleado(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If [Link] <> "" Then
If [Link] <> "" Then
Dim Diferencia As TimeSpan = _
[Link]([Link])
If [Link] > 0 Then
Dim N As Integer = _
Luis Dueñas Pag 245
La Biblia de Visual Basic .NET
[Link]
Dim Fila As DataRow = [Link](N)
[Link]()
Fila(0) = [Link]
Fila(1) = [Link]
Fila(2) = [Link]
Fila(3) = [Link]
[Link]()
Else
[Link]("La Fecha de Nacimiento debe ser menor a
hoy")
[Link]()
End If
Else
[Link]("Falta ingresar el Nombre", "Aviso", _
[Link], [Link])
[Link]()
End If
Else
[Link]("Falta ingresar el Apellido", "Aviso", _
[Link], [Link])
[Link]()
End If
End Sub
Private Sub EliminarEmpleado(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If [Link] <> "" Then
If [Link]("Estas seguro de eliminarlo", "Aviso", _
[Link], [Link]) = _
[Link] Then
Dim N As Integer = [Link]
[Link](N).Delete()
End If
Else
[Link]("Falta seleccionar el Empleado", "Aviso", _
[Link], [Link])
End If
End Sub
Luis Dueñas Pag 246
La Biblia de Visual Basic .NET
Private Sub CerrarGrilla(ByVal sender As Object, ByVal e As EventArgs)
[Link]()
End Sub
Private Sub VerCambios(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim frm As New Form
[Link] = [Link]
[Link] = [Link]
Dim dgv As New DataGridView
[Link] = [Link]
[Link] = [Link]
[Link] = True
[Link] = False
[Link] = [Link]
AddHandler [Link], AddressOf CerrarGrilla
[Link](dgv)
[Link] = New Size(400, 200)
[Link]()
End Sub
Private Sub GrabarCambios(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Try
[Link]()
[Link] = 1
[Link](dtb)
ListarEmpleados()
[Link]("Operacion realizada con exito", _
"Aviso", [Link], [Link])
Catch ex As Exception
[Link]("No se pudo realizar laoperacion", _
"Aviso", [Link], [Link])
Finally
If [Link] = [Link] Then [Link]()
End Try
End Sub
End Class
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 247
La Biblia de Visual Basic .NET
Gráfico 3.28: Ejecución del formulario Mantenimiento de
Empleados Desconectado
Luis Dueñas Pag 248
La Biblia de Visual Basic .NET
3. Trabajando en Forma Desconectada con Listas de Objetos
Otra forma de trabajar desconectados es usando listas de objetos, sobre
todo si trabajamos con el Modelo de Desarrollo Distribuido (MDD) y usamos
entidades del negocio, es preferible usar lista de objetos al DataSet, ya que
se consume menos memoria debido a que el DataSet no solo tiene la data
de las tablas sino también su metadata o definición para cada elemento o
atributo.
En .NET Framework existe el espacio de nombres [Link].
Generics que permite trabajar con listas genéricas de objetos. En esta parte
aprenderemos como crear una lista de objetos, como filtrar datos de la
lista, como ordenar, buscar y finalmente como realizar un mantenimiento
con objetos.
3.1 Llenando una Lista de Objetos
Para trabajar con Listas de Objetos primero es necesario crear los
Procedimientos Almacenados, luego las diferentes Librerías de Clases
iniciando con las Entidades del Negocio, luego el Acceso a Datos y
después las Reglas del Negocio, finalmente se crea la aplicación que usa
las librerías de negocio: entidades y reglas.
Creando los Procedimientos Almacenados
Es preferible usar procedimientos almacenados de SQL Server en vez de
enviar desde la aplicación la instrucción SQL, ya que los procedimientos
almacenados se compilan en el servidor y se encuentran preparados para
su ejecución, lo que lo hace mas rápido.
Para crear los procedimientos almacenados podemos usar cualquier cliente
de SQL Server como el Microsoft SQL Server Management Studio si es que
se ha instalado el cliente de SQL Server 2005 o 2008, también podríamos
usar el Explorador de Servidores de Visual Studio 2010.
Crear los siguientes procedimientos almacenados:
Luis Dueñas Pag 249
La Biblia de Visual Basic .NET
1. Procedimiento almacenado que lista empleados
Create Procedure usp_Employees_Sel
AS
Select EmployeeID,LastName,FirstName,
IsNull(BirthDate,'') As BirthDate
From Employees
2. Procedimiento almacenado que lista productos
Create Procedure usp_Products_Sel
AS
SELECT
ProductID,
ProductName,
IsNull(SupplierID,0) As SupplierID,
IsNull(CategoryID,0) As CategoryID,
IsNull(UnitPrice,0) As UnitPrice,
IsNull(UnitsInStock,0) As UnitsInStock
FROM Products
ORDER BY 1
3. Procedimiento almacenado que lista categorias
Create Procedure usp_Categories_Sel
AS
Select CategoryID,CategoryName
From Categories Order By 2
4. Procedimiento Almacenado que lista proveedores
Create Procedure usp_Suppliers_Sel
AS
Select SupplierID,CompanyName
From Suppliers Order By 2
Nota: Para nombrar el procedimiento se ha usado el prefijo usp seguido
del Nombre de la tabla y como sufijo el tipo de operación SQL: sel indica
selección, ins indica inserción, upd indica actualización y del indica
eliminación. Para separar el prefijo, la tabla y el sufijo se usa _.
Luis Dueñas Pag 250
La Biblia de Visual Basic .NET
Creando la Librería de Entidades del Negocio
Después de crear los procedimientos almacenados hay que crear las clases
entidades del negocio que se obtienen de los datos que queremos manejar
de cada tabla.
Demo [Link]
Del menú “File”, seleccionar “New Project” y luego “Class Library”.
Escribir como nombre físico al proyecto: [Link].
Cambiar de nombre a la clase de [Link] a [Link].
Escribir el siguiente código para la clase beEmpleado:
Public Class beEmpleado
Public Property Codigo As Integer
Public Property Apellido As String
Public Property Nombre As String
Public Property FechaNac As DateTime
End Class
Nota: En la versión 2010 de Visual Basic ya se puede crear directamente
las propiedades sin necesidad de definir variables locales y los métodos Get
y Set para propiedades de lectura y escritura.
Agregar una nueva clase para Productos: del menú “Project”, “Add
Class” y escribir como nombre: beProducto.
Escribir el siguiente código para la clase beProducto:
Public Class beProducto
Public Property Codigo As Integer
Public Property Nombre As String
Public Property IdProveedor As Integer
Public Property IdCategoria As Integer
Public Property PrecioUnitario As Decimal
Public Property Stock As Short
End Class
Luis Dueñas Pag 251
La Biblia de Visual Basic .NET
Agregar una nueva clase para Categorias: del menú “Project”, “Add
Class” y escribir como nombre: beCategoria.
Escribir el siguiente código para la clase beCategoria:
Public Class beCategoria
Public Property Codigo As Integer
Public Property Nombre As String
End Class
Agregar una nueva clase para Proveedores: del menú “Project”, “Add
Class” y escribir como nombre: beProveedor.
Escribir el siguiente código para la clase beProveedor:
Public Class beProveedor
Public Property Codigo As Integer
Public Property Nombre As String
End Class
Finalmente, del menú “Build” seleccionar “Build [Link]
Entities” para crear la dll con las entidades del negocio.
Luis Dueñas Pag 252
La Biblia de Visual Basic .NET
Creando la Librería de Acceso a Datos
Después de crear la librería con las clases entidades se crea la librería de
acceso a datos que contiene los métodos que ejecutan los procedimientos
almacenados mediante comandos de ADO .NET y llenan la lista de objetos
para devolverlos a las reglas del negocio.
Para crear listas de objetos primero hay que hacer referencia a la librería
de entidades creada anteriormente.
Cada método de acceso a datos tiene como parámetro la clase Connection
para que abriendo una sola conexión desde la regla de negocio se pueda
llamar a varios métodos de los servicios de acceso a datos.
Demo [Link]
Del menú “File”, seleccionar “New Project” y luego “Class Library”.
Escribir como nombre físico al proyecto: [Link].
Hacer una referencia a la librería de entidades creada: seleccionar el
proyecto, clic derecho “Add References”, seleccionar ficha “Browse” y
buscar el archivo [Link] creado.
Cambiar de nombre a la clase de [Link] a [Link].
Escribir el siguiente código para la clase daEmpleado:
Imports [Link]
Imports [Link]
Public Class daEmpleado
Public Function fListar(ByVal con As SqlConnection) As List(Of beEmpleado)
Dim lobeEmpleado As New List(Of beEmpleado)
Dim cmd As New SqlCommand("usp_Employees_Sel", con)
[Link] = [Link]
[Link] = 60
Dim drd As SqlDataReader = _
[Link]([Link])
If drd IsNot Nothing Then
Luis Dueñas Pag 253
La Biblia de Visual Basic .NET
Dim posCodigo As Integer = [Link]("EmployeeID")
Dim posApellido As Integer = [Link]("LastName")
Dim posNombre As Integer = [Link]("FirstName")
Dim posFechaNac As Integer = [Link]("BirthDate")
Dim obeEmpleado As beEmpleado
Do While [Link]
obeEmpleado = New beEmpleado
With obeEmpleado
.Codigo = drd.GetInt32(posCodigo)
.Apellido = [Link](posApellido)
.Nombre = [Link](posNombre)
.FechaNac = [Link](posFechaNac)
End With
[Link](obeEmpleado)
Loop
[Link]()
End If
Return (lobeEmpleado)
End Function
End Class
Nota: Es importante definir el objeto obeEmpleado fuera del bucle Do
While y dentro de este crear una sola instancia del objeto para ir
agregándolo a la lista de objetos al final.
Agregar una nueva clase para Productos: del menú “Project”, “Add
Class” y escribir como nombre: daProducto.
Escribir el siguiente código para la clase daProducto:
Imports [Link]
Imports [Link]
Public Class daProducto
Public Function fListar(ByVal con As SqlConnection) As List(Of beProducto)
Dim lobeProducto As New List(Of beProducto)
Dim cmd As New SqlCommand("usp_Products_Sel", con)
[Link] = [Link]
[Link] = 60
Luis Dueñas Pag 254
La Biblia de Visual Basic .NET
Dim drd As SqlDataReader = _
[Link]([Link])
If drd IsNot Nothing Then
Dim posCodigo As Integer = [Link]("ProductID")
Dim posNombre As Integer = [Link]("ProductName")
Dim posIdProveedor As Integer = [Link]("SupplierID")
Dim posIdCategoria As Integer = [Link]("CategoryID")
Dim posPrecioUnitario As Integer = [Link]("UnitPrice")
Dim posStock As Integer = [Link]("UnitsInStock")
Dim obeProducto As beProducto
Do While [Link]
obeProducto = New beProducto
With obeProducto
.Codigo = drd.GetInt32(posCodigo)
.Nombre = [Link](posNombre)
.IdProveedor = drd.GetInt32(posIdProveedor)
.IdCategoria = drd.GetInt32(posIdCategoria)
.PrecioUnitario = [Link](posPrecioUnitario)
.Stock = drd.GetInt16(posStock)
End With
[Link](obeProducto)
Loop
[Link]()
End If
Return (lobeProducto)
End Function
End Class
Agregar una nueva clase para Categorias: del menú “Project”, “Add
Class” y escribir como nombre: daCategoria.
Escribir el siguiente código para la clase daCategoria:
Imports [Link]
Imports [Link]
Public Class daCategoria
Public Function fListar(ByVal con As SqlConnection) As List(Of beCategoria)
Dim lobeCategoria As New List(Of beCategoria)
Luis Dueñas Pag 255
La Biblia de Visual Basic .NET
Dim cmd As New SqlCommand("usp_Categories_Sel", con)
[Link] = [Link]
[Link] = 60
Dim drd As SqlDataReader = _
[Link]([Link])
If drd IsNot Nothing Then
Dim posCodigo As Integer = [Link]("CategoryID")
Dim posNombre As Integer = [Link]("CategoryName")
Dim obeCategoria As beCategoria
Do While [Link]
obeCategoria = New beCategoria
With obeCategoria
.Codigo = drd.GetInt32(posCodigo)
.Nombre = [Link](posNombre)
End With
[Link](obeCategoria)
Loop
[Link]()
End If
Return (lobeCategoria)
End Function
End Class
Agregar una nueva clase para Proveedores: del menú “Project”, “Add
Class” y escribir como nombre: daProveedor.
Escribir el siguiente código para la clase daProveedor:
Imports [Link]
Imports [Link]
Public Class daProveedor
Public Function fListar(ByVal con As SqlConnection) As List(Of beProveedor)
Dim lobeProveedor As New List(Of beProveedor)
Dim cmd As New SqlCommand("usp_Suppliers_Sel", con)
[Link] = [Link]
[Link] = 60
Dim drd As SqlDataReader = _
[Link]([Link])
Luis Dueñas Pag 256
La Biblia de Visual Basic .NET
If drd IsNot Nothing Then
Dim posCodigo As Integer = [Link]("SupplierID")
Dim posNombre As Integer = [Link]("CompanyName")
Dim obeProveedor As beProveedor
Do While [Link]
obeProveedor = New beProveedor
With obeProveedor
.Codigo = drd.GetInt32(posCodigo)
.Nombre = [Link](posNombre)
End With
[Link](obeProveedor)
Loop
[Link]()
End If
Return (lobeProveedor)
End Function
End Class
Finalmente, del menú “Build” seleccionar “Build [Link]
Access” para crear la dll con los servicios de acceso a datos.
Luis Dueñas Pag 257
La Biblia de Visual Basic .NET
Creando la Librería de Reglas del Negocio
Después de crear la librería de Acceso a Datos hay que crear la librería de
Reglas del Negocio, la cual debe usar la de acceso a datos y las entidades
del negocio.
Esta contiene métodos llamados reglas de negocio que definen y abren la
conexión contra el origen de datos y llaman a servicios de datos pasándole
como parámetro la conexión abierta, también se encargan de controlar la
integridad de datos a través de las transacciones.
Hay 2 formas de trabajar con la cadena de conexión desde esta capa, una
es leyendo automáticamente la cadena de conexión desde una variable en
la aplicación (appSettings) y la otra es pasar en el constructor o en cada
método la cadena de conexión desde la aplicación. Para los ejemplos
vamos a usar la primera técnica.
Demo [Link]
Del menú “File”, seleccionar “New Project” y luego “Class Library”.
Escribir como nombre físico al proyecto: [Link].
Hacer una referencia a la librería de entidades creada: seleccionar el
proyecto, clic derecho “Add References”, seleccionar ficha “Browse” y
buscar el archivo [Link] creado.
También hacer una referencia a la librería de acceso a datos:
[Link].
Cambiar de nombre a la clase de [Link] a [Link].
Escribir el siguiente código para la clase brEmpleado:
Imports [Link]
Imports [Link]
Imports [Link]
Public Class brEmpleado
Private strConexion As String
Luis Dueñas Pag 258
La Biblia de Visual Basic .NET
Public Sub New()
Dim asr As New [Link]
strConexion = [Link]("conNW", [Link]("[Link]"))
End Sub
Public Function Listar() As List(Of beEmpleado)
Dim lobeEmpleado As New List(Of beEmpleado)
Using con As New SqlConnection(strConexion)
Try
[Link]()
Dim odaEmpleado As New daEmpleado
lobeEmpleado = [Link](con)
Catch ex As Exception
'Grabar el Log de error
lobeEmpleado = Nothing
End Try
End Using
Return (lobeEmpleado)
End Function
End Class
Advertencia: Si en la aplicación cliente que llama a la librería de reglas
del negocio no se crea un archivo de configuración con una clave llamada
conNW en la sección del appSetting conteniendo la cadena de conexión se
generará una excepción al conectarse a la base de datos, la cual es
controlada por la estructura Try..Catch.
Agregar una nueva clase para Productos: del menú “Project”, “Add
Class” y escribir como nombre: brProducto.
Escribir el siguiente código para la clase brProducto:
Imports [Link]
Imports [Link]
Imports [Link]
Public Class brProducto
Private strConexion As String
Public Sub New()
Dim asr As New [Link]
Luis Dueñas Pag 259
La Biblia de Visual Basic .NET
strConexion = [Link]("conNW", [Link]("[Link]"))
End Sub
Public Function Listar() As List(Of beProducto)
Dim lobeProducto As New List(Of beProducto)
Using con As New SqlConnection(strConexion)
Try
[Link]()
Dim odaProducto As New daProducto
lobeProducto = [Link](con)
Catch ex As Exception
'Grabar el Log de error
lobeProducto = Nothing
End Try
End Using
Return (lobeProducto)
End Function
End Class
Agregar una nueva clase para Categorias: del menú “Project”, “Add
Class” y escribir como nombre: brCategoria.
Escribir el siguiente código para la clase brCategoria:
Imports [Link]
Imports [Link]
Imports [Link]
Public Class brCategoria
Private strConexion As String
Public Sub New()
Dim asr As New [Link]
strConexion = [Link]("conNW", [Link]("[Link]"))
End Sub
Public Function Listar() As List(Of beCategoria)
Dim lobeCategoria As New List(Of beCategoria)
Using con As New SqlConnection(strConexion)
Try
[Link]()
Luis Dueñas Pag 260
La Biblia de Visual Basic .NET
Dim odaCategoria As New daCategoria
lobeCategoria = [Link](con)
Catch ex As Exception
'Grabar el Log de error
lobeCategoria = Nothing
End Try
End Using
Return (lobeCategoria)
End Function
End Class
Agregar una nueva clase para Proveedores: del menú “Project”, “Add
Class” y escribir como nombre: brProveedor.
Escribir el siguiente código para la clase brProveedor:
Imports [Link]
Imports [Link]
Imports [Link]
Public Class brProveedor
Private strConexion As String
Public Sub New()
Dim asr As New [Link]
strConexion = [Link]("conNW", [Link]("[Link]"))
End Sub
Public Function Listar() As List(Of beProveedor)
Dim lobeProveedor As New List(Of beProveedor)
Using con As New SqlConnection(strConexion)
Try
[Link]()
Dim odaProveedor As New daProveedor
lobeProveedor = [Link](con)
Catch ex As Exception
'Grabar el Log de error
lobeProveedor = Nothing
End Try
End Using
Return (lobeProveedor)
Luis Dueñas Pag 261
La Biblia de Visual Basic .NET
End Function
End Class
Finalmente, del menú “Build” seleccionar “Build [Link]
Rules” para crear la dll con los servicios de reglas del negocio.
Creando la Aplicación que usa las Librerías
Finalmente, después de crear todas las librerías hay que crear la aplicación
la cual solo debe usar la librería de del negocio: entidades y reglas, esta no
puede usar la de acceso a datos ya que fue encapsulada desde la regla del
negocio.
Además es importante crear el archivo de configuración para definir la
cadena de conexión que espera las reglas del negocio.
A continuación un par de ejemplos que listan objetos desde las librerías, el
primero trabaja con los Empleados y el segundo con los Productos.
Demo 40
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo40.
Hacer una referencia a las librerías [Link] y
[Link].
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmListaEmpleado
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 400,300
Luis Dueñas Pag 262
La Biblia de Visual Basic .NET
StartPosition CenterScreen
Text Lista de Objetos Empleados
DataGridView1 Name dgvEmpleado
AutoSizeColumnsM AllCells
Dock Fill
ReadOnly True
SelectionMode FullRowSelect
El diseño del formulario debe quedar similar al gráfico 3.29:
Gráfico 3.29: Diseño del formulario Lista de Empleados
Ingresar al editor de código y escribir el siguiente código:
Imports [Link]
Imports [Link]
Public Class frmListaEmpleado
Private Sub ListarEmpleados(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim obrEmpleado As New brEmpleado
Dim lbeEmpleado As List(Of beEmpleado) = [Link]
[Link] = lbeEmpleado
End Sub
End Class
Luis Dueñas Pag 263
La Biblia de Visual Basic .NET
Agregar un archivo de configuración a la aplicación: del menú “Project”,
seleccionar “Add New Item”, en la categoría “General” seleccionar
“Application Configuration File”.
Agregar en el archivo de configuración la clave conNW en la sección
appSettings:
<configuration>
<appSettings>
<add key="conNW" value="uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 3.30: Ejecución del formulario Lista de Empleados
Luis Dueñas Pag 264
La Biblia de Visual Basic .NET
Demo 41
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo41.
Hacer una referencia a las librerías [Link] y
[Link].
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmListaProducto
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 600,300
StartPosition CenterScreen
Text Lista de Objetos Productos
DataGridView1 Name dgvProducto
AutoSizeColumnsM AllCells
Dock Fill
ReadOnly True
SelectionMode FullRowSelect
El diseño del formulario debe quedar similar al gráfico 3.31:
Luis Dueñas Pag 265
La Biblia de Visual Basic .NET
Gráfico 3.31: Diseño del formulario Lista de Productos
Ingresar al editor de código y escribir el siguiente código:
Imports [Link]
Imports [Link]
Public Class frmListaProducto
Private Sub ListarProductos(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim obrProducto As New brProducto
Dim lbeProducto As List(Of beProducto) = [Link]
[Link] = lbeProducto
End Sub
End Class
Agregar un archivo de configuración a la aplicación: del menú “Project”,
seleccionar “Add New Item”, en la categoría “General” seleccionar
“Application Configuration File”.
Agregar en el archivo de configuración la clave conNW en la sección
appSettings:
<configuration>
<appSettings>
<add key="conNW" value="uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind"/>
Luis Dueñas Pag 266
La Biblia de Visual Basic .NET
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 3.32: Ejecución del formulario Lista de Productos
Luis Dueñas Pag 267
La Biblia de Visual Basic .NET
3.2 Filtrando Datos en una Lista de Objetos
Una vez llena la lista de objetos la operación mas común es filtrar datos, es
decir consultar los registros que cumplan con una cierta condición, para
realizar esta operación en .NET Framework se puede hacer de diversas
formas: usando la estructura For y un If, mediante predicados o usando
LINQ.
En esta parte veremos como usar For If y también predicados y mas
adelante veremos como usar LINQ.
Usando For - If
La forma clásica de seleccionar solo los elementos que cumplen con una
condición es aplicar un bucle por ejemplo un For y luego preguntar si se
cumple una condición If.
Demo 42
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo42.
Hacer una referencia a las librerías [Link] y
[Link].
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmFiltroEmpleado
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 400,300
StartPosition CenterScreen
Text Filtro en Lista de Objetos
Luis Dueñas Pag 268
La Biblia de Visual Basic .NET
Empleados con For If
Label1 Name lblApellido
AutoSize True
Location 13, 17
Text Apellido:
TextBox1 Name txtApellido
Location 66, 10
Size 300, 20
DataGridView1 Name dgvEmpleado
AutoSizeColumnsM AllCells
Location 0, 43
ReadOnly True
SelectionMode FullRowSelect
Size 384, 221
El diseño del formulario debe quedar similar al gráfico 3.33:
Gráfico 3.33: Diseño del formulario Filtro de Empleados
Ingresar al editor de código y escribir el siguiente código:
Imports [Link]
Imports [Link]
Public Class frmFiltroEmpleado
Private lbeEmpleado As List(Of beEmpleado)
Luis Dueñas Pag 269
La Biblia de Visual Basic .NET
Private Sub ListarEmpleados(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim obrEmpleado As New brEmpleado
lbeEmpleado = [Link]
[Link] = lbeEmpleado
End Sub
Private Sub FiltrarEmpleadosPorApellido(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim lbeFiltro As New List(Of beEmpleado)
Dim obeEmpleado As beEmpleado
For I As Integer = 0 To [Link] - 1
If lbeEmpleado(I).[Link] _
([Link]) Then
obeEmpleado = New beEmpleado
[Link] = lbeEmpleado(I).Codigo
[Link] = lbeEmpleado(I).Apellido
[Link] = lbeEmpleado(I).Nombre
[Link] = lbeEmpleado(I).FechaNac
[Link](obeEmpleado)
End If
Next
[Link] = lbeFiltro
End Sub
End Class
Nota: En el código anterior se ha creado un objeto y se ha llenado, ya que
no se puede asignar un objeto a otro porque se haría por referencia.
Agregar un archivo de configuración a la aplicación: del menú “Project”,
seleccionar “Add New Item”, en la categoría “General” seleccionar
“Application Configuration File”.
Agregar en el archivo de configuración la clave conNW en la sección
appSettings:
<configuration>
<appSettings>
<add key="conNW" value="uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind"/>
</appSettings>
Luis Dueñas Pag 270
La Biblia de Visual Basic .NET
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 3.34: Ejecución del formulario Filtro de Empleados
Luis Dueñas Pag 271
La Biblia de Visual Basic .NET
Usando Predicados
La forma moderna de filtrar una lista de objetos es usar el método FindAll
de la lista de objetos que usa predicados que son delegados o punteros a
funciones.
Usar delegados es más legible que escribir la condición de filtro dentro de
un bucle. A continuación un par de ejemplos que muestra como filtrar
empleados y productos usando predicados.
Demo 43
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo43.
Hacer una referencia a las librerías [Link] y
[Link].
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmFiltroEmpleado
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 400,300
StartPosition CenterScreen
Text Filtro en Lista de Objetos
Empleados con Predicados
Label1 Name lblApellido
AutoSize True
Location 13, 17
Text Apellido:
TextBox1 Name txtApellido
Location 66, 10
Size 300, 20
DataGridView1 Name dgvEmpleado
Luis Dueñas Pag 272
La Biblia de Visual Basic .NET
AutoSizeColumnsM AllCells
Location 0, 43
ReadOnly True
SelectionMode FullRowSelect
Size 384, 221
El diseño del formulario debe quedar similar al gráfico 3.35:
Gráfico 3.35: Diseño del formulario Filtro de Empleados
Ingresar al editor de código y escribir el siguiente código:
Imports [Link]
Imports [Link]
Public Class frmFiltroEmpleado
Private lbeEmpleado As List(Of beEmpleado)
Private Sub ListarEmpleados(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim obrEmpleado As New brEmpleado
lbeEmpleado = [Link]
[Link] = lbeEmpleado
End Sub
Private Function BuscarEmpleado(ByVal obeEmpleado As beEmpleado) _
As Boolean
Luis Dueñas Pag 273
La Biblia de Visual Basic .NET
Return ([Link] _
([Link]))
End Function
Private Sub FiltrarEmpleadosPorApellido(ByVal sender As [Link],
ByVal e As [Link]) Handles [Link]
Dim lbeFiltro As New List(Of beEmpleado)
Dim pred As New Predicate(Of beEmpleado)(AddressOf BuscarEmpleado)
[Link] = [Link](pred)
End Sub
End Class
Agregar un archivo de configuración a la aplicación: del menú “Project”,
seleccionar “Add New Item”, en la categoría “General” seleccionar
“Application Configuration File”.
Agregar en el archivo de configuración la clave conNW en la sección
appSettings:
<configuration>
<appSettings>
<add key="conNW" value="uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 274
La Biblia de Visual Basic .NET
Gráfico 3.36: Ejecución del formulario Filtro de Empleados
Luis Dueñas Pag 275
La Biblia de Visual Basic .NET
Demo 44
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo44.
Hacer una referencia a las librerías [Link] y
[Link].
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmFiltroProducto
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 600,300
StartPosition CenterScreen
Text Filtro en Lista de Objetos
Productos con Predicados
Label1 Name lblCategoria
AutoSize True
Location 13, 17
Text Selecciona una Categoria:
ComboBox1 Name cboCategoria
Location 151, 9
Size 421, 21
DataGridView1 Name dgvProducto
AutoSizeColumnsM AllCells
Location 0, 43
ReadOnly True
SelectionMode FullRowSelect
Size 584, 225
El diseño del formulario debe quedar similar al gráfico 3.37:
Luis Dueñas Pag 276
La Biblia de Visual Basic .NET
Gráfico 3.37: Diseño del formulario Filtro de Productos x Categoria
Ingresar al editor de código y escribir el siguiente código:
Imports [Link]
Imports [Link]
Public Class frmFiltroProducto
Private lbeProducto As List(Of beProducto)
Private Sub ListarProductos(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim obrCategoria As New brCategoria
Dim lbeCategoria As List(Of beCategoria) = [Link]
Dim obeCategoria As New beCategoria
[Link] = 0
[Link] = "Seleccione"
[Link](0, obeCategoria)
With cboCategoria
.DataSource = lbeCategoria
.DisplayMember = "Nombre"
.ValueMember = "Codigo"
End With
Dim obrProducto As New brProducto
Luis Dueñas Pag 277
La Biblia de Visual Basic .NET
lbeProducto = [Link]
End Sub
Private Function BuscaProducto(ByVal obeProducto As beProducto)
Return ([Link] = [Link])
End Function
Private Sub FiltrarProductosxCategoria(ByVal sender As Object, _
ByVal e As [Link]) Handles _
[Link]
If [Link] = 0 Then
[Link] = Nothing
Else
Dim pred As New Predicate(Of beProducto)(AddressOf BuscaProducto)
[Link] = [Link](pred)
End If
End Sub
End Class
Nota: En el código anterior se ha creado un objeto obeCategoria para
agregar un elemento a la lista de objetos de tal forma que aparezca
Seleccione en el ComboBox. Nunca debe insertarse un registro
directamente en la tabla solo para ver este elemento en un control.
Agregar un archivo de configuración a la aplicación: del menú “Project”,
seleccionar “Add New Item”, en la categoría “General” seleccionar
“Application Configuration File”.
Agregar en el archivo de configuración la clave conNW en la sección
appSettings:
<configuration>
<appSettings>
<add key="conNW" value="uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 278
La Biblia de Visual Basic .NET
Gráfico 3.38: Ejecución del formulario Filtro de Productos x
Categoria
Luis Dueñas Pag 279
La Biblia de Visual Basic .NET
3.3 Ordenando y Buscando datos en una Lista de Objetos
Cuando los datos a consultar son demasiados podemos usar el filtro pero si
los datos no son demasiados podemos usar búsqueda de datos por un
cierta columna para lo cual primero deben estar ordenados los datos por
dicha columna.
Para ordenar se usa el método Sort de la lista de objetos seguido de un
comparador que es una clase que implementa la interface IComparer
conteniendo una función que recibe como parámetros 2 objetos y returna
un entero indicando el tipo de orden.
Para buscar un objeto se usa el método FindIndex de la lista de objetos
que devuelve un entero indicando la posición en la lista de objetos en la
que se encuentra el dato buscado a través de predicados.
A continuación se presenta un ejemplo que implementa una búsqueda por
apellido de los empleados.
Demo 45
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo45.
Hacer una referencia a las librerías [Link] y
[Link].
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmBuscaEmpleado
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 400,300
StartPosition CenterScreen
Luis Dueñas Pag 280
La Biblia de Visual Basic .NET
Text Ordenación y Búsqueda en
Lista de Objetos Empleados
Label1 Name lblApellido
AutoSize True
Location 13, 17
Text Apellido:
TextBox1 Name txtApellido
Location 66, 10
Size 300, 20
DataGridView1 Name dgvEmpleado
AutoSizeColumnsM AllCells
Location 0, 43
ReadOnly True
SelectionMode FullRowSelect
Size 384, 221
El diseño del formulario debe quedar similar al gráfico 3.39:
Gráfico 3.39: Diseño del formulario Búsqueda de Empleados
Agregar una clase para crear un comparador para ordenar la lista de
empleados: del menú “Project” seleccionar “Add Class” y escribir como
nombre: ucComparaEmpleado.
Escribir el siguiente código:
Imports [Link]
Luis Dueñas Pag 281
La Biblia de Visual Basic .NET
Public Class ucComparaEmpleado
Implements IComparer(Of beEmpleado)
Public Function Compare(ByVal x As _
[Link], _
ByVal y As [Link]) As Integer _
Implements [Link] _
(Of [Link]).Compare
Return ([Link]([Link]))
End Function
End Class
Nota: Al escribir la línea con la instrucción Implements y dar Enter el editor
crea automáticamente la plantilla de código con la función a implementar.
Ingresar al código del formulario y escribir lo siguiente:
Imports [Link]
Imports [Link]
Public Class frmBuscaEmpleado
Private lbeEmpleado As List(Of beEmpleado)
Private bs As New BindingSource
Private Sub ListarEmpleados(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim obrEmpleado As New brEmpleado
lbeEmpleado = [Link]
Dim oucComparaEmpleado As New ucComparaEmpleado
[Link](oucComparaEmpleado)
[Link] = lbeEmpleado
[Link] = bs
End Sub
Private Function BuscarEmpleado(ByVal obeEmpleado As beEmpleado) _
As Boolean
Return ([Link] _
([Link]))
End Function
Luis Dueñas Pag 282
La Biblia de Visual Basic .NET
Private Sub BuscarEmpleadosPorApellido(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim lbeFiltro As New List(Of beEmpleado)
Dim pred As New Predicate(Of beEmpleado)(AddressOf BuscarEmpleado)
Dim pos As Integer = [Link](pred)
If pos > -1 Then [Link] = pos
End Sub
End Class
Nota: En el código anterior la grilla no se enlaza directamente a la lista de
objetos sino se hace a través del BindingSource para poder posicionarse
sobre la grilla.
Agregar un archivo de configuración a la aplicación: del menú “Project”,
seleccionar “Add New Item”, en la categoría “General” seleccionar
“Application Configuration File”.
Agregar en el archivo de configuración la clave conNW en la sección
appSettings:
<configuration>
<appSettings>
<add key="conNW" value="uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 283
La Biblia de Visual Basic .NET
Gráfico 3.40: Ejecución del formulario Búsqueda de Empleados
Luis Dueñas Pag 284
La Biblia de Visual Basic .NET
3.4 Mantenimiento con Objetos
En esta última parte veremos como realizar un mantenimiento usando
objetos, para lo cual necesitamos primero crear los procedimientos
almacenados que inserten, actualizen y eliminen, luego agregar los
servicios de datos y reglas de negocio para finalmente crear la aplicación
de mantenimiento.
A continuación presentamos un ejemplo de mantenimiento con objetos
para los Empleados.
Creando los Procedimientos Almacenados
Crear los siguientes procedimientos almacenados:
Procedimiento almacenado que adiciona un empleado
Create Procedure usp_Employees_Ins
@LastName nvarchar(20),
@FirstName nvarchar(10),
@BirthDate datetime
AS
INSERT INTO Employees
(
LastName,
FirstName,
BirthDate
)
VALUES
(
@LastName,
@FirstName,
@BirthDate
)
return @@identity
Procedimiento almacenado que actualiza un empleado
Create Procedure usp_Employees_Upd
Luis Dueñas Pag 285
La Biblia de Visual Basic .NET
@EmployeeID int,
@LastName nvarchar(20),
@FirstName nvarchar(10),
@BirthDate datetime
AS
UPDATE Employees
SET
LastName=@LastName,
FirstName=@FirstName,
BirthDate=@BirthDate
WHERE
EmployeeID=@EmployeeID
Procedimiento almacenado que elimina un empleado
Create Procedure usp_Employees_Del
@EmployeeID int
AS
DELETE FROM Employees
WHERE EmployeeID=@EmployeeID
Luis Dueñas Pag 286
La Biblia de Visual Basic .NET
Modificando la Librería de Acceso a Datos
Del menú “File”, seleccionar “Open Project” y luego abrir el projecto:
“[Link]”.
Modificar la clase daEmpleado para aumentar lo siguiente:
Public Function fAdicionar(ByVal con As SqlConnection, _
ByVal obeEmpleado As beEmpleado) As Integer
Dim N As Integer = -1
Dim cmd As New SqlCommand("usp_Employees_Ins", con)
[Link] = [Link]
Dim par1 As SqlParameter = _
[Link]("@LastName", [Link], 20)
[Link] = [Link]
[Link] = [Link]
Dim par2 As SqlParameter = _
[Link]("@FirstName", [Link], 10)
[Link] = [Link]
[Link] = [Link]
Dim par3 As SqlParameter = _
[Link]("@BirthDate", [Link])
[Link] = [Link]
[Link] = [Link]
Dim par4 As SqlParameter = _
[Link]("@@identity", [Link])
[Link] = [Link]
N = [Link]
If N > 0 Then
Return ([Link])
Else
Return (-1)
End If
End Function
Public Function fActualizar(ByVal con As SqlConnection, _
ByVal obeEmpleado As beEmpleado) As Boolean
Dim Exito As Boolean = False
Dim cmd As New SqlCommand("usp_Employees_Upd", con)
[Link] = [Link]
Dim par1 As SqlParameter = _
Luis Dueñas Pag 287
La Biblia de Visual Basic .NET
[Link]("@EmployeeID", [Link])
[Link] = [Link]
[Link] = [Link]
Dim par2 As SqlParameter = _
[Link]("@LastName", [Link], 20)
[Link] = [Link]
[Link] = [Link]
Dim par3 As SqlParameter = _
[Link]("@FirstName", [Link], 10)
[Link] = [Link]
[Link] = [Link]
Dim par4 As SqlParameter = _
[Link]("@BirthDate", [Link])
[Link] = [Link]
[Link] = [Link]
Dim N As Integer = [Link]
Exito = (N > 0)
Return (Exito)
End Function
Public Function fEliminar(ByVal con As SqlConnection, _
ByVal CodEmpleado As Integer) As Boolean
Dim Exito As Boolean = False
Dim cmd As New SqlCommand("usp_Employees_Del", con)
[Link] = [Link]
Dim par As SqlParameter = _
[Link]("@EmployeeID", [Link])
[Link] = CodEmpleado
Dim N As Integer = [Link]
Exito = (N > 0)
Return (Exito)
End Function
Finalmente, del menú “Build” seleccionar “Build [Link]
Access” para actualizar la dll con los cambios realizados.
Luis Dueñas Pag 288
La Biblia de Visual Basic .NET
Modificando la Librería de Reglas del Negocio
Del menú “File”, seleccionar “Open Project” y luego abrir el projecto:
“[Link]”.
Modificar la clase brEmpleado para aumentar lo siguiente:
Public Function Adicionar(ByVal obeEmpleado As beEmpleado) As Integer
Dim N As Integer = -1
Using con As New SqlConnection(strConexion)
Try
[Link]()
Dim odaEmpleado As New daEmpleado
N = [Link](con, obeEmpleado)
Catch ex As Exception
'Grabar el Log de error
N = -1
End Try
End Using
Return (N)
End Function
Public Function Actualizar(ByVal obeEmpleado As beEmpleado) As Boolean
Dim exito As Boolean = False
Using con As New SqlConnection(strConexion)
Try
[Link]()
Dim odaEmpleado As New daEmpleado
exito = [Link](con, obeEmpleado)
Catch ex As Exception
'Grabar el Log de error
End Try
End Using
Return (exito)
End Function
Public Function Eliminar(ByVal CodEmpleado As Integer) As Boolean
Dim exito As Boolean = False
Using con As New SqlConnection(strConexion)
Try
[Link]()
Luis Dueñas Pag 289
La Biblia de Visual Basic .NET
Dim odaEmpleado As New daEmpleado
exito = [Link](con, CodEmpleado)
Catch ex As Exception
'Grabar el Log de error
End Try
End Using
Return (exito)
End Function
Finalmente, del menú “Build” seleccionar “Build [Link]
Rules” para actualizar la dll con los cambios realizados.
Luis Dueñas Pag 290
La Biblia de Visual Basic .NET
Demo 46
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo46.
Hacer una referencia a las librerías [Link] y
[Link].
Cambiar de nombre al formulario de [Link] a frmMantenimiento
[Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmMantenimientoEmpleado
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 400,400
StartPosition CenterScreen
Text Mantenimiento de Empleados
con Objetos
Label1 Name lblCodigo
AutoSize True
Location 26, 33
Text Código:
TextBox1 Name txtCodigo
Location 100,26
ReadOnly True
Size 47,20
Label2 Name lblApellido
AutoSize True
Location 26, 59
Text Apellido:
TextBox2 Name txtApellido
Location 100,52
Size 178,20
Label3 Name lblNombre
AutoSize True
Luis Dueñas Pag 291
La Biblia de Visual Basic .NET
Location 26, 85
Text Nombre:
TextBox3 Name txtNombre
Location 100,78
Size 178,20
Label4 Name lblFechaNac
AutoSize True
Location 26, 111
Text Fecha Nac:
DateTimePicker1 Name dtpFechaNac
Format Short
Location 100,105
Size 88,20
Button1 Name btnNuevo
Cursor Hand
Location 297, 22
Size 75, 23
Text Nuevo
Button2 Name btnAdicionar
Cursor Hand
Location 297, 22
Size 75, 50
Text Adicionar
Button3 Name btnActualizar
Cursor Hand
Location 297, 78
Size 75, 23
Text Actualizar
Button4 Name btnEliminar
Cursor Hand
Location 297, 106
Size 75, 23
Text Eliminar
DataGridView1 Name dgvEmpleado
Location 13, 151
MultiSelect False
ReadOnly True
SelectionMode FullRowSelect
Size 367, 210
El diseño del formulario debe quedar similar al gráfico 3.41:
Luis Dueñas Pag 292
La Biblia de Visual Basic .NET
Gráfico 3.41: Diseño del formulario Mantenimiento de Empleados
Ingresar al editor de código y escribir el siguiente código.
Imports [Link]
Imports [Link]
Imports [Link].Drawing2D
Public Class frmMantenimientoEmpleado
Private lbeEmpleado As New List(Of beEmpleado)
Private obrEmpleado As New brEmpleado
Private bs As New BindingSource
Private Sub DibujarRecuadro(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
Dim recData As New Rectangle(15, 10, 270, 130)
Dim degData As New LinearGradientBrush _
(recData, [Link], [Link], _
[Link])
[Link](degData, recData)
Dim recBoton As New Rectangle(290, 10, 90, 130)
Dim degBoton As New LinearGradientBrush _
(recBoton, [Link], [Link], _
Luis Dueñas Pag 293
La Biblia de Visual Basic .NET
[Link])
[Link](degBoton, recBoton)
End Sub
Private Sub PersonalizarGrilla()
[Link](0).HeaderText = "ID"
[Link](0).Width = 40
[Link](1).HeaderText = "Apellido"
[Link](1).Width = 80
[Link](2).HeaderText = "Nombre"
[Link](2).Width = 80
[Link](3).HeaderText = "Fecha Nac"
[Link](3).Width = 100
End Sub
Private Sub ListarEmpleados()
lbeEmpleado = [Link]
[Link] = lbeEmpleado
[Link] = bs
End Sub
Private Sub CargarDatos(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
ListarEmpleados()
PersonalizarGrilla()
End Sub
Private Sub MostrarDatos(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
With [Link]
[Link] = .Cells(0).Value
[Link] = .Cells(1).Value
[Link] = .Cells(2).Value
[Link] = .Cells(3).Value
End With
End Sub
Private Sub Nuevo(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link]()
Luis Dueñas Pag 294
La Biblia de Visual Basic .NET
[Link]()
[Link]()
[Link] = Now
[Link]()
End Sub
Private Sub AdicionarEmpleado(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If [Link] <> "" Then
If [Link] <> "" Then
Dim Diferencia As TimeSpan = _
[Link]([Link])
If [Link] > 0 Then
Dim obeEmpleado As New beEmpleado
With obeEmpleado
.Apellido = [Link]
.Nombre = [Link]
.FechaNac = [Link]
End With
Dim N As Integer = [Link](obeEmpleado)
If N > 0 Then
[Link]("Se Adicionó el Empleado", _
"Aviso", [Link], _
[Link])
Else
[Link]("No se pudo Adicionar el Empleado", _
"Error", [Link], _
[Link])
End If
ListarEmpleados()
[Link] = [Link] - 1
Else
[Link]("La Fecha de Nacimiento debe ser menor a
hoy")
[Link]()
End If
Else
[Link]("Falta ingresar el Nombre", "Aviso", _
[Link], [Link])
[Link]()
Luis Dueñas Pag 295
La Biblia de Visual Basic .NET
End If
Else
[Link]("Falta ingresar el Apellido", "Aviso", _
[Link], [Link])
[Link]()
End If
End Sub
Private Sub ActualizarEmpleado(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If [Link] <> "" Then
If [Link] <> "" Then
Dim Diferencia As TimeSpan = _
[Link]([Link])
If [Link] > 0 Then
Dim obeEmpleado As New beEmpleado
With obeEmpleado
.Codigo = [Link]([Link])
.Apellido = [Link]
.Nombre = [Link]
.FechaNac = [Link]
End With
Dim exito As Boolean = [Link](obeEmpleado)
If exito Then
[Link]("Se Actualizó el Empleado", _
"Aviso", [Link], _
[Link])
Else
[Link]("No se pudo Actualizar el Empleado", _
"Error", [Link], _
[Link])
End If
Dim pos As Integer = [Link]
ListarEmpleados()
[Link] = pos
Else
[Link]("La Fecha de Nacimiento debe ser menor a
hoy")
[Link]()
End If
Luis Dueñas Pag 296
La Biblia de Visual Basic .NET
Else
[Link]("Falta ingresar el Nombre", "Aviso", _
[Link], [Link])
[Link]()
End If
Else
[Link]("Falta ingresar el Apellido", "Aviso", _
[Link], [Link])
[Link]()
End If
End Sub
Private Sub EliminarEmpleado(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If [Link] <> "" Then
If [Link]("Estas seguro de eliminarlo", "Aviso", _
[Link], [Link]) = _
[Link] Then
Dim CodEmpleado As Integer = [Link]([Link])
Dim exito As Boolean = [Link](CodEmpleado)
If exito Then
[Link]("Se Eliminó el Empleado", _
"Aviso", [Link], _
[Link])
Else
[Link]("No se pudo Eliminar el Empleado", _
"Error", [Link], _
[Link])
End If
Dim pos As Integer = [Link]
ListarEmpleados()
[Link] = pos
End If
Else
[Link]("Falta seleccionar el Empleado", "Aviso", _
[Link], [Link])
End If
End Sub
End Class
Luis Dueñas Pag 297
La Biblia de Visual Basic .NET
Agregar un archivo de configuración a la aplicación: del menú “Project”,
seleccionar “Add New Item”, en la categoría “General” seleccionar
“Application Configuration File”.
Agregar en el archivo de configuración la clave conNW en la sección
appSettings:
<configuration>
<appSettings>
<add key="conNW" value="uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 3.42: Ejecución del formulario Mantenimiento de
Empleados con Objetos
Luis Dueñas Pag 298
La Biblia de Visual Basic .NET
4. LINQ
Las Consultas Integradas en el Lenguaje (Language Integrated Query o
LINQ) permiten manejar los datos desde el Lenguaje de programación
Visual Basic en vez de hacerlo mediante instrucciones SQL, como Transact
SQL para SQL Server.
El objetivo principal de LINQ es que en vez de que el programador use
diferentes lenguajes o modelos de programación para acceder a datos lo
haga usando un solo lenguaje de consulta que trabaja con los datos en
memoria.
Existen varios tipos de LINQ como lo muestra el gráfico 3.43: a objetos, a
DataSet, a SQL, a Entidades y a XML. LINQ a objetos permite trabajar con
listas o arreglos de objetos en vez de usar predicados; LINQ a DataSet,
SQL y a Entidades permiten trabajar con bases de datos en vez de usar el
DataSet e instrucciones SQL; finalmente, LINQ a XML permite acceder a
XML en vez de usar XMLTextReader o DOM de XML.
Gráfico 3.43: ADO .NET y LINQ
Para ver mas información sobre LINQ ver la referencia 22 al final del libro.
En esta parte solo veremos LINQ con bases de datos es decir LINQ a
DataSet, LINQ a SQL y LINQ a Entidades.
Luis Dueñas Pag 299
La Biblia de Visual Basic .NET
4.1 LINQ a DataSet
LINQ a DataSet facilita el trabajo con el DataSet y se implementa a través
de los métodos de extensión en las clases DataRowExtensions y DataTable
Extensions. Estas extensiones agregan operadores que permiten comparar
secuencias de filas así como métodos que proporcionan acceso a los
campos de un DataRow.
Para habilitar la funcionalidad de LINQ a DataSet hay que hacer referencia
al ensamblado [Link] y para usar el DataSet se
usa el ensamblado [Link].
Nota: Al crear una aplicación Windows, ya viene por defecto referenciado
ambas librerías, es decir, ya estamos listos para trabajar con LINQ a
DataSet.
Las consultas de LINQ a DataSet se pueden escribir en 2 sintaxis distintas:
sintaxis de expresiones de consulta y sintaxis de consultas basadas en
métodos.
Sintáxis de Expresiones de Consulta
Las expresiones de consulta son una sintaxis de consulta declarativa. Esta
sintaxis permite a un desarrollador escribir consultas en Visual Basic en un
formato similar a SQL. Si se utiliza la sintaxis de expresiones de consulta,
se pueden realizar incluso operaciones complejas de filtrado, ordenación y
agrupamiento en orígenes de datos con código mínimo.
Demo 47
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo47.
Cambiar de nombre al formulario de [Link] a [Link]
Luis Dueñas Pag 300
La Biblia de Visual Basic .NET
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmFiltroEmpleado
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 400,300
StartPosition CenterScreen
Text Filtro de Empleados con LINQ a
DataSet
Label1 Name lblApellido
AutoSize True
Location 13, 17
Text Apellido:
TextBox1 Name txtApellido
Location 66,10
ReadOnly True
Size 300,20
ListView1 Name lvwEmpleado
FullRowSelect True
GridLines True
HotTracking True
Location 12, 36
Size 354, 216
El diseño del formulario debe quedar similar al gráfico 3.44:
Luis Dueñas Pag 301
La Biblia de Visual Basic .NET
Gráfico 3.44: Diseño del formulario Filtro de Empleados LINQ a
DataSet
Ingresar al editor de código y escribir el siguiente código:
Imports [Link]
Imports [Link]
Public Class frmFiltroEmpleado
Private dst As New DataSet
Private Sub LlenarListView()
Dim fila As ListViewItem
[Link]()
For Each empleado In [Link](0).Rows
fila = [Link](empleado(0))
[Link](empleado(1))
[Link](empleado(2))
Next
[Link]()
End Sub
Private Sub ListarEmpleados(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Using con As New SqlConnection("uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind")
[Link]()
Luis Dueñas Pag 302
La Biblia de Visual Basic .NET
Dim dap As New SqlDataAdapter _
("Select EmployeeID,LastName,FirstName From Employees", con)
[Link](dst, "Empleados")
End Using
With lvwEmpleado
.[Link]("Codigo", 50, [Link])
.[Link]("Apellido", 100, [Link])
.[Link]("Nombre", 100, [Link])
.View = [Link]
End With
LlenarListView()
End Sub
Private Sub FiltrarEmpleadosPorApellido(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link]()
If [Link] <> "" Then
Dim res = From empleado In [Link](0).AsEnumerable _
Select empleado Where empleado(1).[Link]. _
Contains([Link])
[Link]()
Dim fila As ListViewItem
For Each empleado In res
fila = [Link]([Link](Of Int32)(0))
[Link]([Link](Of String)(1))
[Link]([Link](Of String)(2))
Next
[Link]()
Else
LlenarListView()
End If
End Sub
End Class
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 303
La Biblia de Visual Basic .NET
Gráfico 3.45: Ejecución del formulario Filtro de Empleados con
LINQ a DataSet
Luis Dueñas Pag 304
La Biblia de Visual Basic .NET
Sintáxis de Consultas basadas en Métodos
La otra forma de trabajar con consultas de LINQ a DataSet es usar las
consultas basadas en métodos. La sintaxis de consultas basadas en
métodos es una secuencia de llamadas a métodos directas a los métodos
de operador de LINQ, pasando expresiones lambda como parámetros.
Demo 48
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo48.
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmFiltroProducto
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 400, 300
StartPosition CenterScreen
Text Filtro de Productos con LINQ a
DataSet
Label1 Name lblNombre
AutoSize True
Location 13, 17
Text Nombre:
TextBox1 Name txtNombre
Location 66,10
ReadOnly True
Size 300,20
ListView1 Name lvwProducto
FullRowSelect True
GridLines True
HotTracking True
Location 12, 36
Size 354, 216
Luis Dueñas Pag 305
La Biblia de Visual Basic .NET
El diseño del formulario debe quedar similar al gráfico 3.46:
Gráfico 3.46: Diseño del formulario Filtro de Productos LINQ a
DataSet
Ingresar al editor de código y escribir el siguiente código:
Imports [Link]
Imports [Link]
Public Class frmFiltroProducto
Private dst As New DataSet
Private Sub LlenarListView()
Dim fila As ListViewItem
[Link]()
For Each empleado In [Link](0).Rows
fila = [Link](empleado(0))
[Link](empleado(1))
[Link](empleado(2))
Next
[Link]()
End Sub
Private Sub ListarEmpleados(ByVal sender As [Link], _
Luis Dueñas Pag 306
La Biblia de Visual Basic .NET
ByVal e As [Link]) Handles [Link]
Using con As New SqlConnection("uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind")
[Link]()
Dim dap As New SqlDataAdapter _
("Select ProductID,ProductName,UnitPrice From Products", con)
[Link](dst, "Productos")
End Using
With lvwProducto
.[Link]("Codigo", 50, [Link])
.[Link]("Nombre", 200, [Link])
.[Link]("Precio", 70, [Link])
.View = [Link]
End With
LlenarListView()
End Sub
Private Sub FiltrarProductosPorNombre(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link]()
If [Link] <> "" Then
Dim res = [Link](0).AsEnumerable() _
.Select(Function(producto As DataRow) New With _
{_
.ProductID = [Link](Of Integer)("ProductID"), _
.ProductName = [Link](Of String)("ProductName"), _
.UnitPrice = [Link](Of Decimal)("UnitPrice") _
})
[Link]()
Dim fila As ListViewItem
For Each producto In res
If [Link] _
([Link]) Then
fila = [Link]([Link])
[Link]([Link])
[Link]([Link])
End If
Next
[Link]()
Else
Luis Dueñas Pag 307
La Biblia de Visual Basic .NET
LlenarListView()
End If
End Sub
End Class
Grabar y luego ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 3.47: Ejecución del formulario Filtro de Productos con
LINQ a DataSet
Luis Dueñas Pag 308
La Biblia de Visual Basic .NET
4.2 LINQ a SQL
En LINQ a SQL, el modelo de datos de una base de datos relacional se
asigna a un modelo de objetos expresado en el lenguaje de programación
usado por el programador. Cuando la aplicación se ejecuta, LINQ a SQL
convierte a SQL las consultas integradas en el lenguaje en el modelo de
objetos y las envía a la base de datos para su ejecución. Cuando la base de
datos devuelve los resultados, LINQ a SQL los vuelve a convertir en objetos
con los que pueda trabajar en su propio lenguaje de programación.
Hay 2 herramientas que permiten implementar LINQ a SQL: Object
Relational Designer y SqlMetal. Los desarrolladores de Visual Studio
normalmente utilizan el Object Relational Designer, que proporciona una
interfaz de usuario para implementar muchas de las características de LINQ
a SQL. La segunda forma de generar código es usando por línea de
comandos el utilitario SQL Metal.
LINQ a SQL permite realizar todas las operaciones que se realizan
generalmente con SQL: selección, adición, actualización y eliminación de
registros.
Demo 49
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo49.
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmOrdenesxCliente
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 400,300
StartPosition CenterScreen
Luis Dueñas Pag 309
La Biblia de Visual Basic .NET
Text Filtro de Ordenes x Cliente
con LINQ a SQL
Label1 Name lblOrden
AutoSize True
Location 13, 17
Text Selecciona una Orden:
ComboBox1 Name cboOrden
Location 151, 9
Size 221, 21
DataGridView1 Name dgvCliente
AllowUserToAddRow False
AllowUserToDeleteRow False
Location 4, 43
ReadOnly True
SelectionMode FullRowSelect
Size 376, 218
El diseño del formulario debe quedar similar al gráfico 3.46:
Gráfico 3.48: Diseño del formulario Filtro de Ordenes x Cliente con
LINQ a SQL
Agregar un modelo de clases de datos, del menú “Project” seleccionar
“Add New Item” y en categoría elegir “Data” luego seleccionar “LINQ
To SQL Classes”.
Luis Dueñas Pag 310
La Biblia de Visual Basic .NET
Escribir como nombre del modelo “[Link]” y aparecerá
el diseñador de clases.
Clic al enlace que dice “Server Explorer” y aparecerá la ventana del
explorador de servidores.
Clic derecho a “Data Connections” en la ventana del explorador de
servidores y seleccionar “Add Connections”
Aparecerá el diálogo de agregar conexiones como lo muestra la figura
siguiente.
Gráfico 3.48: Diálogo de agregar conexiones
Ingresar los datos de la conexión a la base de datos Northwind y “OK”.
Luis Dueñas Pag 311
La Biblia de Visual Basic .NET
Expandir la carpeta tablas y arrastrar las tablas “Customers” y “Orders”
hacia el diseñador de clases.
Se crearán 2 tablas en el diseñador tal como lo muestra la siguiente
figura.
Gráfico 3.49: Diseñador Relacional de Objetos
Escribir el siguiente código en el formulario:
Public Class frmOrdenesxCliente
Public Class frmOrdenesxCliente
Private oNW As New ModeloClasesNWDataContext
Private Sub ListarClientes(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link] = [Link]
[Link] = "CompanyName"
[Link] = "CustomerID"
FiltrarOrdenesxCliente(Nothing, Nothing)
End Sub
Private Sub FiltrarOrdenesxCliente(ByVal sender As Object, _
ByVal e As [Link]) Handles
[Link]
Luis Dueñas Pag 312
La Biblia de Visual Basic .NET
Dim CodCliente As String = [Link]
[Link] = From orden In [Link] _
Where [Link] = CodCliente _
Select [Link], [Link], [Link]
End Sub
End Class
Grabar y luego ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 3.50: Ejecución del formulario Filtro de Ordenes x Cliente
con LINQ a SQL
Luis Dueñas Pag 313
La Biblia de Visual Basic .NET
4.3 LINQ a Entidades
[Link] Entity Framework permite a los desarrolladores crear aplicaciones
de acceso a datos programando con un modelo de aplicaciones
conceptuales en lugar de programar directamente con un esquema de
almacenamiento relacional. El objetivo es reducir la cantidad de código y el
mantenimiento necesarios para las aplicaciones orientadas a datos.
LINQ a Entidades permite escribir consultas contra el modelo conceptual de
Entity Framework mediante un lenguaje como Visual Basic. Las consultas
con Entity Framework se representan mediante consultas de árboles de
comandos, que se ejecutan en el contexto del objeto.
LINQ a Entidades convierte las consultas de LINQ en consultas de árboles
de comandos, ejecuta las consultas en Entity Framework y devuelve
objetos que se pueden usarse tanto en Entity Framework como en LINQ.
Los pasos para crear y ejecutar una consulta de LINQ a Entidades son:
1. Crear una instancia de ObjectQuery en ObjectContext.
2. Crear una consulta de LINQ a Entidades en con la instancia de
ObjectQuery.
3. Convertir los operadores y expresiones de consulta estándar de LINQ
en árboles de comandos.
4. Ejecutar la consulta, con representación de un árbol de comandos, en
el origen de datos. Las excepciones producidas en el origen de datos
durante la ejecución se pasan directamente al cliente.
5. Devolver los resultados de la consulta al cliente (Materialización).
Luis Dueñas Pag 314
La Biblia de Visual Basic .NET
Demo 50
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo50.
Cambiar de nombre al formulario de [Link] a frmProductosx
[Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmProductosxProveedor
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 400,300
StartPosition CenterScreen
Text Filtro de Productos x Proveedor
con LINQ a Entidades
Label1 Name lblProveedor
AutoSize True
Location 13, 17
Text Selecciona un Proveedor:
ComboBox1 Name cboProveedor
Location 151, 9
Size 229, 21
DataGridView1 Name dgvProducto
AutoSizeColumnsM AllCells
Location 2, 43
ReadOnly True
SelectionMode FullRowSelect
Size 392, 225
El diseño del formulario debe quedar similar al gráfico 3.51:
Luis Dueñas Pag 315
La Biblia de Visual Basic .NET
Gráfico 3.51: Diseño del formulario Filtro de Productos x
Proveedor con LINQ a Entidades
Agregar un Modelo de Datos de Entidades: del menú “Project”,
seleccionar “Add New Item” y luego en la sección “Data” elegir “ADO
NET Entity Data Model”.
Ingresar como nombre al Modelo: [Link] y “OK”.
Aparecerá el diálogo para seleccionar el contenido del modelo, tal como
se muestra en la figura 3.52.
Luis Dueñas Pag 316
La Biblia de Visual Basic .NET
Gráfico 3.52: Asistente Entity Data Model – Elegir contenido
Seleccionar “Generar desde la Base de Datos” y botón “Siguiente”.
Se mostrará el diálogo para seleccionar o crear la conexión a la base de
datos.
Luis Dueñas Pag 317
La Biblia de Visual Basic .NET
Gráfico 3.53: Asistente Entity Data Model – Elegir conexión
Ingresar como nombre para la configuración de la entidad: “Northwind
Entities” y botón “Siguiente”.
Nota: Marcar la opción “Si, incluir datos confidenciales en la cadena de
conexión” si la seguridad es Mixta.
Apacerá el diálogo de elegir objetos de bases de datos como se
muestra en la siguiente figura.
Luis Dueñas Pag 318
La Biblia de Visual Basic .NET
Gráfico 3.54: Asistente Entity Data Model – Elegir objetos de base
de datos
Expandir tablas y seleccionar las tablas “Products” y “Suppliers”, escribir
como espacios de nombre: “NorthwindModel” y “Finalizar”.
Se creará un modelo de datos similar al mostrado en la siguiente figura.
Luis Dueñas Pag 319
La Biblia de Visual Basic .NET
Gráfico 3.55: Diseñador con el Modelo de Datos de Entidades
Escribir el siguiente código en el formulario:
Public Class frmProductosxProveedor
Private oNW As New NorthwindEntities
Private Sub ListarProveedores(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
With cboProveedor
.DataSource = [Link]
.DisplayMember = "CompanyName"
.ValueMember = "SupplierID"
End With
FiltrarProductosxProveedor(Nothing, Nothing)
End Sub
Private Sub FiltrarProductosxProveedor(ByVal sender As Object, _
ByVal e As [Link]) Handles _
[Link]
Dim IdProveedor As Integer = [Link]
[Link] = From oProducto In [Link] _
Where [Link] = IdProveedor _
Select [Link], [Link], _
[Link]
End Sub
Luis Dueñas Pag 320
La Biblia de Visual Basic .NET
End Class
Grabar y luego ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 3.56: Ejecución del formulario Filtro de Productos x
Proveedor con LINQ a Entidades
Luis Dueñas Pag 321
La Biblia de Visual Basic .NET
Preguntas de Repaso
1. Qué es ADO .NET?
2. Cuáles son los 2 componentes principales de ADO .NET?
3. Menciona los 2 proveedores nativos de datos de ADO .NET.
4. Menciona los 2 proveedores generales de datos de ADO .NET.
5. Menciona las clases que debe implementar todo proveedor de datos?
6. Porqué es importante la cadena de conexión y con qué propiedad de la
clase Connection se define?
7. Cómo sería la cadena de conexión a una base de datos de SQL Server
que tiene seguridad de Windows y hay una sola instancia instalada.
8. Qué proveedor de datos se usa para conectarse a una base de datos de
MS Access, un archivo de MS Excel o un archivo DBF?
9. En qué se diferencia la cadena de conexión a una base de datos de MS
Access de la de un archivo Excel?
10. Cómo se puede obtener las tablas de una base de datos de MS Access
o las hojas de un archivo de MS Excel?
11. Cuál es la forma más eficiente de copiar gran cantidad de datos hacia
SQL Server?
12. Con qué clase de .NET se implementa la copia masiva hacia una base
de datos de MS SQL Server?
13. Con qué método de la clase Command se ejecutan comandos de
selección de un valor?
Luis Dueñas Pag 322
La Biblia de Visual Basic .NET
14. Con qué método de la clase Command se ejecutan comandos de
selección de una fila?
15. Con qué método de la clase Command se ejecutan comandos de
selección de varias filas?
16. Con qué método de la clase Command se ejecutan comandos de
selección de varias conjuntos de filas?
17. Cómo se llama la clase que permite almacenar una sola fila a la vez?
18. Cuál es la diferencia entre un DataReader y un DataSet?
19. Cómo se controlan los nulos mediante el DataReader?
20. Con qué método de la clase DataReader se puede leer el siguiente
conjunto de registros en caso de ser varios Select?
21. Con qué método de la clase Command se ejecuta un comando que
inserta, actualiza o elimina registros?
22. Qué es un DataSet y para que sirve?
23. Cuáles son los elementos de un DataSet?
24. Para que sirve el DataAdapter?
25. Con qué método del DataAdapter se crea un tabla en el DataSet desde
un origen de datos?
26. Cómo se crea una vista o DataView?
27. Con qué propiedad del DataView se filtran registros?
28. Con qué propiedad del DataView se ordenan registros?
29. Con qué método del DataView se busca un registro por una clave?
Luis Dueñas Pag 323
La Biblia de Visual Basic .NET
30. Qué debe hacerse al DataView antes de realizar una búsqueda, sino se
genera una excepción?
31. De qué formas se puede eliminar registros de un DataTable?
32. Cómo se pueden obtener los cambios realizados en un DataTable o
DataSet antes de enviarlos hacia la base de datos?
33. Con qué método del DataAdapter se envían los cambios de regreso a la
base de datos?
34. Cuál es la ventaja de trabajar desconectado usando Listas de Objetos
en vez del DataSet?
35. Cómo se filtran objetos de una lista de objetos?
36. Cómo se ordenan objetos de una lista de objetos?
37. Cómo se buscan datos en una lista de objetos?
38. Menciona 3 métodos extendidos que permitan realizar cálculos en listas
de objetos.
39. Para qué sirve LINQ y Cuántos tipos de LINQ existen?
40. De qué formas podemos acceder a bases de datos con LINQ?
41. Qué clases implementan LINQ a DataSets?
42. De qué formas se puede escribir la sintáxis de LINQ a DataSets?
43. Qué herramienta del Visual Studio se usa para implementar muchas
características de LINQ a SQL?
44. Qué tipo de operaciones se pueden realizar con LINQ a SQL?
Luis Dueñas Pag 324
La Biblia de Visual Basic .NET
45. Qué es ADO .NET Entity Framework?
46. A qué convierte LINQ a Entidades las consultas de LINQ.
47. Cuáles son los pasos para crear y ejecutar una consulta de LINQ a
Entidades?.
Luis Dueñas Pag 325
La Biblia de Visual Basic .NET
Capitulo 4: Desarrollando Aplicaciones Windows
Forms
Las aplicaciones Windows o de escritorio son aquellas basadas en ventanas
y mensajes de Windows, también conocidas como Aplicaciones Cliente
Inteligentes.
En .NET Framework para implementar este tipo de aplicaciones existen el
espacio de nombres [Link] el cual tiene clases como Form
que representa al formulario y otras como Label, TextBox, Button, etc., que
representan a los controles Windows Forms.
Con los formularios Windows Forms podemos crear clientes inteligentes
que aprovechen las ventajas de Windows tales como los gráficos, la
seguridad, manejo de entrada y salida, etc.
Aunque hasta el momento todos los ejemplos del libro han sido
aplicaciones para Windows, en este capítulo veremos formalmente como
crear aplicaciones que usen el formulario y los controles Windows Forms en
la primera parte.
En la segunda parte mejoraremos la interface de usuario creando
formularios MDIs, agregando menús, usando diálogos y agregando barras
de herramientas para hacer más fácil el acceso a la aplicación a los
usuarios.
En la tercera parte trataremos con mayor detalle el control DataGridView
que es principal control Windows Forms usado para mostrar datos en una
aplicación, para lo cual se verá como personalizar columnas, cabeceras,
celdas y filas; también aprenderemos como paginar datos cuando existen
gran cantidad de registros y finalmente como graficar dentro de la grilla.
En la cuarta parte crearemos librerías de controles para Windows,
incluyendo los 3 tipos de controles: extendidos, de usuario y personalizados
además veremos como agregar características para usarse en Visual
Studio.
Finalmente, veremos como crear reportes, informes e impresiones usando
diferentes formas como: usando el objeto PrintDocument y los diálogos de
Luis Dueñas Pag 326
La Biblia de Visual Basic .NET
impresión, también usando el ReportViewer para crear reporte de datos y
usando Office para crear informes en MS Word y exportar datos a Excel y
crear gráficos de datos.
Luis Dueñas Pag 327
La Biblia de Visual Basic .NET
1. Trabajando con el Formulario y los Controles Windows
El Formulario es el contenedor principal de las aplicaciones Windows Forms
y sobre este se encuentran los controles. En esta primera parte veremos
como configurar propiedades, trabajar con métodos y programar eventos
del formulario (clase Form) y los controles Windows estándares.
1.1. Trabajando con el Formulario Windows
Un formulario Form es una representación de cualquier ventana mostrada
en su aplicación. La clase Form se puede utilizar para crear ventanas
estándar, de herramientas, sin bordes y flotantes. También puede utilizar la
clase Form para crear las ventanas modales como un cuadro de diálogo. Un
tipo especial de formulario, el formulario de interfaz de múltiples
documentos (MDI), puede contener otros formularios denominados
formularios MDI secundarios. Los formularios MDI se crean estableciendo
la propiedad IsMdiContainer en true. Los formularios MDI secundarios se
crean estableciendo la propiedad MdiParent en el formulario MDI principal
que contendrá el formulario secundario.
Utilizando las propiedades disponibles en la clase Form, puede determinar
el aspecto, tamaño, color y las funciones de administración de la ventana o
cuadro de diálogo que está creando. La propiedad Text le permite
especificar el título que aparecerá en la barra de título de la ventana. Las
propiedades Size y DesktopLocation le permiten definir el tamaño y la
ubicación de la ventana cuando se muestra en la pantalla. Puede utilizar la
propiedad de color ForeColor para cambiar el color predeterminado de
primer plano de todos los controles incluidos en el formulario. Las
propiedades FormBorderStyle, MinimizeBox y MaximizeBox le permiten
controlar si se puede minimizar o maximizar el formulario, o si se puede
cambiar el tamaño en tiempo de ejecución.
Además de las propiedades, puede utilizar los métodos de la clase para
manipular un formulario. Por ejemplo, puede utilizar el método ShowDialog
para mostrar un formulario como un cuadro de diálogo modal. El método
SetDesktopLocation se puede usar para situar el formulario en el escritorio.
Luis Dueñas Pag 328
La Biblia de Visual Basic .NET
Los eventos de la clase Form le permiten responder a las acciones
realizadas en el formulario. Puede utilizar el evento Activated para realizar
operaciones como actualizar los datos mostrados en los controles del
formulario cuando se activa el formulario.
Puede utilizar un formulario como la clase de inicio de su aplicación
colocando un método llamado Main en la clase. En el método Main,
agregue el código necesario para crear y mostrar el formulario. También
será necesario agregar el atributo STAThread al método Main para que se
ejecute el formulario. Cuando se cierra el formulario de inicio, también se
cierra la aplicación.
Para obtener mas información sobre los formularios de Windows Forms ver
la referencia 23 al final del libro.
A continuación presentaremos un ejemplo de cómo crear un formulario No
rectangular sino en forma de elipse, usando graficos y un temporizador
para desaparecer progresivamente el formulario al dar clic.
Demo 51
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo51.
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmGraficoElipse
Cursor Hand
FormBorderStyle None
Text
WindowState Maximized
El diseño del formulario debe quedar similar al gráfico 4.1:
Luis Dueñas Pag 329
La Biblia de Visual Basic .NET
Gráfico 4.1: Diseño del formulario Grafico de Elipse
Escribir el siguiente código en el formulario:
Imports [Link].Drawing2D 'LinearGradientMode, GraphicsPath
Public Class frmGraficoElipse
Private WithEvents tmrGrafico As New Timer
Private N As Integer
Private Sub GraficarFormulario(ByVal sender As Object, ByVal e As _
[Link]) Handles [Link]
Dim X As Integer = [Link] / 2
Dim Y As Integer = [Link] / 2
Dim rec As New Rectangle(X - 400, Y - 200, 800, 400)
Dim deg As New LinearGradientBrush(rec, [Link], [Link], _
[Link])
[Link](deg, rec)
[Link]("Visual Basic 2010", New Font("Arial", 50), _
[Link], X - 270, Y - 100)
[Link]("Por Luis Dueñas H", New Font("Arial", 40), _
[Link], X - 220, Y + 20)
Dim gp As New GraphicsPath
[Link](rec)
[Link] = New Region(gp)
End Sub
Private Sub HabilitarTimer(ByVal sender As Object, ByVal e As _
Luis Dueñas Pag 330
La Biblia de Visual Basic .NET
[Link]) Handles [Link]
With tmrGrafico
.Interval = 10
.Enabled = True
.Start()
End With
End Sub
Private Sub DesvanecerFormulario(ByVal sender As Object, ByVal e As _
[Link]) Handles [Link]
[Link] = (100 - N) / 100
N += 1
If N = 100 Then [Link]()
End Sub
End Class
Nota: En el código anterior en el evento Paint del formulario se crea el
grafico y luego se configura la propiedad Region del formulario en una
nueva región la cual contiene la elipse.
Importante: No solo se puede cambiar la apariencia del formulario sino
de cualquier control Windows Forms ya que todos heredan de control que
tiene la propiedad región que permite cambiar la forma.
Grabar y luego ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 4.2: Ejecución del formulario Grafico de Elipse
Luis Dueñas Pag 331
La Biblia de Visual Basic .NET
1.2. Usando Controles Básicos
La mayoría de aplicaciones hace uso de los controles básicos de Windows
tales como las etiquetas (clase Label), los cuadros de texto (clase TextBox)
y los botones de comandos (clase Button). En este tema veremos como
usar dichos controles para crear aplicaciones básicas.
En el siguiente ejemplo se muestra como crear un dialogo de Login que
permita al usuario registrarse verificando su usuario y su clave desde un
archivo de texto.
Demo 52
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo52.
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmLogin
AcceptButton btnAceptar
CancelButton btnCancelar
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 300, 200
StartPosition CenterScreen
Text Login del Sistema
Label1 Name lblUsuario
AutoSize True
Location 27, 19
Text &Usuario:
TextBox1 Name txtUsuario
Location 90,12
MaxLength 20
Size 171,20
Tag Ingrese el Usuario
Luis Dueñas Pag 332
La Biblia de Visual Basic .NET
Label2 Name lblClave
AutoSize True
Location 27, 53
Text &Clave:
TextBox2 Name txtClave
Location 90,46
MaxLength 10
Size 171,20
Tag Ingresa la clave
UseSystemPasswordChar True
Button1 Name btnAceptar
Cursor Hand
Enabled False
Location 30, 84
Size 75, 23
Text &Aceptar
Button2 Name btnCancelar
Cursor Hand
Location 186, 84
Size 75, 23
Text &Cancelar
Label3 Name lblMensaje
AutoSize False
BorderStyle Fixed3D
Location 27, 123
Size 234,28
TextAlign MiddleCenter
El diseño del formulario debe quedar similar al gráfico 4.1:
Gráfico 4.3: Diseño del formulario Login
Luis Dueñas Pag 333
La Biblia de Visual Basic .NET
Abrir el bloc de notas y crear un archivo de texto con los nombres de
los usuarios y sus claves, por ejemplo ingresar:
Lduenas,1000
Trojas,2000
Mfuentes,3000
Escribir el siguiente código en el formulario:
Imports [Link]
Public Class frmLogin
Private contador As Integer
Private Sub HabilitarBotonAceptar(ByVal sender As [Link], _
ByVal e As [Link]) Handles _
[Link], [Link]
[Link] = ([Link]<>"" AndAlso [Link]<>"")
End Sub
Private Sub MostrarMensaje(ByVal sender As Object, _
ByVal e As [Link]) Handles _
[Link], [Link]
[Link] = [Link]
End Sub
Private Sub BorrarMensaje(ByVal sender As Object, _
ByVal e As [Link]) Handles _
[Link], [Link]
[Link] = ""
End Sub
Private Sub Aceptar(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim Archivo As String = _
"C:\Lduenas\NET\LibroVB2010\[Link]"
If [Link](Archivo) Then
Dim Encontro As Boolean = False
Using fs As New FileStream(Archivo, _
[Link], [Link], [Link])
Using sr As New StreamReader(fs)
Luis Dueñas Pag 334
La Biblia de Visual Basic .NET
Dim Usuario() As String
Do While Not [Link]
Usuario = [Link](",")
If [Link] = 2 Then
If Usuario(0) = [Link] _
AndAlso Usuario(1) = [Link] Then
Encontro = True
Exit Do
End If
End If
Loop
contador += 1
End Using
End Using
If Encontro Then
[Link]("Login valido", "Aviso", _
[Link], [Link])
[Link]()
Else
[Link]("Login Invalido", "Aviso", _
[Link], [Link])
End If
If contador = 3 Then
[Link]("Acceso Denegado", "Aviso", _
[Link], [Link])
[Link]()
End If
End If
End Sub
Private Sub Cancelar(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link]()
End Sub
End Class
Nota: En el código anterior la ruta del archivo [Link] tiene que
modificarse de acuerdo a la ubicación donde se encuentre su archivo.
Además la propiedad AcceptButton del formulario permite que al dar Enter
Luis Dueñas Pag 335
La Biblia de Visual Basic .NET
sobre cualquier Texto del formulario se dispare el procedimiento asociado
al botón Aceptar y la propiedad CancelButton permite que al pulsar Escape
se dispare el procedimiento asociado al botón Cancelar.
Importante: El & antes de un Texto funciona como ShortKey sobre un
control debido a que la propiedad UseMnemonic es true, si se desea que el
& funcione como un Literal configurar la propiedad UseMnemonic en False.
Además para configurar un Texto como Password hay 2 formas: establecer
la propiedad Passwordchar en un carácter o configurar la propiedad
UseSystemPasswordChar en true.
Grabar y luego ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 4.4: Ejecución del formulario Login
Luis Dueñas Pag 336
La Biblia de Visual Basic .NET
1.3. Usando Controles de Listas
Los controles de listas en Windows Forms son el cuadro de lista (clase
ListBox), cuadro combinado (clase ComboBox) y cuadro de lista con casillas
(clase CheckedListBox).
Todos tienen una colección de elementos (propiedad Items), la cual tiene
métodos comunes como Add para agregar un elemento, AddRange para
agregar una lista de elementos, Remove y RemoveAt para eliminar un
elmento por su nombre o índice y Clear para eliminar todos los elementos
de la lista.
También tienen propiedades comunes como SelectedIndex, SelectedItem y
eventos comunes como SelectedIndexChanged y SelectedValueChanged,
pero el ComboBox además posee el evento SelectionChangedCommited
que ocurre cuando un usuario selecciona un elemento de la lista
desplegable.
Para llenar los elementos de una lista lo más recomendable es cargar todos
los elementos a la vez usando el método AddRange de la propiedad Items,
pero sino se puede usar la forma clásica que es usando un bucle y llenando
cada elemento usando el método Add de la propiedad Items, pero antes de
iniciar el bucle usar el método BeginUpdate para congelar cambios en
pantalla y trabajar solo en memoria y al final después del bucle usar el
método EndUpdate para actualizar la pantalla. Esto evita el parpadeo que
ocurre al cargar las listas.
A continuación mostramos un ejemplo de cómo cargar una lista con las
culturas o países y sus respectivos idiomas usando la clase CultureInfo
ubicada en el espacio de nombres [Link]; el usuario elegirá a
que grupo pertenecerá: A o B y podrá mover elementos entre listas
mostrando siempre el total de elementos de las listas.
Demo 53
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo53.
Luis Dueñas Pag 337
La Biblia de Visual Basic .NET
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmListas
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 400, 300
StartPosition CenterScreen
Text Manejo de Listas
Label1 Name lblUsuario
AutoSize True
Location 27, 19
Text &Usuario:
TextBox1 Name txtUsuario
Location 90,12
MaxLength 20
Size 171,20
Tag Ingrese el Usuario
Label2 Name lblClave
AutoSize True
Location 27, 53
Text &Clave:
TextBox2 Name txtClave
Location 90,46
MaxLength 10
Size 171,20
Tag Ingresa la clave
UseSystemPasswordChar True
Button1 Name btnAceptar
Cursor Hand
Enabled False
Location 30, 84
Size 75, 23
Text &Aceptar
Button2 Name btnCancelar
Cursor Hand
Location 186, 84
Size 75, 23
Luis Dueñas Pag 338
La Biblia de Visual Basic .NET
Text &Cancelar
Label3 Name lblMensaje
AutoSize False
BorderStyle Fixed3D
Location 27, 123
Size 234,28
TextAlign MiddleCenter
El diseño del formulario debe quedar similar al gráfico 4.5:
Gráfico 4.5: Diseño del formulario Manejo de Listas
Escribir el siguiente código en el formulario:
Imports [Link] 'CultureInfo
Public Class frmListas
Private Sub LlenarListas(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
'Llenar la Lista de Culturas
With cboCultura
.[Link]([Link] _
([Link]))
.[Link](0, "Seleccione")
.SelectedIndex = 0
Luis Dueñas Pag 339
La Biblia de Visual Basic .NET
End With
'Llenar la Lista de Grupos
With cboGrupo
.BeginUpdate()
.[Link]("Seleccione")
.[Link]("Grupo A")
.[Link]("Grupo B")
.EndUpdate()
.SelectedIndex = 0
End With
End Sub
Private Sub AgregarElemento(ByVal sender As [Link], _
ByVal e As [Link]) Handles _
[Link],
[Link]
If [Link] > 0 Then
If [Link] = 1 Then
If [Link]([Link]) = -1 Then
If [Link]([Link]) = -1 Then
[Link]([Link])
Else
[Link]("El elemento ya fue agregado al Grupo B", _
"Aviso", [Link], _
[Link])
End If
[Link] = [Link]
Else
[Link]("El elemento ya fue agregado al Grupo A", _
"Aviso", [Link], [Link])
End If
ElseIf [Link] = 2 Then
If [Link]([Link]) = -1 Then
If [Link]([Link]) = -1 Then
[Link]([Link])
Else
[Link]("El elemento ya fue agregado al Grupo A", _
"Aviso", [Link], _
[Link])
End If
Luis Dueñas Pag 340
La Biblia de Visual Basic .NET
[Link] = [Link]
Else
[Link]("El elemento ya fue agregado al Grupo B", _
"Aviso", [Link], [Link])
End If
End If
End If
End Sub
Private Sub MostrarTotalListas()
[Link] = [Link]
[Link] = [Link]
End Sub
Private Sub MoverUnoGrupoB(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If [Link] > 0 Then
If [Link] > -1 Then
[Link]([Link])
[Link]([Link])
MostrarTotalListas()
Else
[Link]("Selecciona el elemento a mover en el Grupo A", _
"Aviso", [Link], [Link])
End If
Else
[Link]("No hay elementos que mover en el Grupo A", _
"Aviso", [Link], [Link])
End If
End Sub
Private Sub MoverTodoGrupoB(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If [Link] > 0 Then
[Link]([Link])
[Link]()
MostrarTotalListas()
Else
[Link]("No hay elementos que mover en el Grupo A", _
"Aviso", [Link], [Link])
Luis Dueñas Pag 341
La Biblia de Visual Basic .NET
End If
End Sub
Private Sub MoverUnoGrupoA(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If [Link] > 0 Then
If [Link] > -1 Then
[Link]([Link])
[Link]([Link])
MostrarTotalListas()
Else
[Link]("Selecciona el elemento a mover en el Grupo B", _
"Aviso", [Link], [Link])
End If
Else
[Link]("No hay elementos que mover en el Grupo B", _
"Aviso", [Link], [Link])
End If
End Sub
Private Sub MoverTodoGrupoA(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If [Link] > 0 Then
[Link]([Link])
[Link]()
MostrarTotalListas()
Else
[Link]("No hay elementos que mover en el Grupo B", _
"Aviso", [Link], [Link])
End If
End Sub
End Class
Nota: En el código anterior para mover todos los elementos de una lista no
se ha usado un bucle sino mediante el método AddRange de la propiedad
Items se ha agregado todos los elementos de la otra lista (mediante su
propiedad Items).
Grabar y luego ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 342
La Biblia de Visual Basic .NET
Gráfico 4.6: Ejecución del formulario Manejo de Listas
Luis Dueñas Pag 343
La Biblia de Visual Basic .NET
1.4. Usando Controles de Vistas
En Windows Forms existen 2 controles de vistas que son la vista de árbol
(clase TreeView) y la vista de lista (clase ListView). El TreeView muestra
información jerárquica y su propiedad más importante es Nodes que es una
colección de tipo TreeNodes y como toda colección de .NET Framework
tiene los métodos Add, AddRange, Remove, RemoveAt y Clear.
El TreeView tiene una propiedad ImageList que permite asociar a una lista
de imágenes, de tal forma de ver una imagen en cada nodo añadido al
árbol, además el evento mas importante de este es el AfterSelecte que
ocurre después de selecciona un nodo, éste evento posee un parámetro de
tipo TreeViewEventArgs que contiene información del nodo, como por
ejemplo el nivel, el texto que se muestra, etc.
Por su parte, el ListView es un control que presenta 5 tipos de vistas:
iconos grandes, iconos pequeños, lista, detalles y mosaicos, las cuales se
controlan mediante la propiedad View. Su propiedad más importante es
Items que es una colección de tipo ListViewItem y al igual que el TreeView
tiene los métodos Add, Add Range, Remove, RemoveAt y Clear.
El ListView también tiene propiedades que indican que imágenes van a
visualizarse en los elementos, para iconos grandes se usa la propiedad
LargeImageList y para iconos pequeños o la vista detalles se usa la
propiedad SmallImageList.
Para presentar mejor la lista de elementos en el ListView se puede usar las
propiedades GridLines, HotTracking, HoverSelection y FullRowSelect. En
cuanto a eventos uno de los más usados es el evento ColumnClick que
ocurre al dar clic a las cebeceras del ListView.
A continuación presentamos un ejemplo muy interesante que simula la
funcionalidad de un Explorador de Windows, inicialmente se carga las
unidades y se lista los directorios raíces de éstas, cuando el usuario
seleccione un directorio en el TreeView se cargarán sus subdirectorios y si
tuviera archivos estos se mostrarán el ListView en la vista detalle con 5
columnas con el nombre del archivo, extensión, tamaño, fecha de creación
y fecha de modificación.
Luis Dueñas Pag 344
La Biblia de Visual Basic .NET
Demo 54
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo54.
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario y los controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmExplorador
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 400,300
StartPosition CenterScreen
Text Explorador de Windows
SplitContainer1 Name scExplorador
Dock Fill
TreeView1 Name tvwDirectorio
(izquierda) Dock Fill
ListView1 Name lvwArchivo
(derecha) Dock Fill
FullRowSelect True
GridLines True
HotTracking True
El diseño del formulario debe quedar similar al gráfico 4.7:
Luis Dueñas Pag 345
La Biblia de Visual Basic .NET
Gráfico 4.7: Diseño del formulario Explorador de Windows
Escribir el siguiente código en el formulario:
Imports [Link]
Public Class frmExplorador
Private ils As New ImageList
Private Sub ListarUnidades(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim Ruta As String = "C:\Lduenas\NET\LibroVB2010\Imagenes\"
[Link]("PC", [Link](Ruta + "[Link]"))
[Link]("Drive", [Link](Ruta + "[Link]"))
[Link]("Folder", [Link](Ruta + "[Link]"))
[Link]("File", [Link](Ruta + "[Link]"))
[Link] = ils
With lvwArchivo
.SmallImageList = ils
.[Link]("Nombre Archivo", 300, [Link])
.[Link]("Extensión", 100, [Link])
.[Link]("Tamaño", 100, [Link])
.[Link]("Fecha Creación", 150, [Link])
.[Link]("Fecha Modificación", 150, [Link])
.View = [Link]
End With
Dim nodoPC As TreeNode = [Link] _
Luis Dueñas Pag 346
La Biblia de Visual Basic .NET
("PC", [Link], 0, 0)
Dim Unidades() As DriveInfo = [Link]
Dim nodoUnidad As TreeNode
For Each Unidad In Unidades
nodoUnidad = [Link]([Link], _
[Link]("\", ""), 1, 1)
ListarDirectorios(nodoUnidad, [Link])
Next
[Link]()
End Sub
Private Sub ListarDirectorios(ByVal nodo As TreeNode, _
ByVal Ruta As String)
Try
Dim Directorios() As String = [Link](Ruta)
For Each Directorio In Directorios
[Link]([Link](Directorio), _
[Link](Directorio), 2, 2)
ListarArchivos(Directorio)
Next
Catch ex As Exception
End Try
End Sub
Private Sub ListarArchivos(ByVal Ruta As String)
Try
Dim Archivos() As String = [Link](Ruta)
[Link]()
Dim fila As ListViewItem
Dim fi As FileInfo
For Each Archivo In Archivos
fi = New FileInfo(Archivo)
fila = [Link] _
([Link](Archivo), 3)
[Link]([Link](Archivo))
[Link]([Link])
[Link]([Link])
[Link]([Link])
Next
Catch ex As Exception
Luis Dueñas Pag 347
La Biblia de Visual Basic .NET
End Try
End Sub
Private Sub ListarSubdirectorios(ByVal sender As [Link], _
ByVal e As [Link]) _
Handles [Link]
If [Link] > 1 Then
[Link]()
Dim Ruta As String = ObtenerRuta([Link])
ListarDirectorios([Link], Ruta)
ListarArchivos(Ruta)
Else
[Link]()
End If
End Sub
Private Function ObtenerRuta(ByVal e As TreeNode) As String
Dim S As String = [Link]
If [Link] > 1 Then
S = ObtenerRuta([Link]) + "\" + S
End If
Return (S)
End Function
End Class
Nota: En el código anterior se crea dinámicamente el ImageList con 4
imágenes, las 3 primeras son para el TreeView y la cuarta para el ListView,
deberás cambiar la ruta donde se encuentran las imágenes de acuerdo a
donde se ubiquen en tu PC.
También hay que aclarar que siempre se verifica que el nivel sea mayor a 1
ya que el nivel 0 es el nodo raíz con el nombre de la PC, el nivel 1 son las
unidades y a partir del nodo 2 empiezan los directorios.
Grabar y luego ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 348
La Biblia de Visual Basic .NET
Gráfico 4.8: Ejecución del formulario Explorador de Windows
Luis Dueñas Pag 349
La Biblia de Visual Basic .NET
2. Creando Formularios MDIs, Menús, Diálogos y Barras
En esta parte mejoraremos el diseño de la interface de usuario creando
formularios MDIs, agregando menús: principal y contextual, usando
diálogos comunes de Windows como los diálogos de archivos: abrir y
guardar, diálogo de color y diálogo de fuente y finalmente, agregando
barras de herramientas y barras de estado.
2.1. Creando Formularios MDIs
Un formulario MDI es una Interface de Múltiples de Documentos, es decir
una ventana que puede contener ventanas hijas, las cuales pueden
organizarse en cascada, mosaico horizontal, mosaico vertical o como
iconos.
La mayoría de Software usan MDIs o Interface de Múltiples Documentos
para trabajar, como por ejemplo el Visual Studio, el SQL Server Managment
Studio, o los Sistemas de Información de muchas Empresas.
En Windows Forms para crear un formulario MDI solo basta configurar la
propiedad IsMdiContainer del formulario en True, esto hace que el
formulario tome un fondo gris, el cual no es un simple fondo sino en
realidad se agrega un control de tipo MdiClient que es un contenedor.
Importante: Si se desea cambiar el fondo de un formulario MDI no se
debe hacer configurando la propiedad BackColor del formulario sino la del
control MdiClient creado, por ejemplo si no hay controles en el MDI
entonces para dar un fondo rojo se debe escribir lo siguiente:
[Link](0).BackColor=[Link].
Para crear un formulario MDI hijo, es necesario configurar la propiedad
MDIParent del formulario hijo con la del padre, para reconocer si el
formulario MDI padre tiene hijos creados se usa la propiedad MDIChildren
que tiene una propiedad Length.
Finalmente, para obtener el formulario hijo que se encuentra activo se usa
la propiedad ActiveMdiChild del formulario padre.
Luis Dueñas Pag 350
La Biblia de Visual Basic .NET
A continuación un simple ejemplo que usa un formulario de Login (creado
en el Demo 52) para ingresar al formulario MDI principal el cual se muestra
degradado y con el nombre del usuario logueado.
Demo 55
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo55.
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmPrincipal
IsMdiContainer True
Size 400,300
Text Pantalla Principal del Sistema
WindowState Maximized
El diseño del formulario debe quedar similar al gráfico 4.9:
Gráfico 4.9: Diseño del formulario MDI Principal
Luis Dueñas Pag 351
La Biblia de Visual Basic .NET
Escribir el siguiente código en el formulario:
Imports [Link].Drawing2D
Public Class frmPrincipal
Public Shared Usuario As String
Private Sub GraficarMDI(ByVal sender As Object, _
ByVal e As PaintEventArgs)
Dim rec As New Rectangle(0, 0, [Link], [Link])
Dim deg As New LinearGradientBrush(rec, [Link], _
[Link], [Link])
[Link](deg, rec)
[Link]("Usuario actual: " + Usuario, _
New Font("Arial", 50), [Link], 300, 300)
End Sub
Private Sub IniciarConfiguracion(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim oFondo As MdiClient = [Link](0)
AddHandler [Link], AddressOf GraficarMDI
End Sub
End Class
Agregar el formulario de Login creado en el Demo 52: seleccionar el
projecto, del menú “Project”, seleccionar “Add Existing Item”, navegar
hasta la carpeta Demo 52 y seleccionar “[Link]”.
Modificar el código del formulario Login como sigue:
Imports [Link]
Public Class frmLogin
Private contador As Integer
Private Sub HabilitarBotonAceptar(ByVal sender As [Link], _
ByVal e As [Link]) Handles _
[Link], [Link]
[Link] = ([Link] <> "" _
AndAlso [Link] <> "")
End Sub
Luis Dueñas Pag 352
La Biblia de Visual Basic .NET
Private Sub MostrarMensaje(ByVal sender As Object, _
ByVal e As [Link]) Handles _
[Link], [Link]
[Link] = [Link]
End Sub
Private Sub BorrarMensaje(ByVal sender As Object, _
ByVal e As [Link]) Handles _
[Link], [Link]
[Link] = ""
End Sub
Private Sub Aceptar(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim Archivo As String = _
"C:\Lduenas\NET\LibroVB2010\Archivos\[Link]"
If [Link](Archivo) Then
Dim Encontro As Boolean = False
Using fs As New FileStream(Archivo, _
[Link], [Link], [Link])
Using sr As New StreamReader(fs)
Dim Usuario() As String
Do While Not [Link]
Usuario = [Link](",")
If [Link] = 2 Then
If Usuario(0) = [Link] _
AndAlso Usuario(1) = [Link] Then
[Link] = Usuario(0)
Encontro = True
Exit Do
End If
End If
Loop
contador += 1
End Using
End Using
If Encontro Then
[Link]()
[Link]()
Luis Dueñas Pag 353
La Biblia de Visual Basic .NET
Else
[Link]("Login Invalido", "Aviso", _
[Link], [Link])
End If
If contador = 3 Then
[Link]("Acceso Denegado", "Aviso", _
[Link], [Link])
[Link]()
End If
End If
End Sub
Private Sub Cancelar(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link]()
End Sub
End Class
Nota: No olvidar que el Login usa un archivo de texto que se encuentra en
una cierta ruta.
Configurar el formulario de inicio y la forma del cierre: seleccionar el
projecto, dar clic derecho “Properties” y aparecerá la figura siguiente.
Luis Dueñas Pag 354
La Biblia de Visual Basic .NET
Gráfico 4.10: Ficha de configuración de la aplicación
En la opción “Startup form” elegir frmLogin y en “Shutdown mode”
elegir When last form closes.
Grabar y ejecutar la aplicación.
Aparecerá el formulario Login primero, ingresar el usuario y la clave y
se mostrará el MDI como en la siguiente figura.
Luis Dueñas Pag 355
La Biblia de Visual Basic .NET
Gráfico 4.11: Ejecución del formulario MDI Principal
Luis Dueñas Pag 356
La Biblia de Visual Basic .NET
2.2. Creando Menús
Existen 2 tipos de menús en las aplicaciones Windows: uno es el menú
principal (clase MenuStrip) y el otro es el menú contextual (clase Context
MenuStrip). Ambos menús tienen una colección de elementos de tipo
ToolStripMenuItem.
Asi como todos los controles de Windows Forms, existen 2 formas de crear
ambos tipos de menús: en tiempo de diseño y en tiempo de ejecución o
dinámicamente.
Para crear un menú Principal en tiempo de diseño arrastrar el control
MenuStrip, llenar las opciones del menú directamente en el diseñador del
formulario, luego configurar las propiedades de cada opción como su
nombre (Name), imagen (Image), tecla de acceso directo (ShortCutKeys) y
luego programar en el evento clic de cada opción el código respectivo.
Para crear un menú contextual el procedimiento es similar que para el
menú principal, es decir, arrastrar el control ContextMenuStrip, llenar sus
opciones, configurar sus propiedades y programar las opciones, la
diferencia es que para que se muestre al dar clic derecho sobre un cierto
control o sobre el formulario, es necesario configurar la propiedad “Context
MenuStrip” del control o formulario donde se va a visualizar el menú
desplegable.
A continuación presentamos un par de ejemplos muy interesantes que
crean menús dinámicamente; el primero el Demo 56 crea a partir de un
archivo XML las opciones del menú principal en un formulario MDI
mediante el objeto XmlDocument de XML DOM, además ejecuta 3 tipos de
acciones al seleccionarse una opción: abre un formulario si el prefijo de la
acción inicia con “frm”, ejecuta un programa si el sufijo es “.exe” y en caso
contrario ejecuta un procedimiento con el nombre de la acción, para
realizar esto último usamos “Reflection”.
El segundo ejemplo, el Demo 57 crea un menú contextual dinámicamente,
este se muestra al dar clic derecho sobre cuadros de textos para
seleccionar una fecha de un calendario y llenar los textos en vez de escribir
la fecha.
Luis Dueñas Pag 357
La Biblia de Visual Basic .NET
Demo 56
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo56.
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmPrincipal
IsMdiContainer True
Size 450,300
Text Crear Menú Principal Dinamica
mente desde Archivo XML
WindowState Maximized
El diseño del formulario debe quedar similar al gráfico 4.12:
Gráfico 4.12: Diseño del formulario MDI Principal
Luis Dueñas Pag 358
La Biblia de Visual Basic .NET
Agregar un archivo XML: del menú “Project”, seleccionar “Add New
Item” y en la sección “Data” elegir “XML File” y escribir como nombre:
“[Link]”.
Escribir en el archivo XML las opciones que iran en el menú principal:
<?xml version="1.0" encoding="utf-8" ?>
<Menus>
<Menu Nombre="Mantenimiento">
<Menu Nombre="Categorias" Accion="frmCategorias"/>
<Menu Nombre="Clientes" Accion="frmClientes"/>
<Menu Nombre="Proveedores">
<Menu Nombre="Nacionales" Accion="frmProveedoresNacionales"/>
<Menu Nombre="Extranjeros" Accion="frmProveedoresExtranjeros"/>
</Menu>
</Menu>
<Menu Nombre="Procesos">
<Menu Nombre="Crear Comprobantes">
<Menu Nombre="Factura" Accion="frmCrearFactura"/>
<Menu Nombre="Boleta" Accion="frmCrearBoleta"/>
</Menu>
<Menu Nombre="Planillas">
<Menu Nombre="Empleados" Accion="frmPlanillaEmpleados"/>
<Menu Nombre="Obreros" Accion="frmPlanillaObreros"/>
</Menu>
</Menu>
<Menu Nombre="Programas">
<Menu Nombre="Windows">
<Menu Nombre="Bloc de Notas" Accion="[Link]"/>
<Menu Nombre="Calculadora" Accion="[Link]"/>
<Menu Nombre="Explorador" Accion="[Link]"/>
</Menu>
<Menu Nombre="Office">
<Menu Nombre="Word" Accion="[Link]"/>
<Menu Nombre="Excel" Accion="[Link]"/>
<Menu Nombre="Power Point" Accion="[Link]"/>
</Menu>
</Menu>
<Menu Nombre="Salir" Accion="Salir">
</Menu>
</Menus>
Luis Dueñas Pag 359
La Biblia de Visual Basic .NET
Nota: El archivo XML define un documento XML el cual tiene reglas de
sintáxis obligatorias sino se genera un error, entre ellas: debe existir un
solo elemento raíz, toda etiqueta de inicio debe tener un fin, es case
sensitive, atributos deben estar entre comillas simples o dobles.
En el archivo creado “Menus” y “Menu” son conocidos como elementos y
“Nombre” y “Accion” son conocidos como atributos.
Agregar los siguientes formularios al proyecto: frmCategorias,
frmClientes, frmProveedoresNacionales, frmProveedoresExtranjeros,
frmCrearFactura, frmCrearBoleta, frmPlanillaEmpleados y frmPlanilla
Obreros.
Nota: Todos los formularios agregados no es necesario que contengan
controles solo es para probar que cargen.
Modificar el código del formulario Principal como sigue:
Imports [Link] 'XmlDocument
Imports [Link] 'Assembly
Public Class frmPrincipal
Private Sub CargarXml(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim ArchivoXml As String = _
"C:\Lduenas\NET\LibroVB2010\Demo56\[Link]"
Dim oDocXml As New XmlDocument
[Link](ArchivoXml)
Dim mnuPrincipal As New MenuStrip
For Each oNodo As XmlNode In _
[Link]
Dim oMenu As New ToolStripMenuItem _
([Link]("Nombre").Value)
EjecutarAccion(oNodo, oMenu)
[Link](oMenu)
CrearMenu(oNodo, oMenu)
Next
[Link](mnuPrincipal)
End Sub
Luis Dueñas Pag 360
La Biblia de Visual Basic .NET
Private Sub CrearMenu(ByVal oNodoRaiz As XmlNode, _
ByVal oMenuRaiz As ToolStripMenuItem)
For Each oNodo As XmlNode In [Link]
Dim oMenu As New ToolStripMenuItem _
([Link]("Nombre").Value)
EjecutarAccion(oNodo, oMenu)
[Link](oMenu)
CrearMenu(oNodo, oMenu)
Next
End Sub
Private Sub EjecutarAccion(ByVal oNodo As XmlNode, _
ByVal oMenu As ToolStripMenuItem)
If [Link]("Accion") IsNot Nothing _
AndAlso [Link]("Accion").Value <> "" Then
Dim Accion As String = [Link]("Accion").Value
[Link] = [Link](0, [Link])
If [Link]("frm") Then
AddHandler [Link], AddressOf AbrirForm
ElseIf [Link](".exe") Then
AddHandler [Link], AddressOf EjecutarPrograma
Else
AddHandler [Link], AddressOf EjecutarProcedimiento
End If
End If
End Sub
Private Sub AbrirForm(ByVal sender As Object, _
ByVal e As EventArgs)
Dim Ensamblado As Assembly = _
[Assembly].GetEntryAssembly
Dim Tipo As Type = _
[Link]("Demo56." + [Link])
If Tipo IsNot Nothing Then
Dim obj As Object = _
[Link](Tipo)
If TypeOf obj Is Form Then
Dim frm As Form = CType(obj, Form)
[Link] = Me
Luis Dueñas Pag 361
La Biblia de Visual Basic .NET
[Link]()
End If
End If
End Sub
Private Sub EjecutarProcedimiento(ByVal sender As Object, _
ByVal e As EventArgs)
Dim obj As Type = [Link]
If obj IsNot Nothing Then
Dim X As Object = _
[Link](obj)
Dim metodo As MethodInfo = _
[Link]([Link])
If metodo IsNot Nothing Then _
[Link](X, Nothing)
End If
End Sub
Private Sub EjecutarPrograma(ByVal sender As Object, _
ByVal e As EventArgs)
[Link]([Link])
End Sub
Public Sub Salir()
[Link]("Hasta la próxima")
[Link]()
End Sub
End Class
Nota: Para cargar el archivo XML como un árbol de nodos se usa el
método Load de la clase XmlDocument, la propiedad DocumentElement de
esta clase representa al elemento raíz en nuestro caso Menus y childNodes
a todos los nodos hijos en nuestro caso Menu. Primero se carga las
opciones del menú principal y luego las de nivel secundario.
Importante: Al igual que otros ejemplos del libro hacemos uso de la
recursividad para volver a ejecutar un procedimiento, en este caso la rutina
CrearMenu se llama mientras existan nodos hijos o menus en el XML.
Luis Dueñas Pag 362
La Biblia de Visual Basic .NET
También es importante mencionar que en la propiedad Tag del menú se ha
guardado la acción que tiene el nombre del formulario a abrir, el nombre
del proceso a ejecutar si es un programa o el nombre del procedimiento a
ejecutar.
Grabar y luego ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 4.13: Ejecución del formulario MDI Principal
Luis Dueñas Pag 363
La Biblia de Visual Basic .NET
Demo 57
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo57.
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmRegistroFechas
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Size 300, 300
StartPosition CenterScreen
Text Crear Menú Contextual
Dinamicamente
Label1 Name lblNombre
AutoSize True
Location 22, 23
Text Nombre del Empleado:
TextBox1 Name txtNombre
Location 25,39
Size 235,20
Label2 Name lblFechaNacimiento
AutoSize True
Location 22, 80
Text Fecha de Nacimiento:
TextBox2 Name txtFechaNacimiento
Location 25,96
Size 111,20
Label3 Name lblFechaIngreso
AutoSize True
Location 22, 138
Text Fecha de Ingreso:
TextBox3 Name txtFechaIngreso
Location 25,154
Size 111,20
Luis Dueñas Pag 364
La Biblia de Visual Basic .NET
El diseño del formulario debe quedar similar al gráfico 4.14:
Gráfico 4.14: Diseño del formulario Registro de Fechas
Escribir el siguiente código en el formulario:
Public Class frmRegistroFechas
Private Sub CrearMenuContextualCalendario(ByVal sender As _
[Link], ByVal e As [Link]) Handles [Link]
Dim mcCalendario As New MonthCalendar
Dim host As New ToolStripControlHost(mcCalendario)
Dim mnuCalendario As New ContextMenuStrip
[Link](host)
[Link] = mnuCalendario
[Link] = mnuCalendario
AddHandler [Link], AddressOf AsignarFecha
End Sub
Private Sub AsignarFecha(ByVal sender As Object, ByVal e As EventArgs)
Dim FechaSeleccionada As Date = CType(sender, _
MonthCalendar).SelectionStart
CType([Link], ContextMenuStrip).Close()
[Link] = FechaSeleccionada
End Sub
End Class
Luis Dueñas Pag 365
La Biblia de Visual Basic .NET
Importante: El ToolStripControlHost permite agregar cualquier tipo de
control a un menú, no solo un calendario, sino podría ser una grilla, un
control de usuario, etc.
Grabar y luego ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 4.15: Ejecución del formulario Registro de Fechas
Nota: Para que aparezca el calendario dar clic derecho sobre el cuadro de
texto de la fecha de nacimiento o la fecha de ingreso, seleccionar un dia y
se mostrará sobre el cuadro de texto la fecha seleccionada.
Luis Dueñas Pag 366
La Biblia de Visual Basic .NET
2.3. Usando Diálogos de Windows
En Windows Forms tenemos 5 diálogos comunes de Windows que son: el
diálogo de abrir archivo (clase OpenFileDialog), el diálogo de guardar
archivo (clase SaveFileDialog), el diálogo de mostrar directorios (clase
FolderBrowserDialog), el diálogo de Color (clase ColorDialog) y el diálogo
de Fuente (clase FontDialog).
Todos los diálogos tienen el método ShowDialog que permite mostrar el
diálogo, los diálogos de archivos: OpenFileDialog y SaveFileDialog
comparten propiedades comunes como el Title que configura el titulo del
diálogo, Filter que especifica los tipos de archivos a mostrar, FileName que
indica el archivo seleccionado, etc.
Por su parte la propiedad más importante del diálogo de color o
ColorDialog es la propiedad “Color” que representa el color seleccionado
del diálogo, igualmente el diálogo de fuente o FontDialog tiene como
propiedad mas importante la propiedad “Font” que devuelve la fuente
seleccionada del diálogo y finalmente el diálogo de mostrar directorios o
FolderBrowserDialog tiene la propiedad “SelectedPath” que representa la
ruta del directorio seleccionado en el diálogo.
A continuación un ejemplo de cómo trabajar con los diálogos de fuente y
color para configurar una marquesina o mensaje en movimiento a través
de un menú de configuración.
Demo 58
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo58.
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmMarquesina
Luis Dueñas Pag 367
La Biblia de Visual Basic .NET
Size 300, 300
Text Marquesina Configurable
WindowState Maximized
MenuStrip1 Name mnuPrincipal
MenuItem1 Name mnuConfiguracion
Text Configuracion
MenuItem1.1 Name mnuIniciar
Text Iniciar
MenuItem1.2 Name mnuMensaje
Text Mensaje
MenuItem1.3 Name mnuFuente
Text Fuente
MenuItem1.4 Name mnuColor
Text Color
El diseño del formulario debe quedar similar al gráfico 4.16:
Gráfico 4.16: Diseño del formulario Marquesina Configurable
Escribir el siguiente código en el formulario:
Public Class frmMarquesina
Private lblMensaje As New Label
Private WithEvents tmrAnimar As New Timer
Private Sub ConfiguracionPorDefecto(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Luis Dueñas Pag 368
La Biblia de Visual Basic .NET
With lblMensaje
.AutoSize = True
.Text = "Visual Basic 2010"
.Font = New Font("Arial", 50)
.ForeColor = [Link]
End With
[Link](lblMensaje)
[Link] = New Point(-[Link], 300)
[Link] = 100
End Sub
Private Sub HabilitarOpciones(ByVal sender As [Link], _
ByVal e As [Link]) Handles _
[Link]
Dim habilitado As Boolean = [Link]("Iniciar")
[Link] = habilitado
[Link] = habilitado
[Link] = habilitado
End Sub
Private Sub IniciarAnimacion(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If [Link] = "Iniciar" Then
[Link] = True
[Link]()
[Link] = "Detener"
Else
[Link]()
[Link] = False
[Link] = "Iniciar"
End If
End Sub
Private Sub tmrAnimar_Tick(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
If [Link].X < [Link] Then
[Link] = New Point([Link].X + 10, _
[Link].Y)
Else
[Link] = New Point(-[Link], 300)
Luis Dueñas Pag 369
La Biblia de Visual Basic .NET
End If
End Sub
Private Sub CambiarMensaje(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link] = InputBox("Nuevo Mensaje:", _
"Cambiar Mensaje", [Link])
[Link] = New Point(-[Link], 300)
End Sub
Private Sub CambiarFuente(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim fd As New FontDialog
If [Link] = [Link] Then
[Link] = [Link]
[Link] = New Point(-[Link], 300)
End If
End Sub
Private Sub CambiarColor(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim cd As New ColorDialog
If [Link] = [Link] Then
[Link] = [Link]
End If
End Sub
End Class
Nota: En el código anterior solo se habilita las opciones de configuración
del mensaje, fuente y color mientras el mensaje no este en movimiento, es
decir para configurar la marquesina hay que detenerla.
Grabar y luego ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 370
La Biblia de Visual Basic .NET
Gráfico 4.17: Ejecución del formulario Marquesina Configurable
Luis Dueñas Pag 371
La Biblia de Visual Basic .NET
2.4. Agregando Barras
En esta última parte de mejorar la interface de usuario veremos como
agregar una barra de herramientas (clase ToolStrip) y barra de estado
(clase StatusStrip).
Ambas barras se componen de una colección de elementos de tipo
ToolStripItem, que podría ser un botón o ToolStripButton, un separador o
ToolStripSeparator, una etiqueta o ToolStripLabel, un Combo o
ToolStripComboBox, un texto o ToolStripTextBox, etc. Cada uno de estos
elementos (ToolStripItem) pueden tener un texto (propiedad Text), una
imagen (propiedad Image), una mensaje al pasar el mouse (propiedad
ToolTipText), etc. Para programar la barra de herramientas se escribe el
código en el evento Click de cada opción o ToolStripItem.
La diferencia entre ambas barras es que la barra de herramientas puede
tener cualquier objeto de tipo ToolStripItem, en cambio la barra de estado
solo puede tener etiquetas, barras de progreso, botón desplegable y botón
de división.
A continuación presentamos un ejemplo completo de cómo mejorar la
interface de usuario usando MDIs, Menús principal y contextual, diálogos
de Windows y barras de herramientas y de estado. Este ejemplo se trata
de un Editor de Documentos de Texto Enriquecido (RTF) similar al
WordPad el cual permite crear un documento, abrir, guardar, hacer
preview, configurar pagina, imprimir, copiar, cortar, pegar, cambiar fuente,
color de fondo, ejecutar programas de Windows y de Office y organizar
ventanas hijas dentro del MDI padre.
Demo 59
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo59.
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario de acuerdo a la siguiente tabla:
Luis Dueñas Pag 372
La Biblia de Visual Basic .NET
Objeto Propiedad Valor
Form1 Name frmEditor
Size 500, 300
IsMdiContainer True
Text Editor de Documentos
de Texto Enriquecido
WindowState Maximized
MenuStrip1 Name mnuPrincipal
MdiWindowListItem mnuVentana
MenuItem1 Name mnuArchivo
Text Archivo
MenuItem1.1 Name mnuNuevo
Image [Link]
ShortCutKeys Ctrl + N
Text &Nuevo
MenuItem1.2 Name mnuAbrir
Image [Link]
ShortCutKeys Ctrl + A
Text &Abrir
MenuItem1.3 Name mnuGuardar
Image [Link]
ShortCutKeys Ctrl + G
Text &Guardar
MenuItem1.4 Name mnuLinea
Text -
MenuItem1.5 Name mnuPreview1
Text Preview 1
MenuItem1.6 Name mnuPreview2
Text Preview 2
MenuItem1.7 Name mnuPageSetup
Text Page Setup
MenuItem1.8 Name mnuPrint
ShortCutKeys Ctrl + P
Text &Print
MenuItem2 Name mnuEdicion
Text Edición
MenuItem2.1 Name mnuCopiar
Image [Link]
ShortCutKeys Ctrl + C
Text &Copiar
Luis Dueñas Pag 373
La Biblia de Visual Basic .NET
MenuItem2.2 Name mnuCortar
Image [Link]
ShortCutKeys Ctrl + X
Text Co&rtar
MenuItem2.3 Name mnuPegar
Image [Link]
ShortCutKeys Ctrl + V
Text &Pegar
MenuItem3 Name mnuFormato
Text Formato
MenuItem3.1 Name mnuFuente
Text Fuente
MenuItem3.2 Name mnuColorFondo
Text Color de Fondo
MenuItem4 Name mnuProgramas
Text Programas
MenuItem4.1 Name mnuWindows
Text Windows
MenuItem4.1.1 Name mnuCalculadora
Tag Calc
Text Calculadora
MenuItem4.1.2 Name mnuBlocDeNotas
Tag Notepad
Text Bloc de Notas
MenuItem4.1.3 Name mnuExplorador
Tag Explorer
Text Explorador
MenuItem4.2 Name mnuOffice
Text Office
MenuItem4.2.1 Name mnuWord
Tag WinWord
Text Word
MenuItem4.2.2 Name mnuExcel
Tag Excel
Text Excel
MenuItem4.2.3 Name mnuInternetExplorer
Tag IExplore
Text Internet Explorer
MenuItem5 Name mnuVentana
Text Ventana
MenuItem5.1 Name mnuCascada
Tag 0
Luis Dueñas Pag 374
La Biblia de Visual Basic .NET
Text Cascada
MenuItem5.2 Name mnuMosaicoHorizontal
Tag 1
Text Mosaico Horizontal
MenuItem5.3 Name mnuMosaicoVertical
Tag 2
Text Mosaico Vertical
MenuItem5.4 Name mnuOrganizarIconos
Tag 3
Text Organizar Iconos
MenuItem6 Name mnuSalir
Text Salir
ToolStrip1 Name tsEditor
ToolStripButton1 Name tsbNuevo
Image [Link]
Text Nuevo
ToolTipText Nuevo
ToolStripButton2 Name tsbAbrir
Image [Link]
Text Abrir
ToolTipText Abrir
ToolStripButton3 Name tsbGuardar
Image [Link]
Text Guardar
ToolTipText Guardar
ToolStripSeparator1 Name tssArchivo
ToolStripButton4 Name tsbCopiar
Image [Link]
Text Copiar
ToolTipText Copiar
ToolStripButton5 Name tsbCortar
Image [Link]
Text Cortar
ToolTipText Cortar
ToolStripButton6 Name tsbPegar
Image [Link]
Text Pegar
ToolTipText Pegar
ToolStripSeparator2 Name tssEdicion
ToolStripButton7 Name tsbSalir
Image [Link]
Text Salir
Luis Dueñas Pag 375
La Biblia de Visual Basic .NET
ToolTipText Salir
StatusStrip1 Name ssEditor
ToolStripStatusLabel1 Name tsslArchivo
AutoSize False
Size 121, 17
Text
ToolStripStatusLabel2 Name tsslFechaHora
AutoSize False
Size 121, 17
Text
PrintDocument1 Name pdEditor
El diseño del formulario debe quedar similar al gráfico 4.18:
Gráfico 4.18: Diseño del formulario MDI Editor
Agregar el formulario de Login creado en el Demo 55: seleccionar el
projecto, del menú “Project”, seleccionar “Add Existing Item”, navegar
hasta la carpeta Demo 55 y seleccionar “[Link]”.
Modificar el código del formulario Login como sigue:
Imports [Link]
Luis Dueñas Pag 376
La Biblia de Visual Basic .NET
Public Class frmLogin
Private contador As Integer
Private Sub HabilitarBotonAceptar(ByVal sender As [Link], _
ByVal e As [Link]) Handles _
[Link], [Link]
[Link] = ([Link] <> "" _
AndAlso [Link] <> "")
End Sub
Private Sub MostrarMensaje(ByVal sender As Object, _
ByVal e As [Link]) Handles _
[Link], [Link]
[Link] = [Link]
End Sub
Private Sub BorrarMensaje(ByVal sender As Object, _
ByVal e As [Link]) Handles _
[Link], [Link]
[Link] = ""
End Sub
Private Sub Aceptar(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim Archivo As String = _
"C:\Lduenas\NET\LibroVB2010\Archivos\[Link]"
If [Link](Archivo) Then
Dim Encontro As Boolean = False
Using fs As New FileStream(Archivo, _
[Link], [Link], [Link])
Using sr As New StreamReader(fs)
Dim Usuario() As String
Do While Not [Link]
Usuario = [Link](",")
If [Link] = 2 Then
If Usuario(0) = [Link] _
AndAlso Usuario(1) = [Link] Then
Encontro = True
Exit Do
End If
Luis Dueñas Pag 377
La Biblia de Visual Basic .NET
End If
Loop
contador += 1
End Using
End Using
If Encontro Then
[Link]()
[Link]()
Else
[Link]("Login Invalido", "Aviso", _
[Link], [Link])
End If
If contador = 3 Then
[Link]("Acceso Denegado", "Aviso", _
[Link], [Link])
[Link]()
End If
End If
End Sub
Private Sub Cancelar(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link]()
End Sub
End Class
Agregar un nuevo formulario: seleccionar el projecto, del menú
“Project”, seleccionar “Add Windows Forms”, escribir como nombre
“[Link]”.
Configurar el formulario Documento de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmDocumento
Size 300, 300
Text Documento
ContextMenuStrip1 Name mnuEdicion
ToolStripMenuItem1 Name mnuCopiar
Image [Link]
Text Copiar
Luis Dueñas Pag 378
La Biblia de Visual Basic .NET
ToolStripMenuItem2 Name mnuCortar
Image [Link]
Text Cortar
ToolStripMenuItem3 Name mnuPegar
Image [Link]
Text Pegar
RichTextBox1 Name rtbDocumento
ContextMenuStrip mnuEdicion
Dock Fill
El diseño del formulario debe quedar similar al gráfico 4.19:
Gráfico 4.19: Diseño del formulario Documento
Escribir el siguiente código en el formulario Documento:
Public Class frmDocumento
Private Sub Copiar(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link]([Link])
End Sub
Private Sub Cortar(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link]([Link])
Luis Dueñas Pag 379
La Biblia de Visual Basic .NET
[Link] = ""
End Sub
Private Sub Pegar(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link] = [Link]
End Sub
End Class
Regresar al formulario Editor y escribir el siguiente código:
Imports [Link].Drawing2D 'LinearGradientBrush
Imports [Link] 'Path
Public Class frmEditor
Private NDoc As Integer
Private WithEvents fd As New FontDialog
Private Sub IniciarCarga(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link]()
Dim X As Control
For Each X In [Link]
If TypeOf X Is MdiClient Then
Dim Area As MdiClient = CType(X, MdiClient)
AddHandler [Link], AddressOf Graficar
End If
Next
[Link] = [Link]
[Link] = [Link]
End Sub
Private Sub Graficar(ByVal sender As Object, _
ByVal e As [Link])
Dim rec As Rectangle = [Link]
Dim deg As New LinearGradientBrush(rec, [Link], _
[Link], [Link])
[Link](deg, rec)
[Link]("El Poder de .NET", _
New Font("Arial", 100), [Link], 100, 200)
End Sub
Luis Dueñas Pag 380
La Biblia de Visual Basic .NET
Private Sub EjecutarPrograma(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link], _
[Link], [Link], [Link], _
[Link], [Link]
[Link]([Link]("{0}.exe", [Link]))
End Sub
Private Sub Nuevo(ByVal sender As [Link], _
ByVal e As [Link]) Handles _
[Link], [Link]
NDoc += 1
Dim oDoc As New frmDocumento
[Link] = [Link]("Documento {0}", NDoc)
[Link] = Me
[Link]()
[Link] = [Link]
End Sub
Private Sub OrganizarVentanas(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link], _
[Link], [Link], _
[Link]
[Link]([Link])
End Sub
Private Sub Abrir(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link], _
[Link]
Dim ofd As New OpenFileDialog
[Link] = "Selecciona archivo rtf"
[Link] = "Archivos de formato enriquecido|*.rtf"
If [Link]() = [Link] Then
If [Link] = 0 Then [Link]()
Dim rtb As RichTextBox = [Link](0)
[Link]([Link], [Link])
[Link] = [Link]([Link])
[Link] = [Link]
End If
End Sub
Luis Dueñas Pag 381
La Biblia de Visual Basic .NET
Private Sub Guardar(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link], _
[Link]
Dim sfd As New SaveFileDialog
[Link] = "Selecciona archivo rtf"
[Link] = "Archivos de formato enriquecido|*.rtf"
If [Link]() = [Link] Then
Dim rtb As RichTextBox = [Link](0)
[Link]([Link], [Link])
[Link] = [Link]([Link])
[Link] = [Link]
End If
End Sub
Private Sub HabilitarMenusArchivo(ByVal sender As Object, _
ByVal e As [Link]) Handles _
[Link]
Dim Habilitado As Boolean = _
([Link] > 0)
[Link] = Habilitado
[Link] = Habilitado
[Link] = Habilitado
[Link] = Habilitado
[Link] = Habilitado
End Sub
Private Sub CrearPagina(ByVal sender As [Link], _
ByVal e As [Link]) _
Handles [Link]
Dim rtb As RichTextBox = [Link](0)
Dim X As Integer = [Link]
Dim Y As Integer = [Link]
[Link]([Link], [Link], _
New SolidBrush([Link]), X, Y)
End Sub
Private Sub PreviewConControl(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim frm As New Form
Luis Dueñas Pag 382
La Biblia de Visual Basic .NET
[Link] = [Link]
[Link] = "Preview del Documento"
Dim ppc As New PrintPreviewControl
[Link] = pdEditor
[Link] = [Link]
[Link](ppc)
[Link]()
End Sub
Private Sub PreviewConDialogo(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim ppd As New PrintPreviewDialog
[Link] = pdEditor
[Link]()
End Sub
Private Sub PageSetup(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim psd As New PageSetupDialog
[Link] = pdEditor
[Link]()
End Sub
Private Sub Print(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim pd As New PrintDialog
[Link] = True
[Link] = True
[Link] = True
[Link] = True
[Link] = True
[Link] = pdEditor
If [Link]() = _
[Link] Then
[Link]()
End If
End Sub
Private Sub HabilitarMenuEdicion(ByVal sender As Object, _
ByVal e As [Link]) Handles _
Luis Dueñas Pag 383
La Biblia de Visual Basic .NET
[Link]
Dim Habilitado As Boolean = _
([Link] > 0)
If Not Habilitado Then
[Link] = False
[Link] = False
[Link] = False
Else
Dim rtb As RichTextBox = _
[Link](0)
Habilitado = ([Link] <> "")
[Link] = Habilitado
[Link] = Habilitado
[Link] = [Link] <> ""
End If
End Sub
Private Sub Copiar(ByVal sender As [Link], _
ByVal e As [Link]) Handles _
[Link], [Link]
Dim rtb As RichTextBox = [Link](0)
[Link]([Link])
End Sub
Private Sub Cortar(ByVal sender As [Link], _
ByVal e As [Link]) Handles _
[Link], [Link]
Dim rtb As RichTextBox = [Link](0)
[Link]([Link])
[Link] = ""
End Sub
Private Sub Pegar(ByVal sender As [Link], _
ByVal e As [Link]) Handles _
[Link], [Link]
Dim rtb As RichTextBox = [Link](0)
[Link] = [Link]
End Sub
Private Sub HabilitarMenuFormato(ByVal sender As Object, _
Luis Dueñas Pag 384
La Biblia de Visual Basic .NET
ByVal e As [Link]) Handles _
[Link]
Dim Habilitado As Boolean = ([Link] > 0)
[Link] = Habilitado
[Link] = Habilitado
End Sub
Private Sub CambiarFuente()
Dim rtb As RichTextBox = [Link](0)
If [Link] <> "" Then
[Link] = [Link]
[Link] = [Link]
Else
[Link] = [Link]
[Link] = [Link]
End If
End Sub
Private Sub Fuente(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link] = True
[Link] = True
[Link] = True
If [Link]() = [Link] Then
CambiarFuente()
End If
End Sub
Private Sub AplicarFuente(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
CambiarFuente()
End Sub
Private Sub MostrarAyuda(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
[Link](Me, "[Link]
End Sub
Private Sub ColorDeFondo(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Luis Dueñas Pag 385
La Biblia de Visual Basic .NET
Dim cd As New ColorDialog
If [Link]() = [Link] Then
Dim rtb As RichTextBox = [Link](0)
[Link] = [Link]
End If
End Sub
Private Sub Salir(ByVal sender As [Link], _
ByVal e As [Link]) Handles _
[Link], [Link]
[Link]()
End Sub
End Class
Nota: En el código anterior se usa la propiedad Tag de los menús de
programas para especificar el programa a abrir y la propiedad tag de los
menús de ventanas para indicar el tipo de organización de las ventanas.
Configurar el formulario de inicio y la forma del cierre: seleccionar el
projecto, dar clic derecho “Properties” y aparecerá una ventana similar
a la mostrada anteriormente en la figura 4.10.
En la opción “Startup form” elegir frmLogin y en “Shutdown mode”
elegir When last form closes.
Grabar y ejecutar la aplicación. Aparecerá el formulario Login primero,
ingresar el usuario y clave y se mostrará el MDI como en la figura 4.20.
Luis Dueñas Pag 386
La Biblia de Visual Basic .NET
Gráfico 4.20: Ejecución del formulario MDI Editor
Luis Dueñas Pag 387
La Biblia de Visual Basic .NET
3. Usando el Control DataGridView
El control DataGridView es el control mas usado en las aplicaciones de
Windows Forms debido a su facilidad para mostrar datos y su flexibilidad
para presentar información de todo tipo: texto, números, fechas, gráficos,
etc. En este parte examinaremos mas a fondo dicho control sobre todo
para presentar información personalizada.
El DataGridView tiene un conjunto de propiedades que inician con Allow
User que permiten configurar varias características como permitir adicionar
registros (AllowUserToAddRows), permitir eliminar registros (AllowUserTo
DeleteRows), permitir ordenar columnas (AllowUserToOrderColumns),
permitir cambiar tamaño de columnas y filas (AllowUserToResizeColumns y
AllowUserToResizeRows).
También tiene propiedades que permiten ajustar automáticamente el
tamaño de las columnas o filas al dato mas ancho o alto, estas son
AutoSizeColumnsMode y AutoSizeRowsMode, las cuales deben configurarse
en AllCells.
Para indicar el modo de selección si es por celda, fila o columna se usa la
propiedad SelectionMode, por ejemplo para pintar todo el registro o fila
configurar su valor en FullRowSelect. Por defecto, se pueden seleccionar
varias filas en la grilla, si se desea que solo una este seleccionada
configurar la propiedad MultiSelect en false.
En cuanto a los eventos del DataGridView los más usados son el
CellContentClick que ocurre al dar clic a una celda, también el
SelectionChanged que ocurre al cambiar de fila. Si deseas formatear celdas
o graficar se puede usar el evento CellFormatting y si se desea repintar las
celdas por ejemplo para cambiar su apariencia usar el evento CellPaint.
Finalmente el DataGridView tiene 2 formas de trabajar: una es enlazado a
datos o automático que se usa cuando la cantidad de registros no es
demasiado y la otra es el modo virtual o manual que se usa para
especificar solo un numero de columnas y filas deseadas. Para ver más
información sobre el DataGridView consultar la referencia 24 al final del
libro.
Luis Dueñas Pag 388
La Biblia de Visual Basic .NET
3.1. Personalizando Columnas en el DataGridView
La forma más común de trabajar es enlazar el DataGridView a un origen de
datos a través de la propiedad DataSource que por defecto muestra todas
las columnas del origen de datos ya que la propiedad AutoGenerate
Columns esta en “True” y crea automáticamente las columnas de la grilla
infiriendo para los datos lógicos una columna de tipo check y para el resto
textos.
Para personalizar las columnas del DataGridView hay que configurar la
propiedad AutoGenerateColumns en “False”, luego enlazar la grilla y
después crear las columnas personalizadas y agregarlas al DataGridView.
Existen varios tipos de columnas: DataGridViewTextBoxColumn que
representa datos de cadenas, números o fechas; DataGridViewCheckBox
Column que se usa para datos lógicos; DataGridViewComboBoxColumn
para mostrar listas desplegables; DataGridViewButtonColumn para mostrar
botones de comandos y DataGridViewLinkColumn para ver enlaces.
Todos los tipos de columnas tienen la propiedad DataPropertyName donde
hay que especificar la columna del origen de datos a mostrar, además
existen otras propiedades como HeaderText para el texto de las cabeceras,
Width para el ancho y DefaulCellStyle que permite configurar el estilo de la
celda: alineación, formato, color de fondo, color de texto, etc.
A continuación un ejemplo de cómo personalizar columnas para la lista de
productos mostrando columnas de selección (checks), columnas con
colores y formato de moneda, columnas de tipo lista desplegable y
columnas con botones que muestran un formulario creado dinámicamente.
Demo 60
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo60.
Hacer una referencia a las librerías [Link] y
[Link].
Cambiar de nombre al formulario de [Link] a [Link]
Luis Dueñas Pag 389
La Biblia de Visual Basic .NET
Configurar el formulario de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmListaProducto
Size 300, 300
Text Crear Columnas
Personalizadas
WindowState Maximized
DataGridView1 Name dgvProducto
AllowUserToAddRows False
AllowUserToDeleteRows False
Dock Fill
MultiSelect False
SelectionMode FullRowSelect
El diseño del formulario debe quedar similar al gráfico 4.19:
Gráfico 4.21: Diseño del formulario Lista de Productos
Escribir el siguiente código en el formulario:
Imports [Link]
Imports [Link]
Public Class frmListaProducto
Private lobeProducto As New List(Of beProducto)
Luis Dueñas Pag 390
La Biblia de Visual Basic .NET
Private lobeCategoria As New List(Of beCategoria)
Private Sub ConfigurarColumnas()
Dim c0 As New DataGridViewCheckBoxColumn
With c0
.Width = 30
.HeaderText = "Sel"
End With
[Link](c0)
Dim c1 As New DataGridViewTextBoxColumn
With c1
.DataPropertyName = "Codigo"
.HeaderText = "ID"
.Width = 50
.ReadOnly = True
.[Link] = _
[Link]
.[Link] = [Link]
.[Link] = [Link]
End With
[Link](c1)
Dim c2 As New DataGridViewTextBoxColumn
With c2
.DataPropertyName = "Nombre"
.HeaderText = "Nombre del Producto"
.Width = 250
.[Link] = _
[Link]
.[Link] = [Link]
.[Link] = [Link]
End With
[Link](c2)
Dim c3 As New DataGridViewTextBoxColumn
With c3
.DataPropertyName = "PrecioUnitario"
.HeaderText = "[Link]"
.Width = 80
.[Link] = _
[Link]
.[Link] = "c2"
Luis Dueñas Pag 391
La Biblia de Visual Basic .NET
.[Link] = [Link]
.[Link] = [Link]
End With
[Link](c3)
Dim c4 As New DataGridViewComboBoxColumn
With c4
.DataSource = lobeCategoria
.DisplayMember = "Nombre"
.ValueMember = "Codigo"
.DataPropertyName = "IdCategoria"
.HeaderText = "Nombre de la Categoria"
.Width = 250
.[Link] = _
[Link]
.[Link] = [Link]
.[Link] = [Link]
End With
[Link](c4)
Dim c5 As New DataGridViewButtonColumn
With c5
.HeaderText = "Comando"
.Text = "Ver Detalle"
.UseColumnTextForButtonValue = True
End With
[Link](c5)
End Sub
Private Sub CargarData(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim obrProducto As New brProducto
lobeProducto = [Link]
Dim obrCategoria As New brCategoria
lobeCategoria = [Link]
[Link] = False
[Link] = lobeProducto
ConfigurarColumnas()
End Sub
Luis Dueñas Pag 392
La Biblia de Visual Basic .NET
Private Sub MostrarFormBoton(ByVal sender As Object, _
ByVal e As [Link]) _
Handles [Link]
If [Link] = 5 Then
Dim frm As New Form
[Link] = [Link]
[Link] = [Link]("Detalle del Producto {0}", _
[Link](1).Value)
[Link]()
End If
End Sub
End Class
Agregar un archivo de configuración a la aplicación: del menú “Project”,
seleccionar “Add New Item”, en la categoría “General” seleccionar
“Application Configuration File”.
Agregar en el archivo de configuración la clave conNW en la sección
appSettings:
<configuration>
<appSettings>
<add key="conNW" value="uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 393
La Biblia de Visual Basic .NET
Gráfico 4.22: Ejecución del formulario Lista de Productos
Luis Dueñas Pag 394
La Biblia de Visual Basic .NET
3.2. Mostrando una Imagen en una Columna
Muchas veces necesitamos mostrar columnas de tipo imagen en una
columna de la grilla, sin importar que sea de una base de datos o de un
archivo de disco el procedimiento es similar, hay que crear una columna de
tipo DataGridViewImageColumn y en el evento CellFormatting hay que
asignar una imagen o bitmap a la propiedad value de la celda de dicha
columna.
A continuación veremos un ejemplo de cómo mostrar una imagen para las
categorías de productos las cuales se encuentran almacenadas en un cierto
directorio y tienen como nombre el código de la categoría con extensión
jpg y para los códigos que no se encuentran existe el archivo [Link].
Demo 61
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo61.
Hacer una referencia a las librerías [Link] y
[Link].
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmListaCategoria
Size 300, 300
Text Lista de Categorias con
Imagen
WindowState Maximized
DataGridView1 Name dgvCategoria
AllowUserToAddRows False
AllowUserToDeleteRows False
Dock Fill
MultiSelect False
SelectionMode FullRowSelect
Luis Dueñas Pag 395
La Biblia de Visual Basic .NET
El diseño del formulario debe quedar similar al gráfico 4.23:
Gráfico 4.23: Diseño del formulario Lista de Categorias
Escribir el siguiente código en el formulario:
Imports [Link]
Imports [Link]
Imports [Link]
Public Class frmListaCategoria
Private lobeCategoria As New List(Of beCategoria)
Private Ruta As String = _
"C:\Lduenas\NET\LibroVB2010\Imagenes\JPG\Categorias\"
Private Sub ListarCategorias(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim obrCategoria As New brCategoria
lobeCategoria = [Link]
[Link] = lobeCategoria
Dim c As New DataGridViewImageColumn
With c
.DataPropertyName = "Codigo"
.Width = 200
.HeaderText = "Foto"
Luis Dueñas Pag 396
La Biblia de Visual Basic .NET
End With
[Link](c)
End Sub
Private Sub MostrarImagen(ByVal sender As Object, _
ByVal e As DataGridViewCellFormattingEventArgs) Handles _
[Link]
If [Link] > -1 Then
If [Link] = 2 Then
Dim archivo As String = [Link] _
("{0}{1}.jpg", Ruta, [Link])
If Not [Link](archivo) Then archivo = _
[Link]("{0}[Link]", Ruta)
Dim img As Image = [Link](archivo)
[Link] = New Bitmap(img, New Size(200, 150))
End If
End If
End Sub
End Class
Nota: En el código anterior para configurar el tamaño de la imagen es
necesario crear un Image y luego asignar a la propiedad Value de la celda
el Bitmap con la imagen del tamaño deseado.
Agregar un archivo de configuración a la aplicación: del menú “Project”,
seleccionar “Add New Item”, en la categoría “General” seleccionar
“Application Configuration File”.
Agregar en el archivo de configuración la clave conNW en la sección
appSettings:
<configuration>
<appSettings>
<add key="conNW" value="uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 397
La Biblia de Visual Basic .NET
Gráfico 4.24: Ejecución del formulario Lista de Categorias
Luis Dueñas Pag 398
La Biblia de Visual Basic .NET
3.3. Personalizando las Cabeceras de las Columnas
Otra tarea especial en una grilla es configurar las cabeceras para mejorar
su apariencia por ejemplo degradandola o también incorporar funcionalidad
de selección, filtro, etc.
Para personalizar las cabeceras del DataGridView hay que programar en el
evento CellPainting para dibujar un nuevo fondo, texto o agregar un control
como por ejemplo una lista desplegable para poder filtrar o un check para
poder seleccionar todo.
A continuación veremos un ejemplo de cómo cambiar las cabeceras de la
grilla de productos para colocar las celdas degradadas y agregar una lsita
desplegable con las categorías para poder filtrar los productos por
categoría tan solo seleccionando la cabecera.
Demo 62
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo62.
Hacer una referencia a las librerías [Link] y
[Link].
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmFiltroProducto
Size 300, 300
Text Personalización de
Cabeceras
WindowState Maximized
DataGridView1 Name dgvProducto
AllowUserToAddRows False
AllowUserToDeleteRows False
Dock Fill
Luis Dueñas Pag 399
La Biblia de Visual Basic .NET
MultiSelect False
SelectionMode FullRowSelect
El diseño del formulario debe quedar similar al gráfico 4.25:
Gráfico 4.25: Diseño del formulario Filtro de Productos
Escribir el siguiente código en el formulario:
Imports [Link]
Imports [Link]
Imports [Link].Drawing2D 'LinearGradientBrush
Public Class frmFiltroProducto
Private lobeProducto As New List(Of beProducto)
Private lobeCategoria As New List(Of beCategoria)
Private WithEvents cboCategoria As New ComboBox
Private Sub CambiarAnchosGrilla()
Dim asr As New [Link]
Dim strAnchos As String = [Link] _
("AnchoGrilla", [Link]("[Link]"))
If Not [Link]("") Then
Dim aAnchos() As String = [Link](",")
If [Link] > 0 Then
For I = 0 To [Link] - 1
Luis Dueñas Pag 400
La Biblia de Visual Basic .NET
[Link](I).Width = aAnchos(I)
Next
End If
End If
End Sub
Private Sub CargarDatos(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim obrProducto As New brProducto
lobeProducto = [Link]
Dim obrCategoria As New brCategoria
lobeCategoria = [Link]
Dim obeCategoria As New beCategoria
[Link] = 0
[Link] = "Todo"
[Link](0, obeCategoria)
With cboCategoria
.DataSource = lobeCategoria
.DisplayMember = "Nombre"
.ValueMember = "Codigo"
End With
[Link](cboCategoria)
[Link] = lobeProducto
CambiarAnchosGrilla()
End Sub
Private Sub FormatearColumnas(ByVal sender As Object, _
ByVal e As DataGridViewCellFormattingEventArgs) Handles _
[Link]
If [Link] > -1 Then
Dim Tipo As String = [Link]
If [Link]("[Link]") Then
[Link] = _
[Link]
Else
Luis Dueñas Pag 401
La Biblia de Visual Basic .NET
[Link] = _
[Link]
If [Link]("[Link]") Then
[Link] = "n2"
End If
End If
End If
End Sub
Private Sub CambiarCabeceraGrilla(ByVal sender As Object, _
ByVal e As DataGridViewCellPaintingEventArgs) Handles _
[Link]
'Si es la cabecera
If [Link] = -1 AndAlso [Link] > -1 Then
Dim Titulo As String = ""
Dim rec As New Rectangle([Link].X, _
[Link].Y, [Link], [Link])
Dim deg As New LinearGradientBrush(rec, [Link], _
[Link], [Link])
[Link](deg, rec)
If [Link] = 0 Then
Titulo = "Codigo"
ElseIf [Link] = 1 Then
Titulo = "Nombre del Producto"
ElseIf [Link] = 2 Then
Titulo = "Id Proveedor"
ElseIf [Link] = 3 Then
[Link] = New Point([Link].X, _
[Link].Y)
[Link] = [Link]
ElseIf [Link] = 4 Then
Titulo = "Pre Unit"
ElseIf [Link] = 5 Then
Titulo = "Stock"
End If
[Link](Titulo, New Font("Arial", 8), _
[Link], [Link].X + 2, [Link].Y + 2)
[Link] = True
End If
End Sub
Luis Dueñas Pag 402
La Biblia de Visual Basic .NET
Private Function BuscaProducto(ByVal obeProducto As beProducto) As
Boolean
Return ([Link] = [Link])
End Function
Private Sub FiltrarProductosxCategoria(ByVal sender As Object, _
ByVal e As [Link]) Handles _
[Link]
If [Link] = 0 Then
[Link] = lobeProducto
Else
Dim pred As New Predicate(Of beProducto) _
(AddressOf BuscaProducto)
[Link] = [Link](pred)
End If
End Sub
End Class
Nota: En el código anterior para configurar el tamaño de las columnas se
hace dinámicamente desde el archivo de configuración mediante una clave
llamada AnchoGrilla.
Agregar un archivo de configuración a la aplicación: del menú “Project”,
seleccionar “Add New Item”, en la categoría “General” seleccionar
“Application Configuration File”.
Agregar en el archivo de configuración la clave conNW en la sección
appSettings:
<configuration>
<appSettings>
<add key="conNW" value="uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind"/>
<add key="AnchoGrilla" value="50,200,100,200,50,50"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 403
La Biblia de Visual Basic .NET
Gráfico 4.26: Ejecución del formulario Filtro de Productos
Luis Dueñas Pag 404
La Biblia de Visual Basic .NET
3.4. Graficando en el DataGridView
Si deseamos crear un gráfico dentro de las celdas de un DataGridView
podemos usar el evento CellFormatting y construir dinámicamente el
gráfico de acuerdo al valor de una celda numérica la cual será representada
por una imagen, por ejemplo una barra que represente los precios de los
productos como se demuestra en el siguiente ejemplo.
Demo 63
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo63.
Hacer una referencia a las librerías [Link] y
[Link].
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmGraficoBarras
Size 300, 300
Text Gráfico de Barras
WindowState Maximized
DataGridView1 Name dgvProducto
AllowUserToAddRows False
AllowUserToDeleteRows False
Dock Fill
MultiSelect False
SelectionMode FullRowSelect
El diseño del formulario debe quedar similar al gráfico 4.27:
Luis Dueñas Pag 405
La Biblia de Visual Basic .NET
Gráfico 4.27: Diseño del formulario Gráfico de Barras
Escribir el siguiente código en el formulario:
Imports [Link]
Imports [Link]
Imports [Link].Drawing2D 'LinearGradientBrush
Public Class frmGraficoBarras
Private lobeProducto As New List(Of beProducto)
Private Sub ListarProductos(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim obrProducto As New brProducto
lobeProducto = [Link]
[Link] = False
[Link] = lobeProducto
Dim c1 As New DataGridViewTextBoxColumn
With c1
.DataPropertyName = "Nombre"
.HeaderText = "Nombre del Producto"
.Width = 200
.[Link] = _
[Link]
End With
[Link](c1)
Luis Dueñas Pag 406
La Biblia de Visual Basic .NET
Dim c2 As New DataGridViewImageColumn
With c2
.DataPropertyName = "PrecioUnitario"
.HeaderText = "Gráfico de Precios de Productos"
.Width = 600
End With
[Link](c2)
End Sub
Private Function GenerarColorAzar() As Color
[Link](10)
Dim oAzar As New Random
Dim R As Integer = [Link](255)
Dim G As Integer = [Link](255)
Dim B As Integer = [Link](255)
Dim X As Color = [Link](R, G, B)
Return (X)
End Function
Private Sub CrearGraficoPrecios(ByVal sender As Object, _
ByVal e As DataGridViewCellFormattingEventArgs) Handles _
[Link]
If [Link] > -1 Then
If [Link] = 1 Then
Dim bmp As New Bitmap(570, 30)
Dim grafico As Graphics = [Link](bmp)
If [Link] IsNot Nothing Then
Dim Precio As Decimal = [Link]([Link])
[Link]([Link] _
("{0:n2}", Precio).PadLeft(6, " "), _
New Font("Courier New", 10), [Link], 0, 5)
Dim rec As New Rectangle(70, 5, Precio, 20)
Dim deg As New LinearGradientBrush(rec, _
GenerarColorAzar, GenerarColorAzar, _
[Link])
[Link](deg, rec)
[Link] = bmp
Else
[Link] = Nothing
End If
Luis Dueñas Pag 407
La Biblia de Visual Basic .NET
End If
End If
End Sub
End Class
Agregar un archivo de configuración a la aplicación: del menú “Project”,
seleccionar “Add New Item”, en la categoría “General” seleccionar
“Application Configuration File”.
Agregar en el archivo de configuración la clave conNW en la sección
appSettings:
<configuration>
<appSettings>
<add key="conNW" value="uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind"/>
<add key="AnchoGrilla" value="50,200,100,200,50,50"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 4.28: Ejecución del formulario Gráfico de Barras
Luis Dueñas Pag 408
La Biblia de Visual Basic .NET
3.5. Paginando en un DataGridView
El DataGridView por defecto trabaja en forma enlazada, es decir muestra
todas las columnas y filas del origen de datos que se configure, en los
temas anteriores vimos como mostrar solo las columnas deseadas, pero no
vimos como limitar el número de filas que se visualizan sobre todo si son
miles de registros.
Si se enlaza un DataGridView a muchos registros se tendrá problemas de
performance ya que NET Framework se demorará en pintar la gran
cantidad de celdas, para esto es conveniente trabajar en modo Virtual o
modo manual el cual consiste en crear uno mismo las columnas y filas a
mostrar.
Lo primero que hay que hacer para paginar en el DataGridView es
configurar la propiedad AutoGenerateColumns en “False”, luego configurar
la propiedad VirtualMode en “True”, después crear las columnas a mostrar
y configurar la propiedad RowCount en el número de filas a visualizar.
Lo mas importante es programar en el evento CellValueNeeded el valor que
se va a mostrar en cada celda y para que se actualize una página es
necesario llamar al método Refresh.
A continuación un ejemplo de paginación de registros para los productos
de tal forma que se muestren de 20 en 20 y podamos ver la primera página,
ir a la página anterior, ir a la página siguiente y ver la ultima página.
Demo 64
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo64.
Hacer una referencia a las librerías [Link] y
[Link].
Cambiar de nombre al formulario de [Link] a frmPaginacion
[Link]
Luis Dueñas Pag 409
La Biblia de Visual Basic .NET
Configurar el formulario de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frm PaginacionProductos
Size 300, 300
Text Paginación de Productos
WindowState Maximized
DataGridView1 Name dgvProducto
AllowUserToAddRows False
AllowUserToDeleteRows False
Anchor Top, Bottom, Left, Right
Location 3,3
MultiSelect False
SelectionMode FullRowSelect
Size 288, 241
Button1 Name btnPrimero
Anchor Bottom, Right
Cursor Hand
Location 61, 250
Size 28, 23
Text <<
Button2 Name btnAnterior
Anchor Bottom, Right
Cursor Hand
Location 90, 250
Size 28, 23
Text <
TextBox1 Name txtPagina
Anchor Bottom, Right
Location 119, 253
ReadOnly True
Size 64, 20
Text
TextAlign Center
Button3 Name btnSiguiente
Anchor Bottom, Right
Cursor Hand
Location 184, 250
Size 28, 23
Text >
Button4 Name btnUltimo
Luis Dueñas Pag 410
La Biblia de Visual Basic .NET
Anchor Bottom, Right
Cursor Hand
Location 213, 250
Size 28, 23
Text >>
El diseño del formulario debe quedar similar al gráfico 4.29:
Gráfico 4.29: Diseño del formulario Paginación de Productos
Escribir el siguiente código en el formulario:
Imports [Link]
Imports [Link]
Public Class frmPaginacionProducto
Private lobeProducto As New List(Of beProducto)
Private NumRegPag As Integer = 20
Private IndicePag As Integer = 0
Private TotalPag As Integer = 0
Private IndiceFila As Integer = 0
Private Sub CrearColumnas()
[Link]("Codigo", "Codigo")
[Link]("Nombre", "Nombre")
[Link]("PrecioUnitario", "PreUnit")
Luis Dueñas Pag 411
La Biblia de Visual Basic .NET
[Link]("Stock", "Stock")
End Sub
Private Sub MostrarPagina()
[Link] = [Link]("{0} de {1}", _
IndicePag + 1, TotalPag)
End Sub
Private Sub ListarProductos(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim obrProducto As New brProducto
lobeProducto = [Link]
If [Link] Mod NumRegPag = 0 Then
TotalPag = [Link] / NumRegPag
Else
TotalPag = ([Link] / NumRegPag) + 1
End If
MostrarPagina()
[Link] = False
[Link] = True
CrearColumnas()
[Link] = NumRegPag
End Sub
Private Sub EscribirCelda(ByVal sender As Object, _
ByVal e As DataGridViewCellValueEventArgs) Handles _
[Link]
IndiceFila = NumRegPag * IndicePag + [Link]
If IndiceFila < [Link] Then
If [Link] = 0 Then
[Link] = lobeProducto(IndiceFila).Codigo
ElseIf [Link] = 1 Then
[Link] = lobeProducto(IndiceFila).Nombre
ElseIf [Link] = 2 Then
[Link] = lobeProducto(IndiceFila).PrecioUnitario
ElseIf [Link] = 3 Then
[Link] = lobeProducto(IndiceFila).Stock
End If
End If
Luis Dueñas Pag 412
La Biblia de Visual Basic .NET
End Sub
Private Sub IrPrimeraPagina(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
IndicePag = 0
[Link]()
MostrarPagina()
End Sub
Private Sub IrPaginaAnterior(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If IndicePag > 0 Then IndicePag -= 1
[Link]()
MostrarPagina()
End Sub
Private Sub IrPaginaSiguiente(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If IndicePag < TotalPag - 1 Then IndicePag += 1
[Link]()
MostrarPagina()
End Sub
Private Sub IrUltimaPagina(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
IndicePag = TotalPag - 1
[Link]()
MostrarPagina()
End Sub
End Class
Agregar un archivo de configuración a la aplicación: del menú “Project”,
seleccionar “Add New Item”, en la categoría “General” seleccionar
“Application Configuration File”.
Agregar en el archivo de configuración la clave conNW en la sección
appSettings:
<configuration>
<appSettings>
<add key="conNW" value="uid=sa;pwd=123456;
Luis Dueñas Pag 413
La Biblia de Visual Basic .NET
data source=Lduenas\MCTS;initial catalog=Northwind"/>
<add key="AnchoGrilla" value="50,200,100,200,50,50"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 4.30: Ejecución del formulario Paginación de Productos
Luis Dueñas Pag 414
La Biblia de Visual Basic .NET
4. Creando una Biblioteca de Controles Windows
Para reusar el código se crea una Biblioteca de Clases, pero si queremos
reusar Controles debemos crear una Biblioteca de Controles Windows que
nos permitan ahorrar tiempo en tareas comunes como validación en
controles, botones comunes, diálogos comunes, grillas de consulta, grillas
paginadas, etc.
Los controles que podemos crear en Windows Forms se clasifican en 3:
controles extendidos, controles de usuario y controles personalizados. En
todos ellos podemos crear propiedades, métodos, eventos, etc, también
podemos sobre escribir el comportamiento de ciertos eventos.
La diferencia entre los 3 es que el primero (control extendido) solo
representa un control al que hereda, el segundo (control de usuario) se
compone de 2 o mas controles Windows y el tercero (control persona
lizado) se tiene que graficar o dibujar. Para obtener más información de
cómo Desarrollar controles personalizados de formularios Windows Forms
con .NET Framework vea la referencia 25 al final del libro.
4.1. Creando Controles Extendidos
Los controles extendidos o ampliados son aquéllos que heredan de un
cierta clase de [Link], como por ejemplo de la clase
TextBox para crear un control que solo acepte números, o de la clase
DataGridView para que la grilla tenga la configuración de solo lectura o de
la clase ListView para crear una propiedad DataSource y poder enlazarlo a
un origen de datos.
Cada vez que se quiera sobre escribir el comportamiento de un control o
mejorar su funcionalidad lo que debemos hacer es crear un control que
herede de dicha clase.
A continuación crearemos una Librería de Controles para Windows y
agregaremos un par de clases: la primera que herede de un TextBox para
crear el control Número y el segundo que herede del DataGridView para
Luis Dueñas Pag 415
La Biblia de Visual Basic .NET
crear el control GrillaConsulta, ambos usaran el prefijo “wic” que indica que
son “Wi”ndows “C”ontrols.
Demo [Link]
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Control Library”.
Escribir como nombre físico al proyecto: [Link].
Eliminar el control que aparece por defecto dando clic derecho y
seleccionando “Eliminar”.
Crear el Control Número
Agregar una clase llamada “wicNumero”.
Escribir el siguiente código para la clase wicNumero:
Public Class wicNumero
Inherits [Link]
Public Property SgteControl() As Control
Protected Overrides Sub OnKeyPress _
(ByVal e As [Link])
If [Link] = [Link] Then
If SgteControl IsNot Nothing Then _
[Link]()
Else
[Link] = Not ([Link]([Link]) Or _
[Link] = [Link])
End If
End Sub
End Class
Nota: En el código anterior se ha creado una propiedad SgteControl que
permite especificar a que control vamos a avanzar al pulsar Enter sobre el
número. Además se ha sobre escrito el evento OnKeyPress para permitir
ingresar solo digitos y BackSpace.
Luis Dueñas Pag 416
La Biblia de Visual Basic .NET
Crear el Control Grilla Consulta
Agregar una nueva clase llamada “wicGrillaConsulta”.
Escribir el siguiente código para la clase wicGrillaConsulta:
Imports [Link]
Public Class wicGrillaConsulta
Inherits DataGridView
Public Sub New()
[Link] = False
[Link] = False
[Link] = True
[Link] = _
[Link]
End Sub
Private Sub FormatearColumnasGrilla(ByVal sender As Object, _
ByVal e As DataGridViewCellFormattingEventArgs) _
Handles [Link]
If [Link] > -1 Then
Dim Tipo As String = [Link]
If [Link]("[Link]") Then
[Link] = _
[Link]
Else
[Link] = _
[Link]
If [Link]("[Link]") Then
[Link] = "n2"
End If
End If
End If
End Sub
End Class
Nota: En el código anterior se ha modificado el contructor para que cada
vez que se cree una instancia de la grilla se configure las propiedades para
que sea solo lectura. Además en el evento CellFormatting se ha
Luis Dueñas Pag 417
La Biblia de Visual Basic .NET
programado para que todas las columnas de texto se alineen a la izquierda
y el resto: números y fechas se alineen a la derecha, además las columnas
que tienen decimales aparecerán con 2 decimales por defecto.
4.2. Creando Controles de Usuario
Los controles de usuario o compuestos son aquéllos que se componen de 2
o más controles de Windows a los cuales se les conoce como controles
constituyentes, los controles de usuario heredan de la clase UserControl de
System. [Link].
Este control es el más fácil de crear porque se dispone del diseñador de
Windows Forms para arrastrar los controles que van a formar el control de
usuario; casi siempre es necesario crear propiedades al control para
exponer las propiedades de sus controles constituyentes.
A continuación vamos a agregar 3 controles de usuario a nuestra Librería
de Controles creada anteriormente: el primero wicBotonesMante que
permite tener los botones de Nuevo, Adicionar, Actualizar y Eliminar de un
mantenimiento; el segundo wicDialogo que permite seleccionar un archivo
a abrir o guardar y configurar un texto con la ruta seleccionada; finalmente
el tercer control y el más importante wicGrillaPaginada que permite realizar
paginación desconectada mediante listas de objetos.
Crear el Control Botones de Mantenimiento
Agregar un control de usuario: del menú “Project” seleccionar “Add
User Control”
Escribir como nombre del control: “wicBotonesMante”.
Agregar y configurar controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
UserControl Name wicBotonesMante
Size 80, 118
Button1 Name btnNuevo
Luis Dueñas Pag 418
La Biblia de Visual Basic .NET
Cursor Hand
Location 3,3
Size 75, 23
Text Nuevo
Button2 Name btnAdicionar
Cursor Hand
Location 3, 32
Size 75, 50
Text Adicionar
Button3 Name btnActualizar
Cursor Hand
Location 3, 61
Size 75, 23
Text Actualizar
Button4 Name btnEliminar
Cursor Hand
Location 3, 90
Size 75, 23
Text Eliminar
El diseño del control debe quedar similar al gráfico 4.31:
Gráfico 4.31: Diseño del control de Usuario wicBotonesMante
Escribir el siguiente código para el control wicBotonesMante:
Public Class wicBotonesMante
Public Event Elegir(ByVal N As Integer)
Private Sub Nuevo(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
RaiseEvent Elegir(1)
End Sub
Luis Dueñas Pag 419
La Biblia de Visual Basic .NET
Private Sub Adicionar(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
RaiseEvent Elegir(2)
End Sub
Private Sub Actualizar(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
RaiseEvent Elegir(3)
End Sub
Private Sub Eliminar(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
RaiseEvent Elegir(4)
End Sub
End Class
Nota: En el código anterior se ha creado un evento llamado “Elegir” el cual
se desencadena al dar clic sobre cada botón, para lo cual se pasa un
número que indica que botón es el que desencadenó el evento.
Crear el Control Diálogo
Agregar un control de usuario: del menú “Project” seleccionar “Add
User Control”
Escribir como nombre del control: “wicDialogo”.
Agregar y configurar controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
UserControl Name wicDialogo
Size 270, 52
Label1 Name lblArchivo
AutoSize True
Location 0, 9
Text Selecciona el Archivo
TextBox1 Name txtArchivo
Location 3, 25
ReadOnly True
Size 235,20
Luis Dueñas Pag 420
La Biblia de Visual Basic .NET
Button1 Name btnMostrarDialogo
Cursor Hand
Location 243, 22
Size 24, 23
Text …
El diseño del control debe quedar similar al gráfico 4.32:
Gráfico 4.32: Diseño del control de Usuario wicDialogo
Escribir el siguiente código para el control wicDialogo:
Public Class wicDialogo
Private _TipoDialogo As TiposDialogo
Private _Filtro As String
Public Event SeleccionarArchivo()
Public Enum TiposDialogo
DialogoAbrir = 0
DialogoGuardar = 1
End Enum
Public Property TituloTexto() As String
Get
Return ([Link])
End Get
Set(ByVal value As String)
[Link] = value
End Set
End Property
Public Property TituloColor() As Color
Get
Return ([Link])
End Get
Set(ByVal value As Color)
[Link] = value
Luis Dueñas Pag 421
La Biblia de Visual Basic .NET
End Set
End Property
Public Property TipoDialogo() As TiposDialogo
Get
Return (_TipoDialogo)
End Get
Set(ByVal value As TiposDialogo)
_TipoDialogo = value
End Set
End Property
Public Property Filtro() As String
Get
Return (_Filtro)
End Get
Set(ByVal value As String)
_Filtro = value
End Set
End Property
Public Property NombreArchivo() As String
Get
Return ([Link])
End Get
Set(ByVal value As String)
[Link] = value
End Set
End Property
Private Sub MostrarDialogo(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim fd As FileDialog
If _TipoDialogo = [Link] Then
fd = New OpenFileDialog
Else
fd = New SaveFileDialog
End If
[Link] = [Link]
[Link] = _Filtro
Luis Dueñas Pag 422
La Biblia de Visual Basic .NET
If [Link] = [Link] Then
[Link] = [Link]
RaiseEvent SeleccionarArchivo()
End If
End Sub
End Class
Nota: En el código anterior se ha creado una propiedad enumerada
TipoDialogo que especifica si lo que se va a mostrar es el dialogo de abrir o
guardar. Además se ha creado un evento que se dispara cuando se elige
un archivo del diálogo.
Crear el Control Grilla Paginada
Agregar un control de usuario: del menú “Project” seleccionar “Add
User Control”
Escribir como nombre del control: “wicGrillaPaginada”.
Agregar y configurar controles de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
UserControl Name wicGrillaPaginada
MinimumSize 290, 290
Size 290, 290
DataGridView1 Name dgvProducto
AllowUserToAddRows False
AllowUserToDeleteRows False
Anchor Top, Bottom, Left, Right
Location 5, 3
MultiSelect False
SelectionMode FullRowSelect
Size 278, 255
Button1 Name btnPrimero
Anchor Bottom, Right
Cursor Hand
Location 52, 264
Size 28, 23
Text <<
Button2 Name btnAnterior
Luis Dueñas Pag 423
La Biblia de Visual Basic .NET
Anchor Bottom, Right
Cursor Hand
Location 81, 264
Size 28, 23
Text <
TextBox1 Name txtPagina
Anchor Bottom, Right
Location 110, 267
ReadOnly True
Size 64, 20
Text
TextAlign Center
Button3 Name btnSiguiente
Anchor Bottom, Right
Cursor Hand
Location 175, 264
Size 28, 23
Text >
Button4 Name btnUltimo
Anchor Bottom, Right
Cursor Hand
Location 204, 264
Size 28, 23
Text >>
El diseño del control debe quedar similar al gráfico 4.33:
Luis Dueñas Pag 424
La Biblia de Visual Basic .NET
Gráfico 4.33: Diseño del control de Usuario wicGrillaPaginada
Escribir el siguiente código para el control wicGrillaPaginada:
Imports [Link]
Imports [Link]
Public Class wicGrillaPaginada
Private _DataSource As Object
Private _NumRegPag As Integer
Private IndicePag As Integer = 0
Private TotalPag As Integer = 0
Private IndiceFila As Integer = 0
Public Property DataSource() As Object
Get
Return (_DataSource)
End Get
Set(ByVal value As Object)
_DataSource = value
If _DataSource IsNot Nothing Then
If _DataSource.Count Mod _NumRegPag = 0 Then
TotalPag = _DataSource.Count \ _NumRegPag
Else
TotalPag = (_DataSource.Count \ _NumRegPag) + 1
End If
Luis Dueñas Pag 425
La Biblia de Visual Basic .NET
MostrarPagina()
[Link] = False
[Link] = True
CrearColumnas()
[Link] = _NumRegPag
End If
End Set
End Property
Public Property NumRegPag() As Integer
Get
Return (_NumRegPag)
End Get
Set(ByVal value As Integer)
_NumRegPag = value
End Set
End Property
Private Sub CrearColumnas()
Dim Propiedades() As PropertyInfo = _
_DataSource(0).[Link]
For Each Propiedad In Propiedades
[Link]([Link], [Link])
Next
End Sub
Private Sub MostrarPagina()
[Link] = [Link]("{0} de {1}", _
IndicePag + 1, TotalPag)
End Sub
Private Sub EscribirCelda(ByVal sender As Object, _
ByVal e As DataGridViewCellValueEventArgs) Handles _
[Link]
IndiceFila = _NumRegPag * IndicePag + [Link]
If IndiceFila < _DataSource.Count Then
Dim campo As String = [Link]([Link]).Name
[Link] = _DataSource(IndiceFila).GetType. _
GetProperty(campo).GetValue(_DataSource(IndiceFila), Nothing)
Luis Dueñas Pag 426
La Biblia de Visual Basic .NET
End If
End Sub
Private Sub IrPrimeraPagina(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
IndicePag = 0
[Link]()
MostrarPagina()
End Sub
Private Sub IrAnteriorPagina(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If IndicePag > 0 Then IndicePag -= 1
[Link]()
MostrarPagina()
End Sub
Private Sub IrSiguientePagina(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If IndicePag < TotalPag - 1 Then IndicePag += 1
[Link]()
MostrarPagina()
End Sub
Private Sub btnUltimo_Click(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
IndicePag = TotalPag - 1
[Link]()
MostrarPagina()
End Sub
End Class
Nota: En el código anterior se ha creado 2 propiedades: una para
configurar el origen de datos (lista de objetos) y otra para especificar el
número de registros por página a visualizar. También se usa Reflection
para obtener las propiedades del tipo de objeto de la lista de objetos.
Luis Dueñas Pag 427
La Biblia de Visual Basic .NET
Creando Controles Personalizados
Un control personalizado (Custom Control) es un control que se tiene que
crear desde cero mediante gráficos, éste hereda de la clase Control del
espacio de nombres [Link].
Crear este tipo de controles no es tan fácil ya que se tiene que realizar por
código mediante gráficos y se usa justamente para crear pantallas gráficas.
A continuación agregaremos a la librería de controles creada el control
Logo que dibuja un rectángulo degradado en pantalla con un mensaje y
finalmente probaremos en una aplicación de Windows (Demo 65) todos los
controles anteriormente creados.
Crear el Control Logo
Agregar un control personalizado: del menú “Project” seleccionar “Add
New Item” y luego elegir “Custom Control”.
Escribir como nombre del control: “wicLogo”.
Escribir el siguiente código para el control wicLogo:
Imports [Link].Drawing2D
Public Class wicLogo
Public Property TituloTexto() As String
Public Property TituloFuente() As Font
Public Property TituloColor() As Color
Public Property TituloPosicion() As New Point(0, 0)
Public Property FondoColor1() As Color
Public Property FondoColor2() As Color
Protected Overrides Sub OnPaint _
(ByVal e As [Link])
Dim rec As New Rectangle(0, 0, [Link], [Link])
Dim deg As New LinearGradientBrush(rec, FondoColor1, _
FondoColor2, [Link])
[Link](deg, rec)
[Link](TituloTexto, TituloFuente, _
New SolidBrush(TituloColor), TituloPosicion)
Luis Dueñas Pag 428
La Biblia de Visual Basic .NET
End Sub
End Class
Finalmente, del menú “Build” seleccionar “Build [Link]
WinForms” para crear la dll con todos los controles creados.
Demo 65
Del menú “File”, seleccionar “Add”, “New Project” y luego “Windows
Forms Application”.
Crear una aplicación en Visual Basic llamada: Demo65.
Hacer una referencia a las librerías [Link] y
[Link].
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmPrueba1
FormBorderStyle FixedSingle
Size 400, 300
MaximizeBox False
MinimizeBox False
Text Prueba de Control Logo,
Diálogo y Número
StartUpPosition CenterScreen
WicLogo1 Name Logo
FondoColor1 Aqua
FondoColor1 Blue
Location 12, 12
Size 370, 87
TituloColor Red
TituloFuente Arial Black, 20.25pt
TituloPosicion 5, 20
TituloTexto Visual Basic – Lduenas
WicDialogo1 Name DialogoAbrir
Location 61, 105
Size 270, 52
Luis Dueñas Pag 429
La Biblia de Visual Basic .NET
WinNumero1 Name Numero1
Location 43, 173
SgteControl Numero2
Size 100, 20
WinNumero2 Name Numero2
Location 149, 173
SgteControl Numero3
Size 100, 20
WinNumero3 Name Numero3
Location 255, 173
SgteControl btnCalcular
Size 100, 20
Button1 Name btnCalcular
Cursor Hand
Location 159, 212
Text Calcular
El diseño del formulario debe quedar similar al gráfico 4.34:
Gráfico 4.34: Diseño del formulario Prueba1
Configurar la aplicación Windows como el que inicia: clic derecho al
proyecto y seleccionar “Set as StartUp Project”.
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 430
La Biblia de Visual Basic .NET
Gráfico 4.35: Ejecución del formulario Prueba1
Agregar otro formulario a la aplicación y llamarle [Link]
Configurar el formulario de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmPrueba2
FormBorderStyle FixedSingle
Size 700, 400
MaximizeBox False
MinimizeBox False
Text Prueba del Control
Botones y Grilla Consulta
StartUpPosition CenterScreen
WicGrillaConsulta1
Name gcProducto
Location 7, 3
Size 595, 359
WicBotonesMante1 Name bmProducto
Location 607, 3
Size 80, 118
El diseño del formulario debe quedar similar al gráfico 4.36:
Luis Dueñas Pag 431
La Biblia de Visual Basic .NET
Gráfico 4.36: Diseño del formulario Prueba2
Escribir el siguiente código para el formulario de prueba 2:
Imports [Link]
Imports [Link]
Public Class frmPrueba2
Private Sub ListarProductos(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim obrProducto As New brProducto
Dim lobeProducto As List(Of beProducto) = [Link]
[Link] = lobeProducto
End Sub
End Class
Agregar un archivo de configuración a la aplicación: del menú “Project”,
seleccionar “Add New Item”, en la categoría “General” seleccionar
“Application Configuration File”.
Agregar en el archivo de configuración la clave conNW en la sección
appSettings:
<configuration>
Luis Dueñas Pag 432
La Biblia de Visual Basic .NET
<appSettings>
<add key="conNW" value="uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind"/>
</appSettings>
</configuration>
Configurar como formulario de inicio a frmPrueba2.
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 4.37: Ejecución del formulario Prueba2
Agregar otro formulario a la aplicación y llamarle [Link]
Configurar el formulario de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmPrueba3
FormBorderStyle FixedSingle
Size 700, 400
MaximizeBox False
MinimizeBox False
Text Prueba del Control Grilla
Paginada
StartUpPosition CenterScreen
Luis Dueñas Pag 433
La Biblia de Visual Basic .NET
WicGrillaPaginada1 Name gpProducto
Dock Fill
El diseño del formulario debe quedar similar al gráfico 4.38:
Gráfico 4.38: Diseño del formulario Prueba3
Escribir el siguiente código para el formulario de prueba 3:
Imports [Link]
Imports [Link]
Public Class frmPrueba3
Private Sub ListarProductos(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim obrProducto As New brProducto
Dim lobeProducto As List(Of beProducto) = [Link]
[Link] = 20
[Link] = lobeProducto
End Sub
End Class
Luis Dueñas Pag 434
La Biblia de Visual Basic .NET
Importante: Es necesario que primero se llene la propiedad NumRegPag
antes que la propiedad DataSource, ya que al establecer la propiedad
DataSource se configura el numero de registros a visualizar.
Configurar como formulario de inicio a frmPrueba3.
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 4.39: Ejecución del formulario Prueba3
Luis Dueñas Pag 435
La Biblia de Visual Basic .NET
5. Creando Reportes e Impresiones en Windows Forms
En esta última parte aprenderemos como crear reportes e imprimir desde
una aplicación Windows Forms, para lo cual existen varias formas, como
por ejemplo usar el objeto PrintDocument para crear el documento a
imprimir usando gráficos y diálogos para la visualización de la vista
preliminar, configurar la página o impresión.
Si se desea un reporte de datos complejo la mejor alternativa seria usar el
Microsoft ReportViewer que permite crear reportes usando como origen de
datos objetos y permite realizar agrupaciones, subtotales, fórmulas,
además permite exportar el reporte a un archivo de Excel o PDF.
Otra alternativa de crear un documento para imprimir es usar Microsoft
Word sobre todo si ya existe una plantilla en formato doc o docx la cual
debe llenarse con data de la aplicación o quizás crear un cuadro de análisis
usando Microsoft Excel el cual también nos permitirá graficar.
5.1. Usando PrintDocument
La clase PrintDocument que se encuentra en el espacio de nombres
[Link] se usa para crear contenido a imprimir mediante
el uso de graficos (clase Graphics). Esta clase tiene varios eventos pero el
principal es el evento PrintPage donde se escribe el código de la página o
páginas que se desean imprimir.
Otros eventos de la clase PrintDocument son BeginPrint cuando se inicia la
impresión, EndPrint cuando se finaliza la impresión y QueryPageSettings
que es usado para cambiar la configuración de la impresión.
Para realizar una vista preliminar (preview) del documento que se ha
construido en el evento PrintPage del PrintDocument existen 2 formas: usar
el control PrintPreviewControl o usar el diálogo PrintPreviewDialog, la
diferencia es que el primero es un simple control que hay que agregar a un
formulario y no tiene funcionalidad de zoom, ver varias páginas, etc. que si
trae incorporado el diálogo de preview.
Luis Dueñas Pag 436
La Biblia de Visual Basic .NET
También existen 2 diálogos más de impresión: uno es el PageSetupDialog
que permite cambiar la configuración de la página y el otro es el
PrintDialog que permite especificar la salida de la impresión.
El control de preview y los 3 dialogos de impresión tienen una propiedad
Document donde hay que asociar el objeto PrintDocument para poder
referenciar al documento que se desea imprimir. Para obtener más
información de cómo imprimir usando la clase PrintDocument ver la
referencia 26 al final del libro.
A continuación veremos un ejemplo de cómo crear un reporte de productos
en varias hojas usando el PrintDocument y los 3 diálogos de impresión, los
cuales se verán al dar clic derecho sobre la grilla de productos.
Demo 66
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo66.
Hacer una referencia a las librerías [Link] y
[Link].
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmReporteProducto
FormBorderStyle FixedSingle
Size 500, 400
MaximizeBox False
MinimizeBox False
Text Reporte de Productos
con PrintDocument
StartUpPosition CenterScreen
ContextMenuStrip1 Name mnuImpresion
ToolStripMenuItem1 Name mnuPreview
Text Preview
ToolStripMenuItem2 Name mnuPageSetup
Text PageSetup
Luis Dueñas Pag 437
La Biblia de Visual Basic .NET
ToolStripMenuItem3 Name mnuPrint
Text Print
DataGridView1 Name dgvProducto
AllowUserToAddRows False
AllowUserToDeleteRows False
ContextMenuStrip mnuImpresion
Dock Fill
ReadOnly True
SelectionMode FullRowSelect
El diseño del formulario debe quedar similar al gráfico 4.40:
Gráfico 4.40: Diseño del formulario Reporte de Productos
Escribir el siguiente código para el formulario:
Imports [Link]
Imports [Link]
Imports [Link] 'PrintDocument
Imports [Link].Drawing2D
Public Class frmReporteProducto
Private lobeProducto As New List(Of beProducto)
Private WithEvents pd As New PrintDocument
Luis Dueñas Pag 438
La Biblia de Visual Basic .NET
Private cr As Integer
Private totPags As Integer
Private numPag As Integer
Private Sub ListarProductos(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim obrProducto As New brProducto
lobeProducto = [Link]()
[Link] = lobeProducto
End Sub
Private Sub ImprimirPagina(ByVal sender As Object, _
ByVal e As PrintPageEventArgs) Handles [Link]
Dim x As Integer = [Link]
Dim y As Integer = [Link]
Dim rec As New Rectangle(x, y - 20, _
[Link], [Link])
Dim deg As New LinearGradientBrush(rec, [Link], _
[Link], [Link])
Dim fuente As New Font("Arial", 10)
Dim brocha As Brush = [Link]
Dim brochaTitulo As Brush = [Link]
Dim tlp As Integer = [Link] \ _
([Link] + 20)
totPags = ([Link] \ (tlp - 1))
If [Link] Mod (tlp - 1) > 0 Then totPags += 1
numPag += 1
With [Link]
'.FillRectangle(deg, rec)
x = [Link]
.DrawString("Codigo", fuente, brochaTitulo, x, y)
x = x + 100
.DrawString("Nombre", fuente, brochaTitulo, x, y)
x = x + 300
.DrawString("Precio Unit", fuente, brochaTitulo, x, y)
x = x + 100
.DrawString("Stock", fuente, brochaTitulo, x, y)
y = y + [Link] + 20
Dim I As Integer
For I = 0 To tlp - 2
Luis Dueñas Pag 439
La Biblia de Visual Basic .NET
If cr = [Link] Then Exit For
x = [Link]
.DrawString(lobeProducto(cr).Codigo, _
fuente, brocha, x, y)
x = x + 100
.DrawString(lobeProducto(cr).Nombre, _
fuente, brocha, x, y)
x = x + 300
.DrawString(lobeProducto(cr).PrecioUnitario, _
fuente, brocha, x, y)
x = x + 100
.DrawString(lobeProducto(cr).Stock, _
fuente, brocha, x, y)
y = y + [Link] + 20
cr += 1
Next
.DrawString([Link]("Pag {0} de {1}", _
numPag, totPags), fuente, brochaTitulo, 400, _
[Link] + [Link])
[Link] = (cr < [Link] - 1)
End With
End Sub
Private Sub Preview(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
cr = 0
Dim ppd As New PrintPreviewDialog
[Link] = pd
[Link]()
End Sub
Private Sub PageSetup(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim psd As New PageSetupDialog
[Link] = pd
[Link]()
End Sub
Private Sub Print(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Luis Dueñas Pag 440
La Biblia de Visual Basic .NET
Dim pdg As New PrintDialog
[Link] = pd
[Link]()
End Sub
End Class
Nota: En el evento PrintPage el parámetro e tiene una propiedad HasMore
Pages que especifica si se va a crear una nueva pagina, es decir se crearan
nuevas pgainas mientras el contador de registros sea menor al último
registro.
Agregar un archivo de configuración a la aplicación: del menú “Project”,
seleccionar “Add New Item”, en la categoría “General” seleccionar
“Application Configuration File”.
Agregar en el archivo de configuración la clave conNW en la sección
appSettings:
<configuration>
<appSettings>
<add key="conNW" value="uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 441
La Biblia de Visual Basic .NET
Gráfico 4.41: Ejecución del formulario Reporte de Productos
Clic derecho sobre la grilla de productos y se presentará un menú
contextual, seleccionar la opción Preview y se verá la siguiente figura.
Luis Dueñas Pag 442
La Biblia de Visual Basic .NET
Gráfico 4.42: Diálogo de Preview del Reporte de Productos
Clic derecho sobre la grilla de productos y del menú contextual ahora
seleccionar la opción Page Setup y se verá la siguiente figura.
Luis Dueñas Pag 443
La Biblia de Visual Basic .NET
Gráfico 4.43: Diálogo de Configurar Página
Finalmente, clic derecho sobre la grilla de productos y del menú
contextual ahora seleccionar la opción Print y se verá la figura 4.44.
Gráfico 4.44: Diálogo de Imprimir
Luis Dueñas Pag 444
La Biblia de Visual Basic .NET
5.2. Informes de Microsoft
Para crear reportes de datos podemos usar los Informes de Microsoft los
cuales incluyen funcionalidad de diseñar el reporte usando controles y un
diseñador mejorado y también la capacidad de poder presentarlos usando
un visor conocido como el control “ReportViewer” que tiene una versión
para Windows Forms y otra para ASP .NET AJAX.
En Visual Studio 2010 se han mejorado algunas características para los
Informes de Microsoft entre ellas:
Diseñador de Informes para el esquema: Lenguaje de Definición de
Informes (RDL 2008), por ejemplo mejoras en el Diseñador de
Informes.
Nuevo Asistente para Informes que simplifica la definición de datos y el
diseño del informe.
Mejoras en los controles ReportViewer, por ejemplo Exportar a Word.
Mejoras de programación en los controles ReportViewer, por ejemplo
Modelo de Eventos más completo.
Diseñador de Informes
El Diseñador de informes de Visual Studio proporciona una interfaz fácil de
usar para crear informes sólidos que incluyen datos procedentes de varios
tipos de orígenes de datos.
En Visual Studio, los informes se guardan como archivos de definición de
informe del cliente (.rdlc). Estos archivos se basan en el mismo esquema
que los archivos de definición de informe (.rdl) publicados en los servidores
de informes de SQL Server Reporting Services, pero se guardan y se
procesan de manera distinta a los archivos .rdl. En tiempo de ejecución, los
archivos .rdlc se procesan localmente, y los archivos .rdl se procesan
remotamente.
Luis Dueñas Pag 445
La Biblia de Visual Basic .NET
Nota: El Diseñador de informes de Visual Studio es similar a la interfaz de
usuario de Business Intelligence Development Studio de SQL Server 2008 o
posterior, excepto en que no tiene la funcionalidad de vista previa y en que
guarda los informes en archivos .rdlc en lugar de archivos .rdl.
Controles ReportViewer
Microsoft Visual Studio 2010 incluye la funcionalidad de diseño de informes
y los controles ReportViewer, que le permiten agregar informes con todas
las características a las aplicaciones personalizadas. Los informes pueden
contener datos tabulares, agregados y multidimensionales. Los controles
ReportViewer le permitirán procesar y mostrar el informe en la aplicación.
Hay dos versiones del control. El control de servidor web ReportViewer es
un control AJAX de [Link] que se utiliza para hospedar informes en
proyectos de [Link]. El control de Windows Forms ReportViewer se
utiliza para hospedar informes en proyectos de aplicaciones Windows.
Puede configurar los dos controles para ejecutarlos en el modo de
procesamiento local o en el modo de procesamiento remoto. La
configuración del modo de procesamiento afecta a todo el informe, desde
el diseño hasta la implementación.
El modo de procesamiento local hace referencia al procesamiento que
realiza el control ReportViewer en la aplicación cliente. Todo el
procesamiento del informe se realiza en el proceso local con los datos
suministrados por la aplicación. Para crear los informes utilizados en el
modo de procesamiento local, puede utilizar la plantilla Proyecto de informe
de Visual Studio.
El modo de procesamiento remoto hace referencia al procesamiento de
informes que realiza un servidor de informes de SQL Server 2008 Reporting
Services o posterior. En el modo de procesamiento remoto, el control
ReportViewer se utiliza como un visor para representar un informe
procesado en un servidor de informes de Reporting Services. Todo el
procesamiento, desde la recuperación de datos hasta el procesamiento del
informe, se realiza en el servidor de informes. Para utilizar el modo de
Luis Dueñas Pag 446
La Biblia de Visual Basic .NET
procesamiento remoto, debe tener una copia con licencia de SQL Server
2008 o posterior.
Para obtener más información sobre los informes de Microsoft consultar la
referencia 27 al final del libro y para ver ejemplos y tutoriales sobre el
control ReportViewer ver la referencia 28 al final del libro.
A continuación presentamos un ejemplo de cómo crear un Reporte de
Empleados usando el Diseñador de Reportes y cómo presentarlo usando el
control ReportViewer para Windows Forms.
Demo 67
Del menú “File”, seleccionar “New Project” y luego “Windows Forms
Application”.
Crear una aplicación en Visual Basic llamada: Demo67.
Hacer una referencia a las librerías [Link] y
[Link].
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmListaEmpleado
FormBorderStyle FixedSingle
Size 400, 300
MaximizeBox False
MinimizeBox False
Text Reporte de Empleados
con Informes Microsoft
StartUpPosition CenterScreen
ContextMenuStrip1 Name mnuImpresion
ToolStripMenuItem1 Name mnuPreview
Text Preview
DataGridView1 Name dgvEmpleado
AllowUserToAddRows False
AllowUserToDeleteRows False
ContextMenuStrip mnuImpresion
Dock Fill
Luis Dueñas Pag 447
La Biblia de Visual Basic .NET
ReadOnly True
SelectionMode FullRowSelect
El diseño del formulario debe quedar similar al gráfico 4.45:
Gráfico 4.45: Diseño del formulario Lista Empleados
Agregar un nuevo reporte: del menú “Project”, seleccionar “Add New
Item”.
En la sección “Reporting” elegir “Report” y escribir como nombre:
“[Link]”.
En el menú “Data”, seleccionar “Add New Data Source…”
Se mostrará el asistente para la configuración de origenes de datos
similar a la figura 4.46.
Seleccionar como origen de datos la opción “Object” y clic en el botón
“Next”.
Se mostrará la opción para seleccionar objetos del asistente para la
configuración de origenes de datos similar a la figura 4.47.
Seleccionar la clase “beEmpleado” de la librería “[Link]
Entities” y clic en el botón “Finish”.
Luis Dueñas Pag 448
La Biblia de Visual Basic .NET
Gráfico 4.46: Asistente Origenes de Datos – Elegir tipo de origen
Gráfico 4.47: Asistente Origenes de Datos – Seleccionar objetos
Luis Dueñas Pag 449
La Biblia de Visual Basic .NET
Se mostrará el diseñador de informes de Microsoft similar a la figura
4.48.
Gráfico 4.48: Diseñador de Informes Microsoft
En la parte supeior izquierda se muestra el cuadro de herramientas con
los controles para crear el reporte.
En la parte inferior derecha se aprecia el origen de datos creado para
especificar que campo queremos visualizar en el reporte.
Arrastrar un control “TextBox” del cuadro de herramientas y escribir:
“Lista de Empleados”.
Clic derecho a cualquier barra de herramientas y seleccionar la barra
“Report Formatting”.
De la barra configurar el texto a 14 pt, negrita, centrado, color de texto
“rojo” y color de fondo “aqua”.
Del cuadro de herramientas arrastrar el control “Tabla” y aparecerá un
diálogo similar al de la figura 4.49.
Luis Dueñas Pag 450
La Biblia de Visual Basic .NET
Gráfico 4.49: Diálogo de Propiedades del conjunto de datos
Escribir como nombre para el conjunto de datos “ListaEmpleado”, en la
opción “Data Source” elegir “[Link]” y luego en
“Available datasets” seleccionar “beEmpleado”.
En la tabla clic en la primera celda de la última fila y seleccionar el
campo “Codigo”.
En la segunda celda seleccionar “Apellido” y en la tercera “Nombre”.
Seleccionar la última columna, dar clic derecho y del menú contextual
seleccionar “Insert Column”, luego “Right”.
En la cuarta columna seleccionar el campo “FechaNac”.
Mover la tabla y seleccionar cada columna y dar los siguientes anchos
en la propiedad size, width: 2 para la primera columna, 4 para la
segunda y tercera columna y 3 para la cuarta columna.
Seleccionar la fila de las cabeceras y configurar en negrita, centrado y
color de fondo “gris”.
Luis Dueñas Pag 451
La Biblia de Visual Basic .NET
Dar clic derecho a cualquier barra de herramientas y seleccionar la
barra “Report Borders”.
Seleccionar la tabla, y de la barra de bordes elegir “Outside Border”.
El diseño del reporte debe quedar como se muestra en la figura 4.50.
Gráfico 4.50: Diseño del Reporte de Empleados
Por defecto los campos datetime aparecerán como fecha y hora, para
no mostrar la hora en el campo “FechaNac”.
Clic derecho sobre la cuarta celda y seleccionar “Expression”.
Gráfico 4.51: Diálogo de Expresiones de Informes Microsoft
Luis Dueñas Pag 452
La Biblia de Visual Basic .NET
Nota: En el editor de expresiones se puede escribir fórmulas usando
campos del origen de datos, operadores, funciones, etc.
Expandir la categoría “Common Functions”, seleccionar “Text” y luego
“FormatDateTime”.
Cortar el valor de la expresión, dar doble clic a la función, pegar lo
cortado y completar la expresión como se muestra a continuación:
=FormatDateTime(Fields![Link],[Link]).
Alinear la celda de la fecha a la derecha,cerrar la ventana del diseñador
de reporte e ir al formulario.
Hacer una referencia a la librería del visor de reportes para Windows:
del menú “Project”, “Add references” y elegir “[Link].
WinForms”.
Gráfico 4.52: Diálogo para agregar refencia al ReportViewer
Escribir el siguiente código para el formulario:
Imports [Link]
Imports [Link]
Imports [Link]
Luis Dueñas Pag 453
La Biblia de Visual Basic .NET
Public Class frmListaEmpleado
Private lobeEmpleado As New List(Of beEmpleado)
Private Sub ListarEmpleados(ByVal sender As Object, _
ByVal e As EventArgs) Handles [Link]
Dim obrEmpleado As New brEmpleado
lobeEmpleado = [Link]
[Link] = lobeEmpleado
End Sub
Private Sub VerPreviewReporte(ByVal sender As Object, _
ByVal e As EventArgs) Handles [Link]
Dim frm As New Form
Dim rv As New ReportViewer
With [Link]
.ReportPath = _
"C:\Data\DemosLibro\LibroVB2010\Demo67\[Link]"
.[Link](New ReportDataSource _
("ListaEmpleado", lobeEmpleado))
End With
[Link]()
[Link] = [Link]
[Link](rv)
[Link] = "Preview del Reporte de Empleados"
[Link] = [Link]
[Link]()
End Sub
End Class
Nota: En el código anterior se crea dinámicamente un formulario con un
visor el cual para mostrar el reporte necesita configurar 2 propiedades de
su propiedad LocalReport que son ReportPath con la ruta del reporte y
DataSource con el origen de datos asociado al reporte y con la lista de
objetos a llenar.
Agregar un archivo de configuración a la aplicación: del menú “Project”,
seleccionar “Add New Item”, en la categoría “General” seleccionar
“Application Configuration File”.
Luis Dueñas Pag 454
La Biblia de Visual Basic .NET
Agregar en el archivo de configuración la clave conNW en la sección
appSettings:
<configuration>
<appSettings>
<add key="conNW" value="uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 4.53: Ejecución del formulario Lista Empleados
Clic derecho a la grilla de empleados y del menú contextual seleccionar
“Preview”.
Se mostrará la ventana del reporte similar a la figura 4.54.
Luis Dueñas Pag 455
La Biblia de Visual Basic .NET
Gráfico 4.54: Ejecución del Reporte de Empleados
Importante: En la ventana del visor podremos realizar las siguientes
acciones con el reporte:
Avanzar a cualquier página.
Imprimir el reporte.
Ajustar la vista de la página.
Configurar la página: tamaño, tipo, orientación y márgenes.
Exportar: Excel, PDF y Word.
Configurar Zoom.
Buscar un texto dentro del reporte, etc.
Luis Dueñas Pag 456
La Biblia de Visual Basic .NET
5.3. Trabajando con Word
En muchas ocasiones necesitamos crear dinámicamente un documento de
Word con los datos de la aplicación, para esto debemos usar
automatización COM o ActiveX.
Desde .NET cuando usamos otras tecnologías como COM, ActiveX o APIs
trabajamos con [Link], es decir creamos un
puente entre el CLR de .NET y otro Motor de Ejecución externo.
Para usar un componente COM desde Visual Basic como Word o Excel,
existen 2 formas:
Enlace en tiempo de diseño (Early Binding)
Es el mecanismo más usado y consiste en referenciar a una librería de
tipos, la ventaja es que permite crear objetos y usar miembros
disponiendo de la ayuda del IDE que usemos, la desventaja es que nos
hacemos dependiente de una versión especifica del programa, por
ejemplo MS Word 2010.
Enlace en tiempo de ejecución (Late Binding)
Mediante esta técnica no es necesario hacer referencia a ninguna
librería de tipos en especial ya que se crean los objetos usando el
método CreateObject (solo para Visual Basic), la ventaja es que no
dependemos de ninguna versión del programa, se toma la última
existente, la desventaja es que no disponemos de ayuda para crear los
objetos y usar los métodos es decir hay que conocer de memoria todos
los componentes, recomendable para expertos en dicho componente.
La recomendación que haría seria para desarrollar hacerlo usando la
librería de tipos (enlace en tiempo de diseño) y al final antes de desplegar
a producción quitar la referencia y cambiar a enlace en ejecución.
A continuación un ejemplo de cómo crear documentos de Word
dinámicamente, primero mediante enlace en tiempo de diseño llenaremos
un formato de ficha de producto predefinido con los datos del producto
seleccionado y segundo mediante enlace en tiempo de ejecución crearemos
una lista con todos los productos.
Luis Dueñas Pag 457
La Biblia de Visual Basic .NET
Demo 68
Del menú “File”, seleccionar “Add”, “New Project” y luego “Windows
Forms Application”.
Crear una aplicación en Visual Basic llamada: Demo68.
Hacer una referencia a las librerías [Link] y
[Link].
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmListaProducto
FormBorderStyle FixedSingle
Size 500, 400
MaximizeBox False
MinimizeBox False
Text Creación de Documen
tos de Productos con
MS Word
StartUpPosition CenterScreen
ContextMenuStrip1 Name mnuDocumento
ToolStripMenuItem1 Name mnuCrearFicha
Text Crear Ficha
ToolStripMenuItem2 Name mnuCrearLista
Text Crear Lista
DataGridView1 Name dgvProducto
AllowUserToAddRows False
AllowUserToDeleteRows False
ContextMenuStrip mnuDocumento
Dock Fill
ReadOnly True
SelectionMode FullRowSelect
El diseño del formulario debe quedar similar al gráfico 4.55:
Luis Dueñas Pag 458
La Biblia de Visual Basic .NET
Gráfico 4.55: Diseño del formulario Lista Productos
Hacer una referencia a la librería de tipos de MS Word: clic derecho al
proyecto, seleccionar “Add Reference” y luego en la ficha “COM”
seleccionar “Microsoft Word 12.0 Object Library” como se ve debajo.
Gráfico 4.56: Diálogo de Agregar Referencia a MS Word
Luis Dueñas Pag 459
La Biblia de Visual Basic .NET
Crear un documento en MS Word para la Ficha del Producto, similar al
de la siguiente figura.
Gráfico 4.57: Diseño del Documento Ficha del Producto en Word
Nota: Para crear la Ficha del Producto en MS Word se debe activar la
“Ficha del Programador” y luego usar de la barra “Formularios Heredados”
el control “Campo de texto”, el cual se muestra como una sombra gris.
Grabe el documento como “Ficha del [Link]” en alguna ubicación
donde podamos recuperarlo mediante el programa.
Escribir el siguiente código para el formulario:
Imports [Link]
Imports [Link]
Public Class frmListaProducto
Private lobeProducto As New List(Of beProducto)
Private Ruta As String = _
"C:\Lduenas\NET\LibroVB2010\Archivos\"
Private Sub ListarProductos(ByVal sender As [Link], _
Luis Dueñas Pag 460
La Biblia de Visual Basic .NET
ByVal e As [Link]) Handles [Link]
Dim obrProducto As New brProducto
lobeProducto = [Link]()
[Link] = lobeProducto
End Sub
Private Sub CrearFicha(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If [Link] > 0 Then
With [Link]
Dim DocPlantilla As String = _
[Link]("{0}Ficha del [Link]", Ruta)
Dim DocFicha As String = _
[Link]("{0}Ficha del Producto {1}.docx", _
Ruta, .Cells(1).Value)
Dim oWord As New [Link]
[Link] = True
[Link](DocPlantilla)
[Link](1).[Link] = _
.Cells(0).Value
[Link](2).[Link] = _
.Cells(1).Value
[Link](3).[Link] = _
.Cells(4).Value
[Link](4).[Link] = _
.Cells(5).Value
[Link](DocFicha)
End With
End If
End Sub
Private Sub CrearLista(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim oWord As Object = CreateObject("[Link]")
[Link] = True
[Link]()
With [Link]
.[Link] = 16
.[Link] = 2
.TypeText("Lista de Productos")
Luis Dueñas Pag 461
La Biblia de Visual Basic .NET
.TypeParagraph()
Dim Rango As Object = .Range
.[Link](Rango, [Link] + 1, _
[Link])
.Style = "Tabla con cuadrícula"
.Tables(1).ApplyStyleHeadingRows = True
.Tables(1).ApplyStyleFirstColumn = True
.Tables(1).ApplyStyleColumnBands = True
For I = 0 To [Link] - 1
.Tables(1).Rows(1).Cells(I + 1).Select()
.[Link] = 12
.[Link] = 6
.TypeText([Link](I).HeaderText)
Next
.[Link] = 1
For I = 0 To [Link] - 1
For J = 0 To [Link] - 1
.Tables(1).Rows(I + 2).Cells(J + 1).Select()
.[Link] = 12
.[Link] = 1
.TypeText([Link](I).Cells(J).[Link])
Next
Next
End With
Dim DocLista As String = _
[Link]("{0}Lista de [Link]", Ruta)
[Link](DocLista)
End Sub
End Class
Nota: Observe al escribir el código de Crear la Ficha como se muestra la
ayuda de las clases y miembros de cada clase de Word ya que se usa el
enlace en tiempo de diseño, pero en cambio, al Crear la Lista mediante
enlace en tiempo de ejecución (CreateObject) no se dispone de la ayuda.
Agregar un archivo de configuración a la aplicación: del menú “Project”,
seleccionar “Add New Item”, en la categoría “General” seleccionar
“Application Configuration File”.
Luis Dueñas Pag 462
La Biblia de Visual Basic .NET
Agregar en el archivo de configuración la clave conNW en la sección
appSettings:
<configuration>
<appSettings>
<add key="conNW" value="uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 4.58: Ejecución del formulario Lista Productos
Clic derecho sobre la grilla de productos y se presentará un menú
contextual, seleccionar la opción Crear Ficha y se verá la figura 4.57.
Luis Dueñas Pag 463
La Biblia de Visual Basic .NET
Gráfico 4.59: Ejecución del Documento Ficha de Producto en Word
Clic derecho sobre la grilla de productos y del menú contextual ahora
seleccionar la opción Crear Lista y se verá la siguiente figura.
Gráfico 4.60: Ejecución del Documento Lista de Productos Word
Luis Dueñas Pag 464
La Biblia de Visual Basic .NET
5.4. Trabajando con Excel
Excel es una de las aplicaciones mas usadas del mercado para realizar
cálculos y crear gráficos de datos. Desde .NET podemos usar el potencial
de Excel para realizar cálculos complejos o gráficos de datos de diversos
tipos, lo que seria trabajoso en caso de hacerlo desde cero por código.
Al igual que Word la técnica de enlace puede ser en tiempo de diseño o en
ejecución. La programación es muy similar lo que cambia es el modelo de
objetos, en Word se trabaja con Documentos (Documents) y en Excel
trabajamos con Libros (WoorkBooks).
A continuación un ejemplo de creación de una hoja de Excel con los
precios de los productos y un gráfico de barras en 3D.
Demo 69
Del menú “File”, seleccionar “Add”, “New Project” y luego “Windows
Forms Application”.
Crear una aplicación en Visual Basic llamada: Demo69.
Hacer una referencia a las librerías [Link] y
[Link].
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario de acuerdo a la siguiente tabla:
Objeto Propiedad Valor
Form1 Name frmListaProducto
FormBorderStyle FixedSingle
Size 400, 300
MaximizeBox False
MinimizeBox False
Text Creación de Gráficos
con MS Excel
StartUpPosition CenterScreen
ContextMenuStrip1 Name mnuExcel
ToolStripMenuItem1 Name mnuCrearGrafico
Text Crear Gráfico
DataGridView1 Name dgvProducto
Luis Dueñas Pag 465
La Biblia de Visual Basic .NET
AllowUserToAddRows False
AllowUserToDeleteRows False
ContextMenuStrip mnuExcel
Dock Fill
ReadOnly True
SelectionMode FullRowSelect
El diseño del formulario debe quedar similar al gráfico 4.61:
Gráfico 4.61: Diseño del formulario Lista Productos
Hacer una referencia a la librería de tipos de MS Excel: clic derecho al
proyecto, seleccionar “Add Reference” y luego en la ficha “COM”
seleccionar “Microsoft Excel 12.0 Object Library” como se ve en la
figura 4.62.
Luis Dueñas Pag 466
La Biblia de Visual Basic .NET
Gráfico 4.62: Diálogo de Agregar Referencia a MS Excel
Escribir el siguiente código para el formulario:
Imports [Link]
Imports [Link]
Public Class frmListaProducto
Private lobeProducto As New List(Of beProducto)
Private Sub ListarProductos(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim obrProducto As New brProducto
lobeProducto = [Link]()
[Link] = lobeProducto
[Link](0).Visible = False
[Link](1).Width = 250
[Link](2).Visible = False
[Link](3).Visible = False
[Link](4).Width = 80
[Link](4).[Link] = _
[Link]
[Link](4).[Link] = "n2"
[Link](5).Visible = False
End Sub
Luis Dueñas Pag 467
La Biblia de Visual Basic .NET
Private Sub CrearFicha(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim oExcel As New [Link]
Dim oRango As [Link]
[Link] = True
[Link]()
With oExcel
.Cells(1, 1).Value = "Descripción del Producto"
.Cells(1, 2).Value = "Precio Unitario"
For I = 0 To [Link] - 1
.Cells(I + 2, 1).Value = [Link](I).Cells(1).Value
.Cells(I + 2, 2).Value = [Link](I).Cells(4).Value
Next
.[Link]()
.Range("A1").Select()
oRango = .[Link]
.[Link]()
End With
With [Link]
.Location(1)
.SetSourceData(oRango, 2)
.ChartType = -4100
.[Link] = "Gráfico de Precios de Productos"
End With
End Sub
End Class
Nota: En el código anterior el método AutoFit de la colección Columns
permite autoajustar el ancho de todas las columnas automaticamente.
Agregar un archivo de configuración a la aplicación: del menú “Project”,
seleccionar “Add New Item”, en la categoría “General” seleccionar
“Application Configuration File”.
Agregar en el archivo de configuración la clave conNW en la sección
appSettings:
<configuration>
<appSettings>
<add key="conNW" value="uid=sa;pwd=123456;
Luis Dueñas Pag 468
La Biblia de Visual Basic .NET
data source=Lduenas\MCTS;initial catalog=Northwind"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 4.63: Ejecución del formulario Lista Productos
Clic derecho sobre la grilla de productos y se presentará un menú
contextual, seleccionar la opción Crear Gráfico.
Se creará dinámicamente un libro de Excel con 2 hojas: la primera hoja
tiene 2 columnas que muestran el nombre y el precio de los productos
y la segunda hoja tiene el gráfico similar al que se muestra en la figura
4.64.
Luis Dueñas Pag 469
La Biblia de Visual Basic .NET
Gráfico 4.64: Gráfico de Barras de Precios de Productos en Excel
Luis Dueñas Pag 470
La Biblia de Visual Basic .NET
5.5. Usando el Control Chart
El Control Chart permite crear gráfico de datos sin necesidad de salir del
entorno de desarrollo de .NET y recurrir a Excel o librerías de terceros. Este
se encuentra en [Link] en la
clase Chart para lo cual es necesario hacer referencia a la librería
DataVisualization de Windows Forms.
Las 2 propiedades más importantes de la clase Chart son las colecciones
ChartAreas y Series. La propiedad de colección Series almacena objetos
Series, que se utilizan para almacenar datos que serán mostrados, junto
con los atributos de esos datos. La propiedad de colección ChartAreas
almacena objetos ChartArea, que se utilizan principalmente para dibujar
uno o más gráficos mediante un conjunto de ejes.
Para crear un gráfico con el control Chart es necesario configurar las
propiedades del objeto Serie como sigue: la propiedad ChartArea con el
nombre de un objeto ChartArea previamente definido, la propiedad
XValueMember con el nombre del campo o propiedad que irá en el eje de
las X y la propiedad YValueMembers con el nombre o nombres de series
que se graficarán en el eje de las Y.
Para obtener más información sobre el control Chart ver la referencia 29 al
final del libro. A continuación, el siguiente ejemplo muestra como crear un
gráfico de productos usando el control Chart de Windows Forms.
Demo 70
Del menú “File”, seleccionar “Add”, “New Project” y luego “Windows
Forms Application”.
Crear una aplicación en Visual Basic llamada: Demo70.
Hacer una referencia a las librerías [Link] y
[Link].
Cambiar de nombre al formulario de [Link] a [Link]
Configurar el formulario de acuerdo a la siguiente tabla:
Luis Dueñas Pag 471
La Biblia de Visual Basic .NET
Objeto Propiedad Valor
Form1 Name frmListaProducto
FormBorderStyle FixedSingle
Size 400, 300
MaximizeBox False
MinimizeBox False
Text Creación de Gráficos
con el Control Chart
StartUpPosition CenterScreen
ContextMenuStrip1 Name mnuChart
ToolStripMenuItem1 Name mnuCrearGráfico
Text Crear Gráfico
DataGridView1 Name dgvProducto
AllowUserToAddRows False
AllowUserToDeleteRows False
ContextMenuStrip mnuChart
Dock Fill
ReadOnly True
SelectionMode FullRowSelect
El diseño del formulario debe quedar similar al gráfico 4.65:
Gráfico 4.65: Diseño del formulario Lista Productos
Hacer una referencia a la librería de tipos DataVisualization: clic
derecho al proyecto, seleccionar “Add Reference” y luego en la ficha
“NET” seleccionar “[Link]” como se
ve en la figura 4.66.
Luis Dueñas Pag 472
La Biblia de Visual Basic .NET
Gráfico 4.66: Diálogo de Agregar Referencia a DataVisualization
Escribir el siguiente código para el formulario:
Imports [Link]
Imports [Link]
Imports [Link]
Imports [Link]
Public Class frmListaProducto
Private lobeProducto As New List(Of beProducto)
Private Sub ListarProductos(sender As [Link], e As
[Link]) Handles [Link]
Dim obrProducto As New brProducto
lobeProducto = [Link]()
[Link] = lobeProducto
[Link](0).Visible = False
[Link](1).Width = 250
[Link](2).Visible = False
[Link](3).Visible = False
[Link](4).Width = 80
[Link](4).[Link] = _
[Link]
[Link](4).[Link] = "n2"
[Link](5).Visible = False
Luis Dueñas Pag 473
La Biblia de Visual Basic .NET
End Sub
Private Sub CrearGráfico(sender As [Link], e As [Link])
Handles mnuCrearGrá[Link]
Dim oArea As New ChartArea("Area")
Dim oSerie As New Series("Serie")
With oSerie
.ChartArea = "Area"
.ChartType = [Link]
.XValueMember = "Nombre"
.YValueMembers = "PrecioUnitario"
.IsValueShownAsLabel = True
.Color = [Link]
End With
Dim oGrafico As New Chart
With oGrafico
.BackColor = [Link]
.Dock = [Link]
.[Link]([Link]("Gráfico de Productos"))
.Titles(0).ForeColor = [Link]
.Titles(0).Font = New Font("Arial", 20)
.[Link](oArea)
.[Link](oSerie)
.DataSource = lobeProducto
End With
Dim frmGrafico As New Form
With frmGrafico
.Text = "Grafico"
.WindowState = [Link]
.[Link](oGrafico)
.ShowDialog()
End With
End Sub
End Class
Importante: Si no se especifica la propiedad ChartArea de la clase Series
no se visualiza el gráfico.
Agregar un archivo de configuración a la aplicación: del menú “Project”,
seleccionar “Add New Item”, en la categoría “General” seleccionar
“Application Configuration File”.
Luis Dueñas Pag 474
La Biblia de Visual Basic .NET
Agregar en el archivo de configuración la clave conNW en la sección
appSettings:
<configuration>
<appSettings>
<add key="conNW" value="uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 4.67: Ejecución del formulario Lista Productos
Clic derecho sobre la grilla de productos y se presentará un menú
contextual, seleccionar la opción Crear Gráfico.
Se creará dinámicamente un formulario conteniendo un gráfico de
barras de los precios de los productos, similar al que se muestra en la
figura 4.68.
Luis Dueñas Pag 475
La Biblia de Visual Basic .NET
Gráfico 4.68: Gráfico de Barras de Precios con el Control Chart
Luis Dueñas Pag 476
La Biblia de Visual Basic .NET
Preguntas de Repaso
1. Cual es la ventaja de crear aplicaciones Windows con Windows Forms?
2. Qué propiedades del formulario deben configurarse para que no pueda
modificarse de tamaño?
3. Qué propiedad del formulario debe configurase para mostrar en el
formulario un gráfico en forma de elipse o cualquier forma deseada?
4. En qué evento del formulario debe programarse la creación de un
gráfico?
5. Menciona 3 controles básicos de Windows Forms.
6. Qué propiedad del control TextBox permite limitar la cantidad de
caracteres ingresados?
7. De qué formas puede crearse un TextBox que permita ingresar una
contraseña o password?
8. Qué debe hacerse para que al dar Enter sobre cualquier control de
entrada se dispare el procedimiento asociado al clic de un botón?
9. De forma similar, qué debe hacerse para que al pulsar la tecla Escape
se dispare el procedimiento asociado al clic de un botón de salida?
10. Qué se debe configurar en un control Label para que muestre el
símbolo & como un carácter mas o literal.
11. Menciona 3 controles de listas de Windows Forms.
12. Cuál es la propiedad más importante de los controles de listas?
13. Menciona 3 métodos de la propiedad Items para manejar listas.
Luis Dueñas Pag 477
La Biblia de Visual Basic .NET
14. Menciona el evento más importante en el cual generalmente se
programa cuando se selecciona un elemento de una lista.
15. Cuál es la forma mas recomendada de llenar los elementos de una lista.
16. Si la lista se va a llenar elemento por elemento qué métodos debe
usarse antes y después de llenar la lista para evitar escribir cada
elemento en pantalla?
17. Menciona los 2 controles de vistas en Windows Forms.
18. Cuál es la propiedad más importante del control TreeView?
19. Cuál es la propiedad más importante del control ListView?
20. Cuáles son las vistas que puede presentar el control ListView?
21. Cuáles son las propiedades donde se configuran las imágenes a mostrar
en un ListView?
22. Cómo se llama el control Windows Forms que permite dividir el
formulario en 2 partes, por ejemplo para separar a un TreewView de un
ListView?
23. Qué control permite guardar una colección de imágenes?
24. Qué es un formulario MDI y cómo se crea en Windows Forms?
25. Cómo se puede cambiar el fondo de un formulario MDI?.
26. Qué propiedad del formulario MDI padre indica la cantidad de
formularios hijos activos?
27. Qué bede configurarse en Visual Studio para trabajar con un formulario
Login que al auntenticarse se cierre y abra un formulario MDI que
cuando se cierre finalize toda la aplicación?.
Luis Dueñas Pag 478
La Biblia de Visual Basic .NET
28. Cúantos tipos de menús hay y cómo se crean en Windows Forms?
29. Qué propiedad es necesario configurar de un control para que se
muestre un menú contextual?
30. Cómo se puede cargar dinámicamente un formulario teniendo como
dato su nombre?
31. Qué tipo de control permite agregar cualquier control como opción o
elemento de un menú?
32. Cómo se llama el control de Windows Forms que muestra un calendario
con los días de un mes?
33. Menciona los 5 diálogos comunes de Windows que son componentes de
Windows Forms.
34. Cómo se llama el método común que tienen todos los diálogos de
Windows que permiten mostrar el diálogo en pantalla?
35. Qué propiedades comunes tienen los diálogos de archivos OpenFile
Dialog y SaveFileDialog en Windows Forms?
36. Cuál es la propiedad más importante del diálogo de color?
37. Cuál es la propiedad más importante del diálogo de fuente?
38. Cómo se llama el diálogo que permite mostrar directorios?
39. Menciona las barras que se pueden crear en Windows Forms.
40. Cómo se llama la colección de elementos que tienen ambas barras en
Windows Forms?
41. Qué tipo de ToolStripItem tiene la Barra de Herramientas que no tiene
la Barra de Estado?
Luis Dueñas Pag 479
La Biblia de Visual Basic .NET
42. Cuál es el control mas usado para presentar una lista de datos en
Windows Forms?
43. Menciona 3 propiedades Allow del control DataGridView de Windows.
44. Qué pasos debe realizar para crear un DataGridView con columnas
personalizadas?
45. Menciona los 5 tipos de columnas personalizadas que puede tener el
DataGridView.
46. Cómo se llama la propiedad de la columna personalizada que especifica
que dato (campo o propiedad) vamos a presentar?
47. Qué pasos debe realizar para crear un DataGridView con una columna
que muestre una imagen?
48. En qué evento del DataGridView hay que programar para formatear las
columnas del control?
49. Cómo se configura el tamaño de la imagen mostrada en la columna del
DataGridView?
50. En qué evento del DataGridView hay que programar para personalizar
las cabeceras del control?
51. Cómo se crea un gráfico personalizado dentro de una columna del
control GridView?
52. Para qué se usa el modo Virtual del DataGridView?
53. Qué propiedades del DataGridView hay que configurar para crear una
paginación de datos?
54. En qué evento del DataGridView hay que programar para mostrar los
valores de las celdas en una paginación?
Luis Dueñas Pag 480
La Biblia de Visual Basic .NET
55. Qué método del DataGridView hay que invocar para actualizar los
valores de las celdas mostradas en la paginación?
56. Cómo se clasifican los controles que se pueden crear en Windows?
57. Qué tipo de control crearía si desea aumentar las características de un
control existente en Windows Forms?
58. Qué tipo de control crearía si desea usar varios controles de Windows?
59. De qué clase hereda el control personalizado o dibujado?
60. Mencione 3 formas de crear un reporte en Windows Forms.
61. Para qué se usa la clase PrintDocument y en qué espacio de nombres
se encuentra?
62. En qué evento de la clase PrintDocument se tiene que escribir código
para crear la pagina a imprimir?
63. Menciona el control y los 3 diálogos que se pueden asociar a la clase
PrintDocument para crear reportes.
64. Cuál es la diferencia entre el control PrintPreviewControl y el diálogo
PrintPreview al crear la vista preliminar del reporte?
65. En qué consiste los Informes de Microsoft y cuáles son sus dos
componentes principales?
66. Para qué sirve el control ReportViewer?
67. Cuáles son las barras de herramientas que se usan en el diseñador de
informes de Microsoft.
68. Qué propiedades del control ReportViewer deben configurarse para
mostrar un reporte de datos?
Luis Dueñas Pag 481
La Biblia de Visual Basic .NET
69. A qué formatos puede exportar el ReportViewer?
70. Cuál es la diferencia entre crear un gráfico en Excel o usar el control
Chart?
71. Qué propiedades son las más importantes de la clase Chart?
72. En qué espacio de nombres se ubica la clase Chart?
Luis Dueñas Pag 482
La Biblia de Visual Basic .NET
Capitulo 5: Desarrollando Aplicaciones Web con ASP
.NET
En este capítulo abordaremos la creación de aplicaciones o sitios Web
mediante ASP .NET usando el Formulario y los Controles Web.
Al inicio veremos como crear un simple sitio web usando Formularios y
Controles Web sobre todo los controles web estándares simples o
intrínsecos, también aprenderemos como trabajar con imágenes y usar
controles de validación, además veremos como subir archivos desde la
pagina al servidor web con el control FileUpload.
En la segunda parte de este capítulo mejoraremos el diseño del sitio web
usando Hojas de Estilo en Cascada (CSS) y aumentaremos las
características de navegabilidad usando controles de navegación, controles
de vistas y creando páginas principales y de contenido.
En la tercera parte se verá en detalle el control web GridView, iniciando por
personalizar sus columnas, paginar registros, ordenar columnas, realizar un
mantenimiento sobre el mismo control: adicionar, actualizar y eliminar
registros de una BD usando objetos.
Como cuarto tema veremos como crear plantillas en controles enlazados a
datos como el Repeater y DataList, esto nos permitirá personalizar la
apariencia del control a la forma que deseemos, por ejemplo crearemos
una plantilla jerárquica para mostrar una grilla dentro de otra.
Luis Dueñas Pag 483
La Biblia de Visual Basic .NET
1. Trabajar con el Formulario y los Controles Web
La forma más fácil de crear una aplicación web en ASP .NET es usar los
Formularios y Controles Web que son clases ubicadas dentro del espacio de
nombres: [Link] para Page y [Link] para
los controles Web.
Para crear el formulario y los controles web podemos usar cualquier editor
de texto y escribir código en Visual Basic, pero para realizar más rápido el
desarrollo se usa el Visual Studio .NET el cual para la creación de sitios web
es conocido como: Visual Web Developer.
Antes de iniciar con la creación de aplicaciones web daremos una
introducción a ASP .NET para conocer mejor sus características y ventajas,
conoceremos la clasificación de los controles en ASP .NET y también
entenderemos el ciclo de vida de una página creada mediante formularios
web en ASP .NET.
1.1. Introducción a ASP .NET
ASP .NET es un modelo de desarrollo unificado que es parte del .NET
Framework y permite crear de forma fácil y con un mínimo de código
Aplicaciones Web, es decir, aplicaciones para Internet que se usen desde
cualquier Browser.
Para obtener mas información sobre ASP NET ver la referencia 30 al final
del libro.
Características de ASP .NET
Usa las Librerías de Clases del .NET Framework (BCL), que contienen
miles de tipos para ser usados, entre clases, interfaces, estructuras,
etc.
Para escribir código del servidor se puede usar cualquier Lenguaje .NET
disponible, entre ellos Visual Basic, C#, J#, Cobol, Delphi, etc.
Luis Dueñas Pag 484
La Biblia de Visual Basic .NET
El código esta totalmente compilado en el servidor.
Las páginas web de ASP .NET que usan Controles Web del servidor se
pueden ver en cualquier Browser porque generan HTML y javascript en
el cliente.
El resultado de la página se puede guardar en Cache para una mayor
velocidad de respuesta.
No solo se puede crear aplicaciones web, sino también aplicaciones web
móviles y servicios web.
Para configurar la aplicación web se puede realizar mediante el
Administrador del IIS pero también mediante el archivo [Link]
Para manejar eventos de página, sesión, aplicación, etc, no solo se
puede hacer creando controladores o módulos HTTP sino también se
puede programar en los eventos del archivo [Link].
Para asegurar la aplicación web se puede hacer mediante el IIS,
Formularios Web o los servicios de Passport.
Formularios y Controles en ASP .NET
Un Formulario Web es el contenedor de controles web que se envían desde
el cliente al servidor y que guardan el estado o los valores de los controles
de entrada enviados, también tiene la capacidad de ejecutar código del
lado del servidor.
Un Formulario Web tiene controles del servidor los cuales se clasifican en:
Controles HTML del Servidor: Son similares a los controles HTML del
cliente sino que tienen el atributo runat=”server” que indican que
también pueden ejecutan código en el servidor.
Controles Web: Son controles especiales creados por Microsoft para
facilitar el trabajo de crear aplicaciones web y se clasifican en:
Controles Estándares
Luis Dueñas Pag 485
La Biblia de Visual Basic .NET
Controles de Datos
Controles de Validación
Controles de Navegación
Controles de Inicio de Sesión
Controles de Informes
Controles de Servidor AJAX
Controles de Elementos Web
Controles de Datos Dinámicos
Nota: Los controles HTML se encuentran en [Link]
y los controles Web se encuentran en [Link].
Ciclo de Vida de una Página Web en ASP .NET
Desde que un usuario llama a una pagina ASP .NET hasta que se presenta
el resultado en el Browser ocurren una serie de actividades que es
necesario conocer para entender el funcionamiento de una página y poder
programar adecuadamente ésta, estas actividades son:
Por primera vez se solicita (Request) una página ASP .NET (aspx) sel
sitio web a través de un Browser mediante un protocolo, por ejemplo:
Http.
El Parser de ASP .NET analiza la sintáxis de todas las etiquetas de
controles web del servidor: <asp:control runat=”server”> y si alguna
tuviera un error se muestra una excepción de parser en el cliente.
El código del servidor de la página escrito en algún lenguaje .NET como
Visual Basic es compilado por el Compilador del Lenguaje .NET por
ejemplo para Visual Basic es el [Link] y si alguna instrucción tuviera
error se muestra una excepción de compilación en el cliente.
Luis Dueñas Pag 486
La Biblia de Visual Basic .NET
Al compilar el código de alto nivel se crea un ensamblado en lenguaje
de nivel intermedio de Microsoft (MSIL).
El compilador JIT del CLR convierte el código intermedio en bajo nivel
creando un ensamblado nativo.
El CLR ejecuta el código nativo y forma la respuesta HTML.
La respuesta (Response) HTML es enviada al cliente.
El cliente recibe el HTML y el parser analiza si la sintáxis de la página
esta bien formada y si no lo esta se muestra un error.
Una vez listo la página el Browser lo presenta.
En el caso de haber secuencias de comandos (scripts) de lado del
cliente, el Motor de Ejecución de Scripts ejecuta el respectivo código.
Si se devuelve la página al servidor (PostBack) a través de un botón por
ejemplo o cualquier control de entrada con propiedad AutoPostBack en
true, la pagina ya no se parsea ni se compila, por estar en memoria.
El CLR ejecuta nuevamente el código nativo del servidor y forma la
respuesta HTML que es enviada al cliente, y asi se vuelve a repetir el
ciclo antes mencionado solo los últimos pasos.
Finalmente, es necesario entender que existen 2 procesos bien diferentes
que son el cliente compuesto por el Browser, por ejemplo el Internet
explorer ([Link]) y el Servidor Web de Microsoft que es el Internet
Information Server (IIS) cuyo proceso se encuentra en [Link].
Una aplicación web en ASP .NET puede tener código que se ejecuta en el
cliente o en el servidor, para el cliente podemos usar Javascript, DOM de
HTML, JQuery, AJAX, etc y para el servidor podemos usar Formularios
Web, Controles Web, Lenguajes .NET, Librerías de Clases de .NET (BCL),
etc.
Luis Dueñas Pag 487
La Biblia de Visual Basic .NET
1.2. Creando un Simple Sitio Web
Para crear un sitio web en ASP .NET con Visual Web Developer se puede
crear en 3 ubicaciones distintas:
Sistema de archivos (File System): No necesita tener instalado el
servidor web IIS, sino trabaja en forma local con un servidor virtual.
HTTP: Necesita tener instalado localmente un servidor web IIS y es el
mas recomendable para desarrollar aplicaciones para Internet.
FTP: Crea un sitio web en cualquier servidor remoto disponible
mediante FTP, se usa cuando no tenemos un servidor propio y
alquilamos uno (Hosting).
En todos los ejemplos de este libro usaremos la segunda opción: HTTP
para lo cual primero es necesario tener instalado el IIS antes de instalar el
Visual Studio .NET por lo que registra unos scripts de ASP .NET en el IIS.
Además crearemos en el directorio por defecto de IIS: C:\inetpub\wwwroot
una carpeta llamada Demos para todos los sitios web creados en el libro.
Importante: Si ha instalado el IIS después del Visual Studio y no se
puede crear sitios web con ASP .NET No desinstale el Visual Studio, ingrese
al explorador de Windows a: C:\Windows\[Link]\Framework64,
luego en la carpeta v2.0.50727 arrastre el archivo aspnet_regiis.exe al
diálogo de ejecutar (Run) de Windows (tecla Windows + R) y al final
aumente -i para instalar ASP .NET 2. También hay que ingresar a la
carpeta v4.0.30319 y registrar el mismo archivo para ASP .NET 4.
Una vez instalado el IIS y registrado ASP .NET en IIS puede ingresar al
Administrador de IIS para ver los sitios web que va a crear, del menú
“Inicio”, seleccionar “Panel de Control”, “Herramientas Administrativas” y
luego “Administrador de Servicios de Información de Internet”, y se verá
una ventana similar a la mostrada en la figura 5.1
Luis Dueñas Pag 488
La Biblia de Visual Basic .NET
Gráfico 5.1: Ventana del Administrador de IIS
Seleccione el nodo “Default Web Site” y en el menú “Actions” del lado
derecho clic en “Basic Settings” para ver la configuración del directorio raíz,
y se mostrará un diálogo similar a la siguiente figura.
Gráfico 5.2: Diálogo de Configuración Básica Sitio Web x Defecto
Nota: Por defecto todos los sitios web creados heredarán la configuración
del directorio raíz del IIS, aunque se pueden cambiar por aplicación.
Ahora si, estamos listos para crear nuestro primer sitio web como lo
muestra el Demo 71 que tiene 3 páginas, la primera es un menú con 2
enlaces: uno a la primera página y el otro a la segunda.
Luis Dueñas Pag 489
La Biblia de Visual Basic .NET
Demo 71
Del menú “File”, seleccionar “Add”, “New Web Site” y aparecerá una
ventana similar a la mostrada en la figura 5.3.
Gráfico 5.3: Ventana de Creación de un Nuevo Sitio Web
En el lado izquierdo seleccionar como lenguaje “Visual Basic”.
En el lado derecho seleccionar como plantilla de proyecto: “ASP .NET
Empty Web Site”.
En el lado inferior elegir como ubicación HTTP y en la dirección escribir:
[Link] y clic en el botón “OK”.
Se creará un proyecto de sitio web vacío que solo trae un archivo de
configuración: [Link].
Agregar una nueva página de formulario web: del menú “Website”
seleccionar “Add New Item” y se mostrará una ventana similar al de la
figura 5.4.
Seleccionar la plantilla “Web Form” y dejarlo con el nombre sugerido
“[Link]”, clic en el botón “Add”.
Luis Dueñas Pag 490
La Biblia de Visual Basic .NET
Gráfico 5.4: Ventana de Creación de un Nuevo Item
Ubicarse dentro del div de la página e insertar una tabla: del menú
“Table” seleccionar “Insert Table” y se verá el diálogo de insertar tabla.
Gráfico 5.5: Diálogo de Insertar Tabla
Luis Dueñas Pag 491
La Biblia de Visual Basic .NET
Configurar que se necesita 4 filas y 1 columna y clic en el botón “OK”.
En la celda de la primera fila escribir el literal: “Un Simple Sitio Web en
ASP .NET”.
En la celda de la segunda fila escribir otro literal: “Seleccione ua
página”.
En la celda de la tercera fila arrastrar el control “Hiperlink” del cuadro
de herramientas y configurar su propiedad ID a “hlkPrimera” y su
propiedad Text a “Primera página”.
En la celda de la cuarta fila también arrastrar otro “Hiperlink” y
configurar su propiedad ID a “hlkSegunda” y su propiedad Text a
“Segunda página”.
Agregar una nueva página: del menú “Website”, seleccionar “Add New
Item” y llamarle “[Link]”.
Ubicarse dentro del div de la nueva página e insertar una tabla de 2
filas por 1 columna.
En la celda de la primera fila escribir el literal: “Esta es la Primera
Página”.
En la celda de la segunda fila arrastrar un control Hiperlink y configurar
su propiedad ID a “hlkRegresar”, su propiedad Text a “Regresar” y su
propiedad NavigateUrl a “[Link]”.
Agregar otra nueva página: del menú “Website”, seleccionar “Add New
Item” y llamarle “[Link]”.
Ubicarse dentro del div de la nueva página e insertar una tabla de 2
filas por 1 columna.
En la celda de la primera fila escribir el literal: “Esta es la Segunda
Página”.
En la celda de la segunda fila arrastrar un control Hiperlink y configurar
su propiedad ID a “hlkRegresar”, su propiedad Text a “Regresar” y su
propiedad NavigateUrl a “[Link]”.
Luis Dueñas Pag 492
La Biblia de Visual Basic .NET
Regresar a la primera página ([Link]) y configurar la propiedad
NavigateUrl de los 2 controles Hiperlink: hlkPrimera apuntando a
[Link] y hlkSegunda apuntando a [Link].
Finalmente, para probar la página dar clic derecho sobre la página
[Link] en la ventana del explorador de soluciones y del menú
contextual seleccionar “View in Browser”.
Luis Dueñas Pag 493
La Biblia de Visual Basic .NET
1.3. Usando Controles Web Intrínsecos
Los Controles Web Intrínsecos son controles web estándares que al
momento de convertirse en HTML cada uno tiene una equivalencia a un
solo control HTML, lo cual lo podemos representar en la siguiente tabla:
Control Web Intr. Control HTML generado
BulletList <ul><li>..</li></ul>
Button <input type=”submit” ../>
Checkbox <input type=”checkbox” ../>
DropDownList <select><option>..</option></select>
FileUpload <input type=”file” ../>
HiddenField <input type=”hidden” ../>
HiperLink <a href=”Pagina”>..</a>
Image <img src=”Archivo” ../>
Label <span ../>
ListBox <select size=”4”><option>..</option></select>
Literal Literal
Panel <div>..</div>
RadioButton <input type=”radio” ../>
Table <table><tr><td>..<td></tr></table>
TextBox <input type=”text” ../>
TextMode=SingleLine
TextBox <textarea rows=”filas” cols=”columnas” ../>
TextMode=MultiLine
TextBox <input type=”password” ../>
TextMode=Password
Nota: De la lista hay controles HTML que son compuestos como la lista de
viñetas <ul>, las listas <select> y las tablas <table> los cuales tienen mas
elementos pero que forman parte del elemento padre como si fueran uno
solo.
A continuación un ejemplo de cómo usar controles web estándares
intrínsecos, para registrar el curso seleccionado por un alumno en un
archivo de texto. En este ejemplo usaremos los controles Label, TextBox,
DropDownList y Button. También veremos como validar usando Javascript.
Luis Dueñas Pag 494
La Biblia de Visual Basic .NET
Demo 72
Crear un nuevo sitio web vacío: del menú “File”, seleccionar “Add”,
“New Web Site”.
Seleccionar como lenguaje “Visual Basic” y como plantilla “ASP .NET
Empty Web Site”.
Seleccionar como ubicación del sitio web “HTTP” y escribir como
nombre: [Link]
Agregar una nueva página: del menú “Website”, seleccionar “Add New
Item”, luego “Web Form” y llamarle “[Link]”.
Ubicarse dentro del div de la nueva página e insertar una tabla de 5
filas por 2 columnas.
Diseñar la página dentro de las celdas de la tabla como sigue:
Objeto Propiedad Valor
Literal1 Text Ficha del Alumno
fila 1, celdas 1 y Size 6
2 combinadas Td Align Center
Literal 2 Text Ingresa el Nombre
fila 2, celda 1 Td width 20%
TextBox1 ID txtNombre
fila 2, celda 2 Width 300px
Td width 80%
Literal 3 Text Selecciona el Curso
fila 3, celda 1 Td width 20%
DropDownList ID ddlCurso
fila 3, celda2 Td width 80%
Literal 4 Text Seleccione el Turno
fila 4, celda 1 Td width 20%
RadioButtonList ID rblTurno
fila 4, celda 2 RepeatDirection Horizontal
Td width 80%
Button1 ID btnRegistrar
fila 5, celdas 1 y Text Registrar
2 combinadas OnClientClick return(ValidarDatosAlumno());
Luis Dueñas Pag 495
La Biblia de Visual Basic .NET
El diseño de la página debe quedar similar al gráfico 5.6:
Gráfico 5.6: Diseño de la Página Ficha del Alumno
Cambiar de la vista “Design” a la vista “Source” y escribir dentro de la
sección “Head” el siguiente código para validar el ingreso de datos:
<script language="javascript" type="text/javascript">
function ValidarTexto(Text, Mensaje) {
var Texto = [Link](Text);
if (Texto != null) {
if ([Link](/^\s+|\s+$/g, "").length == 0) {
alert('Ingrese ' + Mensaje);
[Link]();
return false;
}
}
return true;
}
function ValidarCombo(Comb, Mensaje) {
var Combo = [Link](Comb);
if (Combo != null) {
if (([Link] == ' ') || ([Link] == '') ||
([Link] == '0')) {
alert('Selecciona ' + Mensaje);
[Link]();
return false;
}
}
return true;
}
function ValidarRadioButton2Opciones(rbl, mensaje) {
var rbl1 = [Link](rbl + "_0");
Luis Dueñas Pag 496
La Biblia de Visual Basic .NET
var rbl2 = [Link](rbl + "_1");
if ([Link] == false && [Link] == false) {
alert("Selecciona " + mensaje);
return false;
}
return true;
}
function ValidarDatosAlumno() {
if (ValidarTexto("txtNombre", "Nombre del Alumno") == false)
return false;
if (ValidarCombo("ddlCurso", "Curso a llevar") == false) return false;
if (ValidarRadioButton2Opciones("rblTurno", "Turno a estudiar") ==
false) return false;
return true;
}
Nota: Se ha creado 4 funciones de Javascript, 3 son genéricas y una
específica, las genéricas nos permiten validar la primera cualquier texto
obligatorio, la segunda que se seleccione una opción de un combo y la
tercera una opción de un RadioButtonList de 2 opciones. La cuarta función
usa las 3 funciones para validar y pasa solo los controles y el mensaje.
Escribir el siguiente código en la página:
Imports [Link]
Partial Class FichaAlumno
Inherits [Link]
Protected Sub Page_Load(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
If Not [Link] Then
[Link](New ListItem("Seleccione", ""))
[Link](New ListItem("Windows", "01"))
[Link](New ListItem("ASP NET", "02"))
[Link](New ListItem("WPF", "03"))
[Link](New ListItem("WCF", "04"))
[Link](New ListItem("WWF", "05"))
[Link](New ListItem("Mañana", "M"))
[Link](New ListItem("Tarde", "T"))
Luis Dueñas Pag 497
La Biblia de Visual Basic .NET
End If
End Sub
Protected Sub btnRegistrar_Click(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
Dim Archivo As String = [Link]("[Link]")
Using fs As New FileStream(Archivo, [Link], _
[Link], [Link])
Using sw As New StreamWriter(fs)
[Link]("{0},{1},{2}", [Link], _
[Link], [Link])
End Using
End Using
[Link]([Link], "Mensaje", _
"alert('El alumno ha sido registrado');", True)
End Sub
End Class
Importante: En el código anterior se usa [Link] para devolver la
ruta donde se esta ejecutando la página actual, es decir la ruta del
directorio Demo72 (C:\inetpub\wwwroot\Demos\Demo72) ya que si no se
especifica la ruta, al trabajar con archivos en ASP .NET, por defecto se lee
o se escribe donde esta corriendo el proceso de IIS que es “[Link]”
ubicado en el directorio “C:\Windows\System32\inetsrv”.
Nota: Además para leer o escibir un archivo es necesario dar permiso en el
Servidor Web al usuario respectivo, en nuestro caso como la seguridad del
sitio es por defecto anónima se usa el usuario invitado de Internet:
IIS_IUSRS. Este debe tener permisos para escribir archivo de lo contrario
se generará una excepción.
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Nota: La primera vez que se ejecuta una aplicación se msotrará un
mensaje indicando que se hará cambios en el archivo [Link] para
depueración, seleccionar el botón “OK”.
Luis Dueñas Pag 498
La Biblia de Visual Basic .NET
Gráfico 5.7: Ejecución de la Página Ficha del Alumno
No ingrese ningún dato y de clic al botón registrar y verá como la
aplicación le ira pidiendo ingresar cada dato ya que todos son
obligatorios.
Importante: La validación se esta haciendo en el cliente usando
Javascript y asi evitamos viajes innecesarios al servidor para hacer
validaciones.
Ingrese todos los datos y clic al botón “Registrar”, ocurrirá una
excepción con el siguiente mensaje de error: “Access to the path
'C:\inetpub\wwwroot\Demos\Demo72\[Link]' is denied.”
Ingrese al Explorador de Windows hasta la carpeta Demo 72 para dar
permisos de escritura al usuario invitado de Internet.
Clic derecho sobre la carpeta y del menú contextual seleccionar
“Properties”.
Aparecerá una ventana similar a la mostrada en la figura 5.8.
Luis Dueñas Pag 499
La Biblia de Visual Basic .NET
Gráfico 5.8: Ventana de Propiedades de una Carpeta
Seleccionar la ficha “Security” y clic en el botón “Edit”.
Aparecerá una ventana similar a la mostrada en la figura 5.9
Luis Dueñas Pag 500
La Biblia de Visual Basic .NET
Gráfico 5.9: Ventana de Permisos de una Carpeta
Seleccionar el usuario “IIS_IUSRS” y marcar la casilla “Full Control”.
Clic en el botón “OK” y nuevamente intentar registrar alumnos.
Finalmente, verifique que exista el archivo [Link] en el directorio
Demo72.
Luis Dueñas Pag 501
La Biblia de Visual Basic .NET
1.4. Usando Controles Web de Imágenes
En ASP NET existen 3 controles Web de imágenes que son el Image, el
ImageButton y el ImageMap. El primero de ellos el control Image solo
muestra una imagen en el cliente, el segundo se usa para mostrar una
imagen y programar una acción el servidor en algún evento como Click y el
tercero de ellos el ImageMap crea un Mapa (control HTML Map) que define
regiones (elemento HTML Area) con diferentes imágenes a mostrar.
El control Image tiene varias propiedades pero la más importante es
ImageUrl que indica la ruta de la imagen que se va a mostrar, esta puede
configurarse en tiempo de diseño o también en tiempo de ejecución en el
caso de crearse el gráfico dinámicamente.
A continuación un ejemplo que crea dinámicamente una imagen para
comprobar si el que ingresa a la página es una persona o una aplicación
(CAPTCHA: Completely Automated Public Turing test to tell Computers and
Humans Apart), para lo cual después de crearse el gráfico con 4 caracteres
al azar se pide ingresar y se valida mediante Javascript si lo ingresado es
igual a lo generado por la aplicación.
Demo 73
Crear un nuevo sitio web vacío: del menú “File”, seleccionar “Add”,
“New Web Site”.
Seleccionar como lenguaje “Visual Basic” y como plantilla “ASP .NET
Empty Web Site”.
Seleccionar como ubicación del sitio web “HTTP” y escribir como
nombre: [Link]
Agregar una nueva página: del menú “Website”, seleccionar “Add New
Item”, luego “Web Form” y llamarle “[Link]”.
Ubicarse dentro del div de la nueva página e insertar una tabla de 5
filas por 1 columna.
Ingresar a la vista “Source” y modificar la tabla como sigue:
Luis Dueñas Pag 502
La Biblia de Visual Basic .NET
<table style="width:100%;text-align:center">
Cambiar a la vista “Design” y diseñar la página dentro de las celdas de
la tabla como sigue:
Objeto Propiedad Valor
Literal1 Text Seguridad mediante CAPTCHA
fila 1, celda 1 Size 6
Image1 Name imgCaptcha
fila 2, celda 1 Height 80px
Width 200px
Literal2 Text Ingresa el código generado
fila 3, celda1 arriba:
Input Text Id txtClaveUsuario
fila 3, celda1 Size 10
Button1 ID btnValidar
fila 4, celda 1 Text Validar
OnClientClick return(ValidarClave());
HiperLink1 ID hlkVerFoto
fila 5, celda 1 NavigateUrl ~/[Link]
Text Ver Foto en Las Vegas
HiddenField1 ID hdfClaveOriginal
fila 5, celda 1
El diseño de la página debe quedar similar al gráfico 5.10:
Gráfico 5.10: Diseño de la Página Seguridad con CAPTCHA
Cambiar de la vista “Design” a la vista “Source” y escribir dentro de la
sección “Head” el siguiente código para validar el ingreso de datos:
Luis Dueñas Pag 503
La Biblia de Visual Basic .NET
<script language="javascript" type="text/javascript">
function ValidarClave() {
var txtClaveUsuario = [Link]("txtClaveUsuario");
var claveOriginal = [Link]("hdfClaveOriginal").value;
if ([Link] != claveOriginal) {
alert("Clave incorrecta");
[Link]();
return false;
}
return true;
}
</script>
Escribir el siguiente código en la página:
Imports [Link]
Imports [Link].Drawing2D
Partial Class Seguridad
Inherits [Link]
Private Function GenerarCaracterAzar() As Char
Dim oAzar As New Random
[Link](20)
Dim N As Integer = [Link](26) + 65
Return (Chr(N))
End Function
Private Sub CrearGrafico()
Dim rec As New Rectangle(0, 0, 200, 80)
Dim deg As New LinearGradientBrush(rec, [Link], _
[Link], [Link])
Dim bmp As New Bitmap(200, 80)
Dim grafico As Graphics = [Link](bmp)
[Link](deg, rec)
Dim clave As String = ""
For I = 1 To 4
clave += GenerarCaracterAzar()
Next
Dim archivoImg As String = [Link] _
([Link]("{0}.jpg", clave))
Luis Dueñas Pag 504
La Biblia de Visual Basic .NET
[Link] = clave
[Link](clave, New Font("Arial", 40), _
[Link], 10, 10)
Dim oAzar As New Random
Dim X1, Y1, X2, Y2 As Integer
Dim R, G, B As Integer
Dim X As Color
Dim Lapiz As Pen
For I = 1 To 10
R = [Link](255)
G = [Link](255)
B = [Link](255)
X = [Link](R, G, B)
Lapiz = New Pen(New SolidBrush(X), 2)
X1 = [Link](200)
Y1 = [Link](80)
X2 = [Link](200)
Y2 = [Link](80)
[Link](Lapiz, X1, Y1, X2, Y2)
Next
[Link](archivoImg)
[Link] = [Link] _
("[Link] clave)
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As
[Link]) Handles [Link]
If Not [Link] Then
CrearGrafico()
End If
End Sub
Protected Sub btnValidar_Click(ByVal sender As Object, ByVal e As
[Link]) Handles [Link]
[Link] = True
End Sub
End Class
Importante: Para generar un número al azar se usa la clase Random,
pero si se llama consecutivamente al método Next este siempre devolvería
Luis Dueñas Pag 505
La Biblia de Visual Basic .NET
el mismo número, para evitar esto se debe hacer una pausa de 20
milisegundos, en este caso usando el método Sleep de la clase Thread.
Nota: Antes de ejecutar la aplicación tiene que dar permisos para escribir
el archivo con el Captcha generado al usuario IIS_IUSRS.
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 5.11: Ejecución de la Página Seguridad CAPTCHA sin Link
Ingresar un código equivocado y se hará una validación en el cliente
mostrando un error.
Ingresar el código mostrado y se irá al servidor para habilitar el Link
similar a lo mostrado en la figura 5.12.
Luis Dueñas Pag 506
La Biblia de Visual Basic .NET
Gráfico 5.12: Ejecución de la Página Seguridad CAPTCHA con Link
Finalmente, clic al Link para ver la pagina con la foto.
Luis Dueñas Pag 507
La Biblia de Visual Basic .NET
1.5. Usando el Control FileUpload y Controles de Validación
En esta sección revisaremos 2 temas: el primero como subir un archivo
desde el cliente al servidor web usando el control Web FileUpload y el
segundo tema como validar datos en el cliente usando los controles Web
de Validación.
El control FileUpload es la forma más simple de subir un archivo desde la
página hacia el servidor Web, tiene propiedades para manejar el archivo
que ha sido enviado desde el cliente con el PostBack, tales como HasFile
que indica si se ha enviado un archivo, PostedFile que representa al archivo
enviado, FileBytes que devuelve un arreglo de bytes con su contenido,
FileContent que devuelve un objeto FileStream o FileName que obtiene el
nombre del archivo en el cliente.
Además el control FileUpload tiene el método SaveAs que permite guardar
el archivo en el disco del servidor web. Por defecto el tamaño máximo del
archivo a enviar es de 4MB y el límite es de 4GB, para aumentar el tamaño
del archivo configurar la propiedad maxRequestLength del elemento
httpRuntime en el archivo de configuración [Link]. Para obtener más
información sobre el control FileUpload ver la referencia 31 al final del libro.
Antes de enviar datos al servidor es necesario validar si los datos fueron
ingresados por el usuario, si concuerdan con el tipo a recibir y si son
válidos, para esto generalmente usamos código en Javascript, pero
también podemos usar los controles de Validación de ASP .NET entre los
cuales tenemos:
RequiredFieldValidator: Se usa para validar que el ingreso de un campo
sea obligatorio.
CompareValidator: Valida los datos ingresados por el usuario con
respecto a una constante, el valor de otro control o si es de un tipo de
dato especifico, por ejemplo una fecha, un número entero, etc.
Rangevalidator: Comprueba que el valor de un control se encuentre en
un intervalo dado por las propiedades MinimunValue y MaximunValue.
Luis Dueñas Pag 508
La Biblia de Visual Basic .NET
RegularExpressionValidator: Valida que el valor de un control cumpla
con un patrón o expresión regular, por ejemplo una dirección de correo
electrónico, una dirección URL, un DNI, un número telefónico, etc.
CustomValidator: Se usa para personalizar la lógica de validación y
puede ser en el lado del cliente usando la propiedad ClientValidation
Function o en el servidor programando el evento ServerValidate.
Todos los controles de validación comparten propiedades comunes como:
ControlToValidate: Especifica el control que se va a validar.
Display: Indica la forma como se presentan los mensajes, que puede
ser estática o dinámica (sin dejar espacios).
ErrorMessage: Especifica el mensaje que aparecerá en el control de
resumen de validación cuando ocurre un error.
Text: Indica el texto que se muestra en el propio control de validación
cuando ocurre un error.
Finalmente, para mostrar el resumen de todos los errores originados por
los controles de validación esta el control “ValidationSummary” que tiene
propiedades como:
DisplayMode: Especifica el tipo de mensaje, puede ser con viñetas, lista
o simple texto.
ShowMessageBox: Si está en true se muestran los errores en un cuadro
de mensaje (alert).
ShowSummary: Si está en true (por defecto) se muestran los errores en
la página.
Para obtener más información sobre los controles de validación de ASP
.NET puede ver la referencia 32 al final del libro.
A continuación un ejemplo sobre una Bolsa de Trabajo que permite a los
postulantes registrar su nombre y fecha de nacimiento en un archivo de
texto y enviar un archivo con su curriculum y otro con su foto los cuales se
guardan en el servidor, previa validación usando controles de ASP .NET,
Luis Dueñas Pag 509
La Biblia de Visual Basic .NET
también podremos visualizar en una tabla todos los datos de los
postulantes registrados.
Demo 74
Crear un nuevo sitio web vacío: del menú “File”, seleccionar “Add”,
“New Web Site”.
Seleccionar como lenguaje “Visual Basic” y como plantilla “ASP .NET
Empty Web Site”.
Seleccionar como ubicación del sitio web “HTTP” y escribir como
nombre: [Link]
Agregar una nueva página: del menú “Website”, seleccionar “Add New
Item”, luego “Web Form” y llamarle “[Link]”.
Ubicarse dentro del div de la nueva página e insertar una tabla de 4
filas por 1 columna.
Diseñar la página Menú dentro de las celdas de la tabla como sigue:
Objeto Propiedad Valor
Literal1 Text Bolsa de Trabajo
fila 1, celda 1 Size 6
Literal2 Text Seleccione una opción
fila 2, celda1
HiperLink1 ID hlkRegistro
fila 3, celda1 NavigateUrl [Link]
Text Registro del Postulante
HiperLink12 ID hlkLista
fila 4, celda 1 NavigateUrl [Link]
Text Lista de Postulantes
El diseño de la página Menú debe quedar similar al gráfico 5.13:
Luis Dueñas Pag 510
La Biblia de Visual Basic .NET
Gráfico 5.13: Diseño de la Página Menú
Agregar otra página: del menú “Website”, seleccionar “Add New Item”,
luego “Web Form” y llamarle “[Link]”.
Ubicarse dentro del div de la nueva página e insertar una tabla de 8
filas por 2 columnas.
Diseñar la página Registro dentro de las celdas de la tabla como sigue:
Objeto Propiedad Valor
Literal1 Text Bolsa de Trabajo
fila 1, celdas 1 y 2 Size 6
combinadas
Literal2 Text Nombre
fila 2, celda1 Td Width 20%
TextBox1 ID txtNombre
fila 2, celda2 Width 200px
Td Width 80%
RequiredField ID rfvNombre
Validator1 ControlToValidate txtNombre
fila 2, celda 2 ErrorMessage 1 Ingresa el Nombre
Text 1
Literal3 Text Fecha de Nacimiento
fila 3, celda1 Td Width 20%
TextBox2 ID txtFechaNac
fila 3, celda2 Width 100px
Td Width 80%
RequiredField ID rfvFechaNac
Validator2 ControlToValidate txtFechaNac
fila 3, celda 2 Display Dynamic
ErrorMessage 2 Ingresa la Fecha de Nac.
Text 2
Compare Validator1 ID cvFechaNac
fila 3, celda 2 ControlToValidate txtFechaNac
Display Dynamic
ErrorMessage 3 Fecha inválida
Luis Dueñas Pag 511
La Biblia de Visual Basic .NET
Text 3
Operator DataTypeCheck
Type DateTime
Literal4 Text Archivo CV
fila 4, celda1 Td Width 20%
FileUpload1 ID fupCV
fila 4, celda2 Td Width 80%
RequiredField ID rfvCV
Validator3 ControlToValidate fupCV
fila 4, celda 2 ErrorMessage 4 Seleccione el CV
Text 4
Literal5 Text Archivo Foto
fila 5, celda1 Td Width 20%
FileUpload2 ID fupFoto
fila 5, celda2 Td Width 80%
RequiredField ID rfvFoto
Validator4 ControlToValidate fupFoto
fila 5, celda 2 ErrorMessage 5 Seleccione la Foto
Text 5
Button1 ID btnRegistrar
fila 6, celdas 1 y 2 Text Registrar
combinadas Td align center
HiperLink1 ID hlkRegresar
fila 7, celdas 1 y 2 NavigateUrl [Link]
combinadas Text Regresar
Td align Center
ValidationSummary1 ID vsrRegistro
fila 8, celdas 1 y 2 DisplayMode List
combinadas ShowMessageBox True
ShowSummary False
El diseño de la página Registro debe quedar similar al gráfico 5.14:
Luis Dueñas Pag 512
La Biblia de Visual Basic .NET
Gráfico 5.14: Diseño de la Página Registro
Escribir el siguiente código en la página:
Imports [Link]
Partial Class Registrar
Inherits [Link]
Protected Sub btnRegistrar_Click(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
Dim ArchivoTxt As String = _
[Link]("[Link]")
Using sw As New StreamWriter(ArchivoTxt, True)
[Link]("{0},{1}", [Link], [Link])
End Using
Dim ArchivoCV As String = _
[Link]([Link]("CVs/{0}{1}", _
[Link], [Link]([Link])))
[Link](ArchivoCV)
Dim ArchivoFoto As String = _
[Link]([Link]("Fotos/{0}{1}", _
[Link], [Link]([Link])))
[Link](ArchivoFoto)
End Sub
End Class
Luis Dueñas Pag 513
La Biblia de Visual Basic .NET
Nota: Antes de ejecutar la aplicación debe crear 2 carpetas para
almacenar los archivos: CVs y Fotos y también tiene que dar permisos para
escribir en dichas carpetas los archivos al usuario IIS_IUSRS.
Agregar otra página: del menú “Website”, seleccionar “Add New Item”,
luego “Web Form” y llamarle “[Link]”.
Ubicarse dentro del div de la nueva página e insertar una tabla de 3
filas por 1 columna.
Diseñar la página Lista dentro de las celdas de la tabla como sigue:
Objeto Propiedad Valor
Literal1 Text Lista de Postulantes
fila 1, celda 1 Size 6
Literal1 (Control) ID litPostulante
fila 2, celda1
HiperLink1 ID hlkRegresar
fila 3, celda 1 NavigateUrl [Link]
Text Regresar
El diseño de la página Lista debe quedar similar al gráfico 5.15:
Gráfico 5.15: Diseño de la Página Lista
Escribir el siguiente código en la página:
Imports [Link]
Partial Class Listar
Inherits [Link]
Protected Sub Page_Load(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
If Not [Link] Then
Luis Dueñas Pag 514
La Biblia de Visual Basic .NET
Dim sb As New StringBuilder
[Link]("<table>")
[Link]("<tr bgcolor='blue'>")
[Link]("<td style='width:200px'><font color='white'>Nombre
del Postulante</font></td>")
[Link]("<td style='width:100px'><font color='white'>Fecha
Nac</font></td>")
[Link]("<td style='width:200px'><font color='white'>CV
</font></td>")
[Link]("<td style='width:200px'><font color='white'>Foto
</font></td>")
[Link]("</tr>")
Dim ArchivoTxt As String = [Link]("[Link]")
Dim RutaCV As String = [Link]("CVs/")
Dim ArchivoCV As String
Dim RutaFoto As String = [Link]("Fotos/")
Dim ArchivoFoto As String
Dim Postulante() As String
If [Link](ArchivoTxt) Then
Using sr As New StreamReader(ArchivoTxt)
Do While Not [Link]
Postulante = [Link](",")
ArchivoCV = [Link]("{0}{1}.docx", RutaCV,
Postulante(0))
ArchivoFoto = [Link]("{0}{1}.jpg", RutaFoto,
Postulante(0))
[Link]("<tr>")
[Link]("<td style='width:200px'>")
[Link](Postulante(0))
[Link]("</td>")
[Link]("<td style='width:100px'>")
[Link](Postulante(1))
[Link]("</td>")
[Link]("<td style='width:200px'>")
If [Link](ArchivoCV) Then
[Link]("<a href='[Link]
/CVs/")
[Link]([Link]("{0}.docx", Postulante))
[Link]("'>")
[Link]([Link]("{0}.docx", Postulante))
Luis Dueñas Pag 515
La Biblia de Visual Basic .NET
[Link]("</a>")
End If
[Link]("</td>")
[Link]("<td style='width:200px'>")
If [Link](ArchivoFoto) Then
[Link]("<a href='[Link]
/Fotos/")
[Link]([Link]("{0}.jpg", Postulante))
[Link]("'>")
[Link]([Link]("{0}.jpg", Postulante))
[Link]("</a>")
End If
[Link]("</td>")
[Link]("</tr>")
Loop
End Using
End If
[Link]("</table>")
[Link] = [Link]
End If
End Sub
End Class
Configurar la página Menu como pagina de inicio, dando clic derecho
sobre esta y del menú contextual seleccionar “Set as Start Page”.
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 516
La Biblia de Visual Basic .NET
Gráfico 5.16: Ejecución de la Página Menú
Seleccionar la opción Registro del Postulante.
Gráfico 5.17: Ejecución de la Página Registro
Clic al botón Registrar sin ingresar ningún dato y se presentará un
cuadro de mensaje con los errores de ingreso.
Ingresar el nombre del postulante y su fecha de nacimiento.
Seleccionar un archivo docx de Word para el CV.
Luis Dueñas Pag 517
La Biblia de Visual Basic .NET
Seleccionar un archivo Jpg para la foto.
Clic al botón Registrar y se creará el archivo [Link] en el
servidor y también se grabará 2 archivos en las carpetas CVs y Fotos
con el nombre del postulante.
Agregar todos los postulantes que desee y después clic al enlace de
Regresar para ir a la página principal.
Seleccionar la opción Lista de Postulantes y verá todos los postulantes
ingresados.
Gráfico 5.18: Ejecución de la Página Lista
Finalmente, podrá visualizar el documento de Word o ver la foto del
postulante en una página dando clic al enlace dentro de la tabla.
Luis Dueñas Pag 518
La Biblia de Visual Basic .NET
2. Mejorando el Diseño y la Navegabilidad del Sitio Web
Para mejorar el diseño del Sitio Web podemos usar las Hojas de Estilo en
Cascada para aplicar un formato común tanto a controles HTML como
controles Web y para mejorar la navegabilidad podemos usar Paginas
Principales (Master Pages) y Paginas de Contenido (Content Page) usando
también en dichas páginas los controles de navegación como el Menú,
TreeView y SiteMapPath.
Además si deseamos incorporar Fichas (Tabs) dentro de nuestra aplicación
la forma mas fácil de logralo es usar los controles de Vistas: MultiView y
Views los cuales permite crear varias paginas o vistas en una sola página.
2.1. Creando y usando Hojas de Estilo en Cascada
Las Hojas de Estilos en Cascada (Cascading Style Sheets) o CSS es un
lenguaje usado para definir la presentación de una pagina HTML o un
documento XML.
Mediante las hojas de estilo podemos simplificar el diseño de las páginas
dando un estilo común de acuerdo al elemento, por ejemplo para los
titulos, subtitulos, etiquetas, botones, fichas, números, textos, controles de
solo lectura, etc.
Las ventajas de usar CSS son que una página puede tener varias hojas de
estilo aplicándole el elemento: <link href="[Link]" rel="stylesheet"
type="text/css" />, luego usando el atributo class para los controles HTML y
la propiedad cssClass para los controles Web.
En Visual Web Developer existe una barra de herramientas denominada
“Style Sheet” que permite crear y modificar estilos en un archivo CSS
usando diálogos y también escribiendo en el editor de código.
A continuación veremos un ejemplo de cómo crear un archivo de hoja de
estilos y aplicárselo a la página Ficha del Alumno creada en el Demo 72,
esta hoja de estilos tiene 4 clases de estilos: Titulo, Subtitulo, Botón y un
color de Fondo para la página.
Luis Dueñas Pag 519
La Biblia de Visual Basic .NET
Demo 75
Crear un nuevo sitio web vacío: del menú “File”, seleccionar “Add”,
“New Web Site”.
Seleccionar como lenguaje “Visual Basic” y como plantilla “ASP .NET
Empty Web Site”.
Seleccionar como ubicación del sitio web “HTTP” y escribir como
nombre: [Link]
Agregar una página existente: del menú “Website”, seleccionar “Add
Existing Item”.
Ingresar a la carpeta Demo72 y abrir el archivo “[Link]”.
Agregar un archivo CSS: del menú “Website”, seleccionar “Add New
Item”, luego “Style Sheet” y escribir como nombre “[Link]”.
El archivo creado viene con un estilo para el cuerpo de la página
llamado Body.
Mostrar la Barra de herramientas de estilos: clic derecho a cualquier
barra de herramientas y seleccionar “Style Sheet”.
Gráfico 5.19: Barra de Herramientas de Hojas de Estilo
Clic al segundo botón “Build Style” de la barra para modificar el estilo
del Body y aparecerá un diálogo similar al de la figura 5.20.
Luis Dueñas Pag 520
La Biblia de Visual Basic .NET
Gráfico 5.20: Diálogo de Modificar Estilo
Seleccionar la categoria “Background” y cambiar el color de fondo a
“aqua” y clic en el botón “OK”.
Ubicarse debajo del Body y clic al primer botón “Add Style Rule” de la
barra de herramientas de estilos.
Luis Dueñas Pag 521
La Biblia de Visual Basic .NET
Gráfico 5.21: Diálogo de Agregar Regla de Estilo
Seleccionar la opción “Class name” y escribir como nombre “Titulo” y
clic al botón “>” para pasarlo a la lista de reglas de estilos y botón “OK”
Se creará un nuevo estilo llamado Titulo ubicarse dentro de las llaves y
clic al segundo botón “Build Style”.
Se mostrará el dialogo visto en la figura 5.20 para modificar el estilo.
Seleccionar en la categoría “Font” la fuente “Arial Black”, en tamaño “x-
large” y en color “White”.
Seleccionar en la categoría “Background” el color de fondo “Black”.
Complete los otros estilos para que quede como el siguiente código:
body
{
background-color: aqua;
}
.Titulo
{
background-color: black;
color: white;
font-size: x-large;
font-family: 'Arial Black';
}
Luis Dueñas Pag 522
La Biblia de Visual Basic .NET
.Subtitulo
{
background-color: white;
color: blue;
font-size: large;
font-family: Arial, Helvetica, sans-serif;
}
.Boton
{
background-color: blue;
color: white;
}
Grabe el proyecto para que se guarde el archivo con los estilos creados.
Cierre la ventana de hoja de estilo y abra la pagina ficha del alumno.
Arrastre el archivo CSS encima de la página y observe que cambia de
fondo a “aqua”.
Ingrese a la vista “Source” para verificar que se ha agregado al código
HTML: <link href="[Link]" rel="stylesheet" type="text/css" />.
Regrese a la vista “Design” seleccione la primera celda y en la
propiedad “Class” de la celda (Td) elija “Titulo”.
Seleccione la celda del literal con el nombre y configure la propiedad
“Class” al estilo “Subtitulo”.
También haga lo mismo para las celdas con los literales del curso y
turno y configure su propiedad “Class” en “Subtitulo”.
Seleccione el botón Registrar y configure su propiedad “CssClass” en
“Boton”.
El diseño de la página debe quedar como se muestra en la figura 5.22
Luis Dueñas Pag 523
La Biblia de Visual Basic .NET
Gráfico 5.22: Diseño de la Página Ficha del Alumno
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 5.23: Ejecución de la Página Ficha del Alumno
Nota: No olvidarse que la aplicación crea un archivo de texto, por tanto
hay que dar permiso al usuario IIS_IUSRS.
Luis Dueñas Pag 524
La Biblia de Visual Basic .NET
2.2. Paginas Principales y Controles de Navegación
Las Paginas Principales (Master Page) se usan para crear un mismo diseño
o plantilla para varias páginas conocidas como Paginas de Contenido
(Content Pages), las cuales se combinan con la pagina principal en tiempo
de ejecución para formar una sola página.
Las paginas principales de ASP .NET son archivos de extensión .master e
inician con la directiva de procesamiento @Master, a diferencia de las
páginas de formularios web ASP .NET que son archivos de extensión .aspx
y contienen la directiva @Page.
Una página principal debe tener como mínimo un control ContentPlace
Holder que indica la sección donde irá la pagina de contenido, por su parte
la página de contenido debe tener el atributo MasterPageFile que indica
cual es la pagina principal con la cual se unirá, además tiene un control
Content para los Scripts y otro para el contenido de la página.
Las páginas principales permiten ahorrar la escritura de código
centralizando en un solo archivo las partes cimunes de todas las paginas de
contenido, por ejemplo la misma cabecera, el mismo menú, el mismo pie,
etc. Para obtener más información sobre Páginas Principales en ASP .NET
ver la referencia 33 al final del libro.
Por su parte los Controles de Navegación permiten acceder de forma
directa a las páginas del sitio web, entre ellos tenemos:
SiteMapPath: Permite mostrar la ubicación de la pagina actual dentro
de un mapa de sitio definido en el archivo [Link], además
permite navegar directamente a cualquier página del sitio.
Menú: Este muestra un conjunto de opciones o elementos a partir de
un origen de datos que puede ser un objeto SiteMapDataSource el cual
se puede enlazar a un archivo XML o un Mapa de Sitio definido en el
archivo [Link], también lo podemos llenar programáticamente
obteniendo los elementos desde una tabla de base de datos, etc.
TreeView: Visualiza información jerárquica y también puede estar
enlazado a un SiteMapDataSource lo cual mostraría las paginas del sitio
Luis Dueñas Pag 525
La Biblia de Visual Basic .NET
web en forma jerárquica o también puede llenarse por código usando la
colección de nodos (Nodes).
A continuación un ejemplo que nos demuestra como crear una página
principal y varias páginas de contenido, así como también aprenderemos a
usar los controles de navegación para navegar por las páginas del sitio web
de un instituto que tiene diversas unidades de negocio que ofrecen
diversos programas.
Demo 76
Crear un nuevo sitio web vacío: del menú “File”, seleccionar “Add”,
“New Web Site”.
Seleccionar como lenguaje “Visual Basic” y como plantilla “ASP .NET
Empty Web Site”.
Seleccionar como ubicación del sitio web “HTTP” y escribir como
nombre: [Link]
Agregar el archivo de hoja de estilo creado en el demo anterior: del
menú “Website”, seleccionar “Add Existing Item”.
Ingresar al Demo 75 y abrir el archivo “[Link]”.
Agregar una nueva página principal: del menú “Website”, seleccionar
“Add New Item”.
Seleccionar la opción “Master Page” e ingresar como nombre:
“[Link]”.
Arrastrar el archivo css hacia la pagina principal para aplicar el estilo.
Cortar el control ContentPlaceHolder y estando dentro del div agregar
una tabla de 4 filas x 2 columnas.
Diseñar la página principal dentro de las celdas de la tabla como sigue:
Objeto Propiedad Valor
Literal1 Text Instituto Peruano de TICs
fila 1, celdas 1 y 2 CssClass Titulo
Luis Dueñas Pag 526
La Biblia de Visual Basic .NET
combinadas
SiteMapPath1 ID smpPrincipal
fila 2, celdas 1 y 2 Auto Format Colorful
combinadas
Menu1 ID mnuPrincipal
fila 3, celdas 1 y 2 Auto Format Colorful
combinadas Orientation Horizontal
TreeView1 ID tvwPrincipal
fila 4, celda 1 Auto Format Inbox
Td width 20%
ContentPlaceHolder1 ID ContentPlaceHolder1
Fila 4, celda 2 Td width 80%
El diseño de la página Lista debe quedar similar al gráfico 5.23:
Gráfico 5.23: Diseño de la Página Principal
Agregar un archivo de mapa de sitio: del menú “Website”, seleccionar
“Add New Item”, luego seleccionar “Site Map”.
Modificar el archivo “[Link]” para que quede de la siguiente
forma:
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="[Link] >
<siteMapNode url="[Link]" title="Sitio Web Instituto Peruano de
TICs" description="Pagina por Defecto">
<siteMapNode url="[Link]" title="Carreras" description="Carreras
del Instituto">
<siteMapNode url="[Link]" title="Computación"
description="Carrera de Computacion"/>
<siteMapNode url="[Link]" title="Marketing"
Luis Dueñas Pag 527
La Biblia de Visual Basic .NET
description="Carrera de Marketing"/>
<siteMapNode url="Diseñ[Link]" title="Diseño" description="Carrera de
Diseño"/>
</siteMapNode>
<siteMapNode url="[Link]" title="ISILTECH"
description="Capacitación para Profesionales">
<siteMapNode url="[Link]" title="PECI" description="Especializacion
Desarrollo"/>
<siteMapNode url="[Link]" title="CISCO"
description="Especializacion en Redes"/>
</siteMapNode>
</siteMapNode>
</siteMap>
Cerrar la ventana del archivo de mapa de sitio.
Agregar una pagina de contenido: seleccionar la pagina principal y del
menú “Website”, “Add New Item”, “Web Form”, pero marcar la casilla
inferior “Select Master Page” y escribir como nombre “[Link]”,
luego seleccionar la página “[Link]”.
Ubicarse dentro del div de la página de contenido Default y esciribir el
literal: “Página principal del Instituto”, configurar la propiedad class a
“Subtitulo”.
Agregar una pagina de contenido llamada “[Link]” y escribir en el
div el literal: “Página de Carreras del Instituto”, luego configurar la
propiedad class a “Subtitulo”.
Agregar una pagina de contenido llamada “[Link]” y
escribir en el div el literal: “Página de la Carrera de Computación”,
luego configurar la propiedad class a “Subtitulo”.
Agregar una pagina de contenido llamada “[Link]” y escribir
en el div el literal: “Página de la Carrera de Marketing”, luego configurar
la propiedad class a “Subtitulo”.
Agregar una pagina de contenido llamada “Diseñ[Link]” y escribir en el
div el literal: “Página de la Carrera de Diseño”, luego configurar la
propiedad class a “Subtitulo”.
Luis Dueñas Pag 528
La Biblia de Visual Basic .NET
Agregar una pagina de contenido llamada “[Link]” y escribir en
el div el literal: “Página de ISILTECH”, luego configurar la propiedad
class a “Subtitulo”.
Agregar una pagina de contenido llamada “[Link]” y escribir en el
div el literal: “Página de los Programas PECI”, luego configurar la
propiedad class a “Subtitulo”.
Agregar una pagina de contenido llamada “[Link]” y escribir en el
div el literal: “Página del Programa de CISCO”, luego configurar la
propiedad class a “Subtitulo”.
Cerrar todas las ventanas abiertas y regresar a la página principal.
Seleccionar el menú, dar clic a la etiqueta inteligente (Smart Tag) y en
la opción “Choose Data Source” elegir “New Data Source”.
Se presentará un diálogo similar al mostrado en la figura 5.24.
Gráfico 5.24: Diálogo de Configuración del Orígen de Datos
Luis Dueñas Pag 529
La Biblia de Visual Basic .NET
Seleccionar la opción “Site Map” y asignar como nombre al objeto
“SiteMapDataSource” el de “smdsPrincipal”.
Nota: Observe como se ha configurado la propiedad DataSourceID del
control Menu en el objeto “smdsPrincipal”.
Seleccionar el TreeView y configurar la propiedad DataSourceID al
objeto “smdsPrincipal” creado.
Configurar la página “[Link]” como pagina de inicio, dando clic
derecho sobre esta y del menú contextual seleccionar “Set as Start
Page”.
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 5.25: Ejecución de la Página Principal
Navegar através del Menú o el TreeView y observar el control
SiteMapPath como muestra la ubicación donde nos encontramos,
además de poder ir a una cierta página dando clic al enlace mostrado.
Con esto hemos terminado el uso de páginas principales y controles de
navegación y como se habran dado cuenta no hay ninguna línea de
programación, pero sin embargo hemos obtenido los resultados esperados
Luis Dueñas Pag 530
La Biblia de Visual Basic .NET
que es hacer el acceso más fácil a los usuarios del sitio web con el mínimo
esfuerzo.
Luis Dueñas Pag 531
La Biblia de Visual Basic .NET
2.3. Usando Controles de Vistas MultiView y Views
Cuando la información de una pagina es demasiada se puede agrupar en
secciones para lo cual es muy común usar Fichas (Tabs) para ver la
información agrupada por categorías.
En ASP .NET podemos implementar esto de 2 formas: la primera es usando
una pagina principal con botones que simulen las fichas y al dar clic
mostrar la página de contenido, pero el problema es que tendríamos que
guardar el estado de cada página en algún lado como por ejemplo en
variables de sesión y la programación sería considerable.
La segunda alternativa para trabajar con fichas es usar los controles de
vistas MultiView y varios Views, en cada View va la sección que se desea
presentar como una página, sin embargo todas las secciones o “paginas”
se encuentran en una sola y por defecto se puede conservar el estado sin
necesidad de usar variables de sesión u otros objetos ni programar para
lograr este fín.
El control MultiView tiene una propiedad ActiViewIndex que inicia en 0 y
especifica el índice del control View que tiene la sección o “página” que
queremos mostrar.
Esta técnica para implementar fichas es muy interesante pero hay que
tener en cuenta que aunque solo se vea una sección en la página
internamente se esta guardando el estado de todas las secciones, por lo
que el tamaño de la página en el cliente podría ser excesivamente grande y
lo mejor es deshabilitar el estado de los controles que no van a usarse o
que ya se están cargando directamente de un origen de datos en línea.
En el siguiente ejemplo veremos una consulta de datos de 3 tablas
diferentes: Empleados, Categorías y Productos usando un MultiView y 3
Views donde al cargar cada uno se realiza una llamada a reglas de negocio
para obtener los datos, por tanto podemos configurar la propiedad
EnableViewState en falso para que no guarde estado y disminuya el código
HTML en el cliente ya que la consulta es en línea y no hay necesidad de
guardar el estado o valores de las 3 grillas.
Luis Dueñas Pag 532
La Biblia de Visual Basic .NET
Demo 77
Crear un nuevo sitio web vacío: del menú “File”, seleccionar “Add”,
“New Web Site”.
Seleccionar como lenguaje “Visual Basic” y como plantilla “ASP .NET
Empty Web Site”.
Seleccionar como ubicación del sitio web “HTTP” y escribir como
nombre: [Link]
Hacer una referencia a la librería [Link].
Nota: En Visual Web Developer al referenciar la principal librería esta copia
todas sus librerías dependientes, a diferencia de una aplicación Windows.
Agregar el archivo de hoja de estilo creado en el demo 75: del menú
“Website”, seleccionar “Add Existing Item”.
Ingresar al Demo 75 y abrir el archivo “[Link]”.
Agregar una nueva página: del menú “Website”, seleccionar “Add New
Item”, “Web Form” y escribir como nombre “[Link]”.
Ubicarse dentro del div de la nueva página e insertar una tabla de 3
filas por 1 columna.
Diseñar la página dentro de las celdas de la tabla como sigue:
Objeto Propiedad Valor
Literal1 Text Consultas de Datos
fila 1, celda 1 Class Titulo
Button1 ID btnEmpleado
fila 2, celda1 Text Empleados
Button2 ID btnCategoria
fila 2, celda 1 Text Categorías
Button3 ID btnProducto
fila 2, celda 1 Text Productos
MultiView1 ID mvConsulta
fila 3, celda 1
View1 ID vwEmpleado
(dentro del
Luis Dueñas Pag 533
La Biblia de Visual Basic .NET
MultiView)
Literal2 Text Lista de Empleados
(dentro del View1)
GridView1 ID gvEmpleado
(dentro del View1) EnableViewState False
Auto Format Colorful
View2 ID vwCategoria
(dentro del
MultiView)
Literal3 Text Lista de Categorías
(dentro del View2)
GridView2 ID gvCategoria
(dentro del View2) EnableViewState False
Auto Format Simple
View3 ID vProducto
(dentro del
MultiView)
Literal4 Text Lista de Productos
(dentro del View3)
GridView3 ID gvProducto
(dentro del View3) EnableViewState False
Auto Format Oceanica
El diseño de la página Consultas debe quedar similar al gráfico 5.26:
Luis Dueñas Pag 534
La Biblia de Visual Basic .NET
Gráfico 5.26: Diseño de la Página de Consultas
Escribir el siguiente código en la página:
Imports [Link]
Imports [Link]
Partial Class Consultas
Inherits [Link]
Protected Sub ListarEmpleados(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
Dim obrEmpleado As New brEmpleado
Dim lobeEmpleado As List(Of beEmpleado) = [Link]
[Link] = lobeEmpleado
[Link]()
End Sub
Protected Sub ListarCategorias(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
Dim obrCategoria As New brCategoria
Dim lobeCategoria As List(Of beCategoria) = [Link]
Luis Dueñas Pag 535
La Biblia de Visual Basic .NET
[Link] = lobeCategoria
[Link]()
End Sub
Protected Sub ListarProductos(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
Dim obrProducto As New brProducto
Dim lobeProducto As List(Of beProducto) = [Link]
[Link] = lobeProducto
[Link]()
End Sub
Protected Sub Page_Load(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
If Not [Link] Then
[Link] = 0
End If
End Sub
Protected Sub VerConsultaEmpleados(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
[Link] = 0
End Sub
Protected Sub VerConsultaCategorias(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
[Link] = 1
End Sub
Protected Sub VerConsultaProductos(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
[Link] = 2
End Sub
End Class
Nota: En el código anterior se ha programado en el evento Load de los
controles Views los cuales se disparan cada vez que se llama a la propiedad
ActiveViewIndex del control MultiView, en nuestro caso al dar clic a los
botones de la parte superior.
Luis Dueñas Pag 536
La Biblia de Visual Basic .NET
Modificar el archivo de configuración [Link] para agregar la clave
conNW en la sección appSettings, tal como se muestra:
<?xml version="1.0"?>
<configuration>
<[Link]>
<compilation debug="true" strict="false" explicit="true"
targetFramework="4.0"/>
</[Link]>
<appSettings>
<add key="conNW" value="uid=CursoNET; pwd=123456;
data source=DSOFT\DSOFT;initial catalog=Northwind"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 5.27: Ejecución de la Página de Consultas
Seleccione cada consulta de datos y vea el código fuente generado en
el cliente: clic derecho a la página y del menú contextual seleccionar
“View Source”.
Luis Dueñas Pag 537
La Biblia de Visual Basic .NET
Sobre todo observe el campo oculto: “__VIEWSTATE” que guarda el
estado de la página, el cual no tiene mucha data.
Pare la ejecución de la aplicación y cambie la propiedad
“EnableViewState” a “true” (valor por defecto) de los controles
GridView.
Ejecute nuevamente la aplicación y vea que el código fuente ha crecido
bastante debido a que siempre guarda el estado de las 3 grillas.
Luis Dueñas Pag 538
La Biblia de Visual Basic .NET
3. Usando el Control GridView
Al igual que en Windows Forms, en ASP .NET Web Forms el control mas
usado es el GridView, este permite mostrar columnas enlazadas a un
origen de datos mediante su propiedad DataSource, también permite
paginar configurando la propiedad AllowPaging u ordenar columnas
configurando la propiedad AllowSorting, editar una fila mediante la
propiedad EditIndex, mostrar una cabecera mediante la propiedad
ShowHeader o un pie de pagina mediante la propiedad ShowFooter, etc.
En cuanto a sus principales métodos tenemos el DataBind que ejecuta el
enlace de datos, el método SelectRow que permite seleccionar una fila por
su índice de fila, el método SetEditRow que permite ingresar al modo
edición por el índice de fila y el método SetPageIndex que permite
seleccionar una página por su índice de página.
Entre sus principales eventos tenemos los eventos PageIndexChanging y el
PageIndexChanged que ocurren mientras y después de cambiar el índice
de página, los eventos Sorting y Sorted que ocurren mientras y después
que se ordena una columna, los eventos SelectedIndexChanging y
SelectedIndexChanged que ocurren al cambiar el índice de fila seleccionada
También existen eventos que se disparan cuando trabajamos con botones
de comandos de editar como el RowEditing, o el comando actualizar que
dispara los eventos RowUpdating y RowUpdated, el comando de cancelar
que dispara el RowCancelEdit, el comando de eliminar que dispara los
eventos RowDeleting y RowDeleted.
Finalmente, se encuentran los ventos RowCreated y RowDataBound, el
primero se usa para crear dinámicamente controles antes de crearse cada
fila y el segundo se usa para dar formato a las filas y ocurre cada vez que
se muestra una fila.
En esta parte veremos como personalizar las columnas mostradas, como
paginar las filas, como ordenar columnas y finalmente como realizar un
mantenimiento dentro del propio control GridView. Para obtener más
información sobre el control GridView ver la referencia 34 al final del libro.
Luis Dueñas Pag 539
La Biblia de Visual Basic .NET
3.1. Personalizando Columnas en el GridView
Por defecto cuando se enlaza un control GridView a un origen de datos se
muestran todas las columnas del origen de datos ya que se crean en
tiempo de ejecución debido a que la propiedad AutoGenerateColumnms
esta en true.
Para personalizar las columnas del GridView se puede realizar programando
la propiedad AutoGenerateColumns en false y creando las columnas a verse
mediante código o mediante el diálogo de campos del control, para lo cual
se selecciona la etiqueta inteligente (SmartTag) asociada al control y se
elije “Edit Columns”, luego se deshabilita la casilla “Auto-generate fields” y
se vana gregando los “Boundfields” o columnas enlazadas a mostrarse.
En cada columna se configuran sus propiedades HeaderText que indica el
texto de la cabecera, DataField que indica el campo (si es una tabla) o
propiedad (si es un objeto) que se va a mostrar del origen de datos,
además de otras propiedades de formato.
A continuación un ejemplo que muestra como personalizar las columnas de
los productos para ver solo el código, nombre, precio unitario y stock,
alineando a la derecha los números y mostrando en formato moneda con 2
decimales el precio.
Demo 78
Crear un nuevo sitio web vacío: del menú “File”, seleccionar “Add”,
“New Web Site”.
Seleccionar como lenguaje “Visual Basic” y como plantilla “ASP .NET
Empty Web Site”.
Seleccionar como ubicación del sitio web “HTTP” y escribir como
nombre: [Link]
Hacer una referencia a la librería [Link].
Agregar el archivo de hoja de estilo creado en el demo 75: del menú
“Website”, seleccionar “Add Existing Item”.
Luis Dueñas Pag 540
La Biblia de Visual Basic .NET
Ingresar al Demo 75 y abrir el archivo “[Link]”.
Agregar una nueva página: del menú “Website”, seleccionar “Add New
Item”, “Web Form” y escribir como nombre “[Link]”.
Ubicarse dentro del div de la nueva página e insertar una tabla de 3
filas por 1 columna.
Diseñar la página dentro de las celdas de la tabla como sigue:
Objeto Propiedad Valor
Literal1 Text Personalizar Columnas en el
fila 1, celda 1 GridView
Class Titulo
Literal2 Text Lista de Productos
fila 2, celda1 Class Subtitulo
Button2 ID gvProducto
fila 3, celda 1 Auto Format Oceanica
Clic a la etiqueta inteligente ubicada al lado izquierdo superior de la
grilla y del menú contextual seleccionar “Edit Columns”.
Se mostrará un diálogo similar al de la figura 5.28:
Luis Dueñas Pag 541
La Biblia de Visual Basic .NET
Gráfico 5.28: Diálogo de configurar Campos del GridView
Desmarcar la casilla de verifcación “Auto-generate fields” de la parte
derecha inferior para no generar columnas en ejecución.
Agregar 4 columnas de tipo “BoundField” y cambiarlas como sigue:
Columna Propiedad Valor
BoundField1 HeaderText Código
DataField Codigo
ItemStyle
HorizontalAlign Right
Width 70px
BoundField2 HeaderText Descripción
DataField Nombre
ItemStyle
Width 300px
BoundField3 HeaderText Precio
DataField PrecioUnitario
DataFormatString {0:c2}
ItemStyle
HorizontalAlign Right
Luis Dueñas Pag 542
La Biblia de Visual Basic .NET
Width 100px
BoundField4 HeaderText Stock
DataField Stock
ItemStyle
HorizontalAlign Right
Width 70px
El diseño de la página Lista de Productos debe quedar similar al gráfico
5.29:
Gráfico 5.29: Diseño de la Página Lista de Productos
Escribir el siguiente código en la página:
Imports [Link]
Imports [Link]
Partial Class _Default
Inherits [Link]
Protected Sub Page_Load(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
If Not [Link] Then
Dim obrProducto As New brProducto
Dim lobeProducto As List(Of beProducto) = [Link]
[Link] = lobeProducto
[Link]()
End If
End Sub
End Class
Luis Dueñas Pag 543
La Biblia de Visual Basic .NET
Modificar el archivo de configuración [Link] para agregar la clave
conNW en la sección appSettings, tal como se muestra:
<?xml version="1.0"?>
<configuration>
<[Link]>
<compilation debug="true" strict="false" explicit="true"
targetFramework="4.0"/>
</[Link]>
<appSettings>
<add key="conNW" value="uid=CursoNET; pwd=123456;
data source=DSOFT\DSOFT;initial catalog=Northwind"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 5.30: Ejecución de la Página Lista de Productos
Luis Dueñas Pag 544
La Biblia de Visual Basic .NET
3.2. Paginando en el GridView
Cuando los registros son demasiados es mejor no presentarlos todos, para
esto se puede paginar o mostrar solo unos cuantos. En una aplicación web
en ASP .NET podemos tener 3 tipos de paginaciones:
Paginación el el Servidor de Datos: Si se trabaja con procedimientos
almacenados consistiría en devolver solo una cierta página o conjunto
de registros, la consulta estaría en línea pero lo malo sería que
estaríamos conectándonos constantemente al servidor para obtener los
datos.
Paginación en el Servidor Web: Consiste en obtener los datos una sola
vez del Servidor de Datos, desconectarse, guardarlos en memoria y
enviar al cliente solo la página deseada. Esto evitaría conexiones
constantes al servidor de datos aligerando su rendimiento pero lo malo
es que no estamos en línea sino trabajando desconectados.
Paginación en el Cliente Web: Consiste en obtener los datos del
servidor de datos, recogerlos en el servidor web y enviarlos al cliente
via Response y manejarlos en el cliente con Javascript, AJAX, JQuery,
etc. Esto evitaría viajes tanto al servidor web como el servidor de datos
pero aumentaría considerablemente el tamaño de la página en el
cliente y lo podría volver lento.
De las 3 alternativas presentadas la mejor por escalabilidad y rendimiento
(según mi opinión) es la segunda, es decir paginar en el Servidor Web y
evitar viajes al servidor de datos y no sobre cargar al cliente. Esta forma de
paginación la podemos implementar usando el GridView.
Para paginar en el GridView configurar la propiedad AllowPaging en True,
definir el tamaño de la página configurando la propiedad PageSize y luego
programar en el evento PageIndexChanging configurando el índice de
página (propiedad PageIndex) en el índice seleccionado por el usuario
([Link]) y finalmente enlazar nuevamente el control GridView.
A continuación un ejemplo basado en el demo anterior que lista los
productos pero esta vez paginado de 10 en 10.
Luis Dueñas Pag 545
La Biblia de Visual Basic .NET
Demo 79
Crear un nuevo sitio web vacío: del menú “File”, seleccionar “Add”,
“New Web Site”.
Seleccionar como lenguaje “Visual Basic” y como plantilla “ASP .NET
Empty Web Site”.
Seleccionar como ubicación del sitio web “HTTP” y escribir como
nombre: [Link]
Hacer una referencia a la librería [Link].
Agregar el archivo de hoja de estilo y la página Lista de Productos
creado en el demo anterior: del menú “Website”, seleccionar “Add
Existing Item”.
Ingresar al Demo 78 y seleccionar los archivos “[Link]” y
“[Link]”.
Modificar el título de la página (literal 1) a “Paginando en el GridView”.
Seleccionar el GridView “gvProducto” y configurar la propiedad
“AllowPaging” en “True”.
El diseño de la página Lista de Productos Paginada debe quedar similar
al gráfico 5.31:
Luis Dueñas Pag 546
La Biblia de Visual Basic .NET
Gráfico 5.31: Diseño de la Página Lista de Productos Paginada
Escribir el siguiente código en la página:
Imports [Link]
Imports [Link]
Partial Class _Default
Inherits [Link]
Private lobeProducto As New List(Of beProducto)
Private Sub EnlazarGridView()
[Link] = lobeProducto
[Link]()
End Sub
Protected Sub Page_Load(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
If Not [Link] Then
Dim obrProducto As New brProducto
lobeProducto = [Link]
Session("Productos") = lobeProducto
EnlazarGridView()
End If
End Sub
Luis Dueñas Pag 547
La Biblia de Visual Basic .NET
Protected Sub PaginarListaProductos(ByVal sender As Object, _
ByVal e As [Link]) _
Handles [Link]
lobeProducto = Session("Productos")
[Link] = [Link]
EnlazarGridView()
End Sub
End Class
Importante: En el código anterior se usa un objeto de sesión para
guardar la lista de productos ya que al enviar los datos al cliente se pierden
los valores de los objetos, es por eso que en las aplicaciones web se usan
variables de sesión para guardar dichos datos en el servidor web y no
perderlos.
Modificar el archivo de configuración [Link] para agregar la clave
conNW en la sección appSettings, tal como se muestra:
<?xml version="1.0"?>
<configuration>
<[Link]>
<compilation debug="true" strict="false" explicit="true"
targetFramework="4.0"/>
</[Link]>
<appSettings>
<add key="conNW" value="uid=CursoNET; pwd=123456;
data source=DSOFT\DSOFT;initial catalog=Northwind"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 548
La Biblia de Visual Basic .NET
Gráfico 5.32: Ejecución de la Página Lista de Productos Paginada
Luis Dueñas Pag 549
La Biblia de Visual Basic .NET
3.3. Ordenando en el GridView
Para acceder rápidamente a los datos es necesario a veces incorporar la
funcionalidad de ordenar las columnas ya sea en forma ascendente o
descendente, con esto el usuario puede ubicar rápidamente los datos de
acuerdo a un criterio.
Para ordenar el GridView de ASP .NET se configura la propiedad Allow
Sorting en True y luego se debe configurar la propiedad SortExpression de
cada columna especificando el campo que se va a ordenar, también
debemos programar en el evento Sorting la ordenación del origen de datos
de acuerdo al campo o columna especificada en la propiedad
SortExpression.
A continuación un ejemplo basado en el demo anterior de la paginación de
productos, a la cual le vamos a aumentar para que se pueda ordenar en
forma ascendente y descendente por cada columna de los productos.
Demo 80
Crear un nuevo sitio web vacío: del menú “File”, seleccionar “Add”,
“New Web Site”.
Seleccionar como lenguaje “Visual Basic” y como plantilla “ASP .NET
Empty Web Site”.
Seleccionar como ubicación del sitio web “HTTP” y escribir como
pnombre: [Link]
Hacer una referencia a la librería [Link].
Agregar el archivo de hoja de estilo y la página Lista de Productos
creado en el demo anterior: del menú “Website”, seleccionar “Add
Existing Item”.
Ingresar al Demo 79 y sleccionar los archivos “[Link]” y
“[Link]”.
Modificar el título de la página (literal 1) a “Ordenando en el GridView”.
Luis Dueñas Pag 550
La Biblia de Visual Basic .NET
Seleccionar el GridView “gvProducto” y configurar la propiedad
“AllowSorting” en “True”.
Clic a la etiqueta inteligente ubicada al lado izquierdo superior de la
grilla y del menú contextual seleccionar “Edit Columns”.
Seleccionar cada columna y escribir en la propiedad SortExpression lo
mismo que tiene la propiedad DataField, es decir el campo a ordenar.
El diseño de la página Lista de Productos Ordenada debe quedar similar
al gráfico 5.33:
Gráfico 5.33: Diseño de la Página Lista de Productos Ordenada
Agregar una clase al App_Code: del menú “Website”, seleccionar “Add
New Item”, luego “Class”, escribir como nombre “[Link]”.
Preguntará si se desea incluir la clase en la carpeta especial App_Code
confirmar que Sí.
Modificar el código de la clase como sigue:
Imports [Link]
Imports [Link]
Public Class ucCompara(Of T)
Luis Dueñas Pag 551
La Biblia de Visual Basic .NET
Implements IComparer(Of T)
Private Campo As String
Private TipoOrden As TiposOrden
Public Enum TiposOrden
Ascendente = 0
Descendente = 1
End Enum
Public Sub New(ByVal vCampo As String, _
ByVal vTipoOrden As TiposOrden)
Campo = vCampo
TipoOrden = vTipoOrden
End Sub
Public Function Compare(ByVal x As T, ByVal y As T) As _
Integer Implements IComparer(Of T).Compare
Dim valX As Object = _
[Link](Campo).GetValue(x, Nothing)
Dim valY As Object = _
[Link](Campo).GetValue(y, Nothing)
If TipoOrden = [Link] Then
Return ([Link](valY))
Else
Return ([Link](valX))
End If
End Function
End Class
Importante: En el código anterior se está creando una clase que permite
ordenar cualquier tipo de objeto en forma ascendente o descendente
usando para ello reflection. No solo se podrá usar para ordenar los
productos de este ejemplo sino cualquier lista de objetos, por lo que es
conveniente que se agrege la clase a una librería para que pueda ser
reusable.
Escribir el siguiente código en la página:
Imports [Link]
Imports [Link]
Luis Dueñas Pag 552
La Biblia de Visual Basic .NET
Partial Class _Default
Inherits [Link]
Private lobeProducto As New List(Of beProducto)
Private Sub EnlazarGridView()
[Link] = lobeProducto
[Link]()
End Sub
Protected Sub Page_Load(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
If Not [Link] Then
Dim obrProducto As New brProducto
lobeProducto = [Link]
Session("Productos") = lobeProducto
EnlazarGridView()
End If
End Sub
Protected Sub PaginarListaProductos(ByVal sender As Object, _
ByVal e As [Link]) _
Handles [Link]
lobeProducto = Session("Productos")
[Link] = [Link]
EnlazarGridView()
End Sub
Protected Sub OrdenarListaProductos(ByVal sender As Object, _
ByVal e As [Link]) _
Handles [Link]
lobeProducto = Session("Productos")
Dim N As Integer = 0
If ViewState([Link]) Is Nothing Then
N=0
Else
If ViewState([Link]) = "1" Then
N=0
Else
N=1
End If
Luis Dueñas Pag 553
La Biblia de Visual Basic .NET
End If
ViewState([Link]) = N
Dim oCompara As New ucCompara(Of beProducto) _
([Link], N)
[Link](oCompara)
[Link] = lobeProducto
[Link]()
End Sub
Protected Sub CambiarSimboloOrdenacion(ByVal sender As Object, _
ByVal e As [Link]) _
Handles [Link]
Dim gv As GridView = sender
If [Link] = [Link] Then
Dim Orden As String = "0"
Dim celda As New TableCell
Dim Dibujo As String = "▲"
Dim Campo As String = ""
For Each celda In [Link]
Campo = CType([Link](0), LinkButton).Text
If Campo = "Descripcion" Then
Orden = ViewState("Nombre")
ElseIf Campo = "Precio" Then
Orden = ViewState("PrecioUnitario")
Else
Orden = ViewState(Campo)
End If
If Orden = "0" Then
Dibujo = "▲"
Else
Dibujo = "▼"
End If
Dim lc As New LiteralControl(Dibujo)
[Link](lc)
Next
End If
End Sub
End Class
Luis Dueñas Pag 554
La Biblia de Visual Basic .NET
Nota: En el código anterior se usa el evento RowCreated para crear
dinámicamente los símbolos de ordenación que indiquen si la columna esta
ordenada en forma ascendente o descendente. Para ello se toma el
nombre de la cabecera como campo pero para el caso del nombre la
cabecera dice Descripcion y para el caso del PrecioUnitario la cabecera dice
solo Precio, es por eso que se hace una validación y conversión al nombre
del campo.
Modificar el archivo de configuración [Link] para agregar la clave
conNW en la sección appSettings, tal como se muestra:
<?xml version="1.0"?>
<configuration>
<[Link]>
<compilation debug="true" strict="false" explicit="true"
targetFramework="4.0"/>
</[Link]>
<appSettings>
<add key="conNW" value="uid=CursoNET; pwd=123456;
data source=DSOFT\DSOFT;initial catalog=Northwind"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 555
La Biblia de Visual Basic .NET
Gráfico 5.34: Ejecución de la Página Lista de Productos Ordenada
Luis Dueñas Pag 556
La Biblia de Visual Basic .NET
3.4. Mantenimiento de Datos en el GridView
Es esta última sección sobre el GridView veremos como realizar un
mantenimiento de registros sobre el propio control GridView, para lo cual
crearemos plantillas a nivel de columnas para agregar los botones de
editar, actualizar,cancelar y eliminar.
Mediante la propiedad EditIndex podemos especificar que se va a editar
una fila de la grilla y para regresar al modo lectura solo se configura la
propiedad en -1.
Cuando enlazamos el control GridView a un origen de datos como por
ejemplo una lista de objetos, desde el HTML de la grilla para referirnos a
un campo o propiedad podemos realizarlo de 2 formas: [Link] o
también [Link].
Es preferible usar la segunda técnica en el enlace de datos, si el origen de
datos fuese una tabla de un DataSet para recuperar una columna se usaría
lo siguiente: [Link](“Campo”), en cambio, si el origen de
datos es una lista de objetos, para recuperar una propiedad se usaría lo
siguiente: [Link].
Para saber la ubicación o el índice de la fila en la cual nos encontramos
sobre la grilla se puede usar lo siguiente [Link], todos
estas instrucciones son de lado del servidor y necesitan escribirse como tal
usando: <%#Instrucción%> desde el HTML de la grilla.
A continuación un ejemplo que ilustra como crear un GridView con
columnas personalizadas de tipo plantillas para crear los botones de Editar,
Actualizar, Cancelar y Eliminar, además de como programarlos de lado del
servidor y hacer validaciones de lado del cliente como por ejemplo
confirmar la eliminación. En este ejemplo usted aprenderá como adicionar,
actualizar y eliminar productos usando el control web GridView. Además la
lista de productos se encuentra paginada para una mejor visualización.
Luis Dueñas Pag 557
La Biblia de Visual Basic .NET
Demo 81
Crear un nuevo sitio web vacío: del menú “File”, seleccionar “Add”,
“New Web Site”.
Seleccionar como lenguaje “Visual Basic” y como plantilla “ASP .NET
Empty Web Site”.
Seleccionar como ubicación del sitio web “HTTP” y escribir como
nombre: [Link]
Hacer una referencia a la librería [Link].
Agregar el archivo de hoja de estilo creado en el demo anterior: del
menú “Website”, seleccionar “Add Existing Item”.
Ingresar al Demo 80 y seleccionar el archivo “[Link]”.
Agregar una nueva página: del menú “Website”, seleccionar “Add New
Item”, “Web Form” y escribir como nombre “Mantenimiento
[Link]”.
Ubicarse dentro del div de la nueva página e insertar una tabla de 4
filas por 1 columna.
Diseñar la página dentro de las celdas de la tabla como sigue:
Objeto Propiedad Valor
Literal1 Text Mantenimiento en el GridView
fila 1, celda 1 Class Titulo
Literal2 Text Lista de Empleados
fila 2, celda1 Class Subtitulo
ImageButton1 ID ibNuevo
fila 3, celda 1 Height 20px
ImageUrl Imagenes/[Link]
Tooltip Nuevo
Width 20px
GridView1 ID gvEmpleado
fila 4, celda 1 Auto Format Oceanica
AllowPaging True
Luis Dueñas Pag 558
La Biblia de Visual Basic .NET
Clic a la etiqueta inteligente ubicada al lado izquierdo superior de la
grilla y del menú contextual seleccionar “Edit Columns”.
Desmarcar la casilla de verifcación “Auto-generate fields” de la parte
derecha inferior para no generar columnas en ejecución.
Agregar las siguientes columnas:
Columna Propiedad Valor
TemplateField1 HeaderText Actualizar
TemplateField2 HeaderText Eliminar
BoundField1 HeaderText Código
DataField Codigo
ReadOnly True
ItemStyle
Width 60px
BoundField2 HeaderText Apellido
DataField Apellido
ItemStyle
Width 100px
BoundField3 HeaderText Nombre
DataField Nombre
ItemStyle
Width 100px
TemplateField3 HeaderText Fecha Nac
Ingresar a la vista “Source” y completar las 3 columnas de tipo plantilla:
<asp:TemplateField HeaderText="Actualizar">
<ItemTemplate>
<asp:HiddenField ID="hdfCorrelativo1"
Value="<%#[Link]%>" runat="server" />
<asp:ImageButton ID="ibEditar" OnClick="EditarEmpleado"
ImageUrl="Imagenes/[Link]" ToolTip="Editar" width="20px"
height="20px" runat="server"/>
</ItemTemplate>
<EditItemTemplate>
<asp:HiddenField ID="hdfCorrelativo2"
Value="<%#[Link]%>" runat="server" />
<asp:ImageButton ID="ibGuardar" OnClick="GuardarEmpleado"
ImageUrl="Imagenes/[Link]" ToolTip="Guardar" width="20px"
Luis Dueñas Pag 559
La Biblia de Visual Basic .NET
height="20px" runat="server"/>
<asp:ImageButton ID="ibCancelar" OnClick="CancelarEmpleado"
ImageUrl="Imagenes/[Link]" ToolTip="Cancelar" width="20px"
height="20px" runat="server"/>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Eliminar">
<ItemTemplate>
<asp:ImageButton ID="imgEliminar"
ImageUrl="~/Imagenes/[Link]" ToolTip="Eliminar" Width="20px"
Height="20px" style="cursor:hand" runat="server"
OnClientClick="return(confirm('Seguro de eleiminar'));"
OnClick="EliminarEmpleado" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Fecha Nac">
<ItemTemplate>
<asp:Label ID="lblFechaNac"
Text='<%#[Link]([Link])%>'
runat="server" />
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txtFechaNac"
Text='<%#[Link]([Link])%>'
runat="server" />
</EditItemTemplate>
<ItemStyle Width="100px" />
</asp:TemplateField>
El diseño de la página debe quedar similar al gráfico 5.35:
Luis Dueñas Pag 560
La Biblia de Visual Basic .NET
Gráfico 5.35: Diseño de la Página Mantenimiento de Productos
Agregar una clase al App_Code: del menú “Website”, seleccionar “Add
New Item”, luego “Class”, escribir como nombre “[Link]”.
Preguntará si se desea incluir la clase en la carpeta especial App_Code
confirmar que Sí.
Modificar el código de la clase como sigue:
Imports [Link]
Public Class ucRutinas
Public Shared Function DevolverFecha _
(ByVal Fecha As DateTime) As String
If [Link] <= 1900 Then
Return ("")
Else
Return ([Link]("{0:d}", Fecha))
End If
End Function
Public Shared Function AsignarFecha _
(ByVal Fecha As String) As DateTime
If Fecha = "" Then
Luis Dueñas Pag 561
La Biblia de Visual Basic .NET
Return (New Date(1900, 1, 1))
Else
Return ([Link](Fecha))
End If
End Function
End Class
Nota: Estas 2 funciones son usadas una por la grilla para devolver una
fecha como cadena y la segunda para asignar una fecha, ambas manejan
las fechas vacias como el 1 de Enero de 1900.
Escribir el siguiente código en la página:
Imports [Link]
Imports [Link]
Partial Class _MantenimientoEmpleados
Inherits [Link]
Private lobeEmpleado As New List(Of beEmpleado)
Private obrEmpleado As New brEmpleado
Private Sub EnlazarGridView()
[Link] = lobeEmpleado
[Link]()
End Sub
Private Sub ListarEmpleados()
lobeEmpleado = [Link]
Session("Empleados") = lobeEmpleado
EnlazarGridView()
End Sub
Protected Sub Page_Load(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
If Not [Link] Then
ListarEmpleados()
End If
End Sub
Protected Sub PaginarEmpleados _
Luis Dueñas Pag 562
La Biblia de Visual Basic .NET
(ByVal sender As Object, ByVal e As GridViewPageEventArgs) _
Handles [Link]
lobeEmpleado = Session("Empleados")
[Link] = [Link]
EnlazarGridView()
End Sub
Protected Sub EliminarEmpleado(ByVal sender As Object, _
ByVal e As EventArgs)
Dim img As ImageButton = sender
Dim celda As DataControlFieldCell = [Link]
Dim fila As GridViewRow = [Link]
Dim Codigo As Integer = [Link]([Link](2).Text)
Dim N As Integer = [Link](Codigo)
If N > 0 Then
[Link]([Link], "Mensaje", _
"<script language='javascript'>alert('Empleado eliminado');</script>")
Else
[Link]([Link], "Mensaje", _
"<script language='javascript'>alert('Empleado No se pudo
eliminar');</script>")
End If
ListarEmpleados()
End Sub
Protected Sub NuevoEmpleado(ByVal sender As Object, _
ByVal e As ImageClickEventArgs) Handles [Link]
ViewState("operacion") = 1 'Adicionar
lobeEmpleado = Session("Empleados")
Dim obeEmpleado As New beEmpleado
[Link](obeEmpleado)
Dim IndiceUltimaPagina As Integer = _
[Link] \ [Link]
If [Link] Mod [Link] = 0 Then _
IndiceUltimaPagina -= 1
[Link] = IndiceUltimaPagina
[Link] = _
([Link] Mod [Link]) - 1
EnlazarGridView()
Luis Dueñas Pag 563
La Biblia de Visual Basic .NET
End Sub
Private Function DevolverCorrelativo(ByVal sender As Object) As Integer
Dim ib As ImageButton = CType(sender, ImageButton)
Dim celda As DataControlFieldCell = _
CType([Link], DataControlFieldCell)
Dim hdf As HiddenField = _
CType([Link](1), HiddenField)
Return ([Link])
End Function
Protected Sub EditarEmpleado(ByVal sender As Object, _
ByVal e As EventArgs)
ViewState("operacion") = 2 'Actualizar
lobeEmpleado = Session("Empleados")
Dim N As Integer = DevolverCorrelativo(sender)
[Link] = _
N - [Link] * [Link]
EnlazarGridView()
End Sub
Protected Sub GuardarEmpleado(ByVal sender As Object, _
ByVal e As EventArgs)
lobeEmpleado = Session("Empleados")
Dim N As Integer = DevolverCorrelativo(sender)
Dim pos As Integer = _
N - [Link] * [Link]
Dim obeEmpleado As New beEmpleado
With obeEmpleado
.Apellido = CType([Link](pos).Cells(3).Controls(0), _
TextBox).Text
.Nombre = CType([Link](pos).Cells(4).Controls(0), _
TextBox).Text
.FechaNac = [Link](CType _
([Link](pos).Cells(5).Controls(1), TextBox).Text)
End With
If ViewState("operacion") = "1" Then
'Adicionar un Empleado
Dim IdEmpleado As Integer = [Link](obeEmpleado)
If IdEmpleado > 0 Then
Luis Dueñas Pag 564
La Biblia de Visual Basic .NET
[Link]([Link]("[Link]"),
"Mensaje", _
"<script languaje='javascript'>alert('Se registro el empleado " + _
[Link] + "');</script>")
Else
[Link]([Link]("[Link]"),
"Mensaje", _
"<script languaje='javascript'>alert('No se pudo registrar el
empleado');</script>")
End If
ElseIf ViewState("operacion") = "2" Then
'Actualizar un Empleado
[Link] = [Link](pos).Cells(2).Text
Dim exito As Boolean = [Link](obeEmpleado)
If exito Then
[Link]([Link]("[Link]"),
"Mensaje", _
"<script languaje='javascript'>alert('Se actualizo el
empleado');</script>")
Else
[Link]([Link]("[Link]"),
"Mensaje", _
"<script languaje='javascript'>alert('No se pudo actualizar el
empleado');</script>")
End If
End If
[Link] = -1
ViewState("operacion") = ""
ListarEmpleados()
End Sub
Protected Sub CancelarEmpleado(ByVal sender As Object, _
ByVal e As EventArgs)
lobeEmpleado = Session("Empleados")
[Link] = -1
EnlazarGridView()
End Sub
End Class
Nota: En el código anterior se usa un objeto ViewState para guardar el
valor de la operación elegida, 1 es para dicionar y 2 para actualizar, este
Luis Dueñas Pag 565
La Biblia de Visual Basic .NET
valor se usa porque existe un solo botón para guardar cualquier operación.
El objeto ViewState guarda dicho valor en el cliente y lo recupera en el
servidor.
Modificar el archivo de configuración [Link] para agregar la clave
conNW en la sección appSettings, tal como se muestra:
<?xml version="1.0"?>
<configuration>
<[Link]>
<compilation debug="true" strict="false" explicit="true"
targetFramework="4.0"/>
</[Link]>
<appSettings>
<add key="conNW" value="uid=CursoNET; pwd=123456;
data source=DSOFT\DSOFT;initial catalog=Northwind"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 566
La Biblia de Visual Basic .NET
Gráfico 5.36: Ejecución de la Página Mantenimiento de Productos
Luis Dueñas Pag 567
La Biblia de Visual Basic .NET
4. Creando Plantillas en Controles Enlazados a Datos
Las plantillas (templates) son un conjunto de elementos, controles HTML y
código de servidor incrustado que se usan para personalizar la apariencia
de un control web enlazado a datos.
Una plantilla permite personalizar el diseño de un control web y especificar
que controles se mostrarán en modo lectura usando ItemTemplate y que
se mostrará en modo edición usando EditItemTemplate. También podemos
definir que irá en la cabecera del control usando HeaderTemplate y que irá
en el pie usando FooterTemplate.
Los controles web que soportan plantillas son los enlazados a datos: tales
como el Repeater, DataList, GridView, DetailsView, FormView; así como
también los controles de navegación: Menu y SiteMapPath, entre otros.
Para darle dinamismo a las plantillas se puede usar código incrustado del
servidor mediante el elemento: <% %>, por ejemplo podemos usar enlace
de datos mediante <%#[Link]%> para obtener el
valor de una propiedad de una fila o también usar una función definida en
el código como protegida: <%#Función(Par1,Par2,…)%>.
En realidad las plantillas permiten crear aplicaciones de datos con poco
código y muy personalizado. Es más fácil usar plantillas con código
incrustado del servidor que programar en el evento RowCreated o
RowDataBound de un GridView para crear subtotales, ocultar elementos,
asociar scripts de lado del cliente, etc.
En esta parte veremos cómo usar plantillas en el control Repeater, luego
en el control DataList y finalmente como crear plantillas jerárquicas para
mostrar un control dentro de otro. Algunos usos de las plantillas jerárquicas
son ver los detalles de cada orden en una misma grilla, los productos de
una cierta categoría, los distritos de cada provincia de cada departamento,
etc.
Para obtener más información sobre plantillas de controles de servidor web
ver la referencia 35 al final del libro.
Luis Dueñas Pag 568
La Biblia de Visual Basic .NET
4.1. Trabajando con el Control Repeater
El control Repeater es el más ligero de todos los controles enlazados a
datos, tiene pocas propiedades y cuando se enlaza a un origen de datos no
se muestra ningún dato, ya que necesita que se cree su plantilla para
indicar que es lo que se va a mostrar.
Este control soporta solo 5 tipos de plantillas: HeaderTemplate,
FooterTemplate, ItemTemplate, AlternatingItemTemplate y Separator
Template. El principal elemento de una plantilla (que nunca debe faltar) es
ItemTemplate que indica el diseño de cada fila a repetirse.
Cuando se especifica el elemento AlternatingItemTemplate las filas pares
salen con este diseño y las impares con lo que se especifique en
ItemTemplate.
Finalmente, para especificar el índice de la fila actual del control Repeater
podemos usar el siguiente código: <%#[Link]%>.
A continuación se verá un ejemplo de como crear una plantilla para el
control Repeater que muestre en una tabla los datos de las categorías:
código, nombre y foto la cual es extraida de una carpeta que tiene archivos
jpg con el código como nombre de archivo, es decir [Link], [Link], etc y para
las categorías nuevas que no tengan foto se mostrará el archivo [Link].
Demo 82
Crear un nuevo sitio web vacío: del menú “File”, seleccionar “Add”,
“New Web Site”.
Seleccionar como lenguaje “Visual Basic” y como plantilla “ASP .NET
Empty Web Site”.
Seleccionar como ubicación del sitio web “HTTP” y escribir como
nombre: [Link]
Hacer una referencia a la librería [Link].
Agregar el archivo de hoja de estilo creado en el demo anterior: del
menú “Website”, seleccionar “Add Existing Item”.
Luis Dueñas Pag 569
La Biblia de Visual Basic .NET
Ingresar al Demo 81 y seleccionar el archivo “[Link]”.
Crear una carpeta llamada “Categorias” y agregar 9 archivos de
imagen: del [Link] al [Link] y el archivo [Link]
Agregar una nueva página: del menú “Website”, seleccionar “Add New
Item”, “Web Form” y escribir como nombre “[Link]”.
Ubicarse dentro del div de la nueva página e insertar una tabla de 3
filas por 1 columna.
Diseñar la página dentro de las celdas de la tabla como sigue:
Objeto Propiedad Valor
Literal1 Text Plantilla en el control repeater
fila 1, celda 1 Class Titulo
Literal2 Text Lista de Categorías
fila 2, celda1 Class Subtitulo
Repeater1 ID rpCategoria
fila 3, celda 1
Ingresar a la vista “Source” y modificar el control Repeater como sigue:
<asp:Repeater ID="rpCategoria" runat="server">
<HeaderTemplate>
<table>
<tr bgcolor="blue">
<td style="width:70px">
<font color="white">Codigo</font>
</td>
<td style="width:200px">
<font color="white">Nombre</font>
</td>
<td style="width:100px">
<font color="white">Foto</font>
</td>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr bgcolor="white">
<td style="width:70px">
Luis Dueñas Pag 570
La Biblia de Visual Basic .NET
<font color="blue">
<%# [Link]%>
</font>
</td>
<td style="width:200px">
<font color="blue">
<%# [Link]%>
</font>
</td>
<td style="width:100px">
<font color="blue">
<img src='<%#VerImagen([Link])%>'
width="100" height="80" alt="" />
</font>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
El diseño de la página debe quedar similar al gráfico 5.37:
Luis Dueñas Pag 571
La Biblia de Visual Basic .NET
Gráfico 5.37: Diseño de la Página Lista de Categorías
Escribir el siguiente código en la página:
Imports [Link]
Imports [Link]
Imports [Link]
Partial Class _ListaCategorias
Inherits [Link]
Protected Sub Page_Load(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
If Not [Link] Then
Dim obrCategoria As New brCategoria
Dim lobeCategoria As List(Of beCategoria) = _
[Link]()
[Link] = lobeCategoria
[Link]()
Luis Dueñas Pag 572
La Biblia de Visual Basic .NET
End If
End Sub
Protected Function VerImagen(ByVal Codigo As Integer) As String
Dim Archivo As String = [Link]( _
[Link]("Categorias/{0}.jpg", Codigo))
Dim URL As String = [Link] _
("[Link] Codigo)
If Not [Link](Archivo) Then
URL = "[Link]
End If
Return (URL)
End Function
End Class
Nota: En el código anterior la función VerImagen esta enlazada a la
propiedad src del control HTML image para devolver el archivo
correspondiente al código de categoría, sino existe se devuelve el archivo
[Link].
Modificar el archivo de configuración [Link] para agregar la clave
conNW en la sección appSettings, tal como se muestra:
<?xml version="1.0"?>
<configuration>
<[Link]>
<compilation debug="true" strict="false" explicit="true"
targetFramework="4.0"/>
</[Link]>
<appSettings>
<add key="conNW" value="uid=CursoNET; pwd=123456;
data source=DSOFT\DSOFT;initial catalog=Northwind"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 573
La Biblia de Visual Basic .NET
Gráfico 5.38: Ejecución de la Página Lista de Categorías
Luis Dueñas Pag 574
La Biblia de Visual Basic .NET
4.2. Trabajando con el Control DataList
Trabajar con el Control DataList es muy similar al control Repeater
anteriormente visto, la diferencias básicas son que el DataList tiene mas
propiedades que permiten controlar la presentación de la plantilla tales
como la propiedad RepeatColumns que indica la cantidad de columnas a
mostrar por defecto se muestra en una, la propiedad RepeatDirection que
indica si se desea ver en forma horizontal o vertical y la propiedad
RepeatLayout que indica el tipo de diseño en tabla, flujo, lista ordenada o
sin ordenar.
Además mientras el control Repeater solo puede crearse la plantilla desde
la vista “Source” en el HTML, el control DataList tiene soporte para crear la
plantilla en modo “Design” dando clic a la etiqueta inteligente al lado
izquierdo superior del control y seleccionando “Edit Templates”.
También otra característica es que soporta todos los tipos de plantillas: las
5 soportadas por el control Repeater (HeaderTemplate, FooterTemplate,
ItemTemplate, AlternatingItemTemplate y SeparatorTemplate), más
EditItemTemplate y SelectedItemTemplate, más todas las plantillas de
estilos: ItemStyle, EditItemStyle, SelectedItemStyle, AlternatingItemStyle,
etc.
A continuación se verá un ejemplo de como crear una plantilla para el
control DataList que muestre en una tabla los datos de las empleados:
código, apellido, nombre, fecha de nacimiento y foto la cual es extraida de
una carpeta que tiene archivos jpg con el código como nombre de archivo,
es decir [Link], [Link], etc y para los empleados que no tengan foto se
mostrará el archivo [Link].
Demo 83
Crear un nuevo sitio web vacío: del menú “File”, seleccionar “Add”,
“New Web Site”.
Seleccionar como lenguaje “Visual Basic” y como plantilla “ASP .NET
Empty Web Site”.
Luis Dueñas Pag 575
La Biblia de Visual Basic .NET
Seleccionar como ubicación del sitio web “HTTP” y escribir como
nombre: [Link]
Hacer una referencia a la librería [Link].
Agregar el archivo de hoja de estilo creado en el demo anterior: del
menú “Website”, seleccionar “Add Existing Item”.
Ingresar al Demo 82 y seleccionar el archivo “[Link]”.
Crear una carpeta llamada “Empleados” y agregar varios archivos de
imagen: del [Link] al [Link] y el archivo [Link]
Agregar una nueva página: del menú “Website”, seleccionar “Add New
Item”, “Web Form” y escribir como nombre “[Link]”.
Ubicarse dentro del div de la nueva página e insertar una tabla de 3
filas por 1 columna.
Diseñar la página dentro de las celdas de la tabla como sigue:
Objeto Propiedad Valor
Literal1 Text Plantilla en el control DataList
fila 1, celda 1 Class Titulo
Literal2 Text Lista de Empleados
fila 2, celda1 Class Subtitulo
DataList1 ID dlsEmpleado
fila 3, celda 1
Ingresar a la vista “Source” y modificar el control DataList como sigue:
<asp:DataList ID="dlsEmpleado" runat="server">
<HeaderTemplate>
<table width="600px">
<tr bgcolor="green">
<td><font color="yellow">Codigo</font></td>
<td><font color="yellow">Apellido</font></td>
<td><font color="yellow">Nombre</font></td>
<td><font color="yellow">Fecha Nac</font></td>
<td><font color="yellow">Foto</font></td>
</tr>
</HeaderTemplate>
Luis Dueñas Pag 576
La Biblia de Visual Basic .NET
<ItemTemplate>
<tr bgcolor="white">
<td><font color="blue"><%#Eval("Codigo")%></font></td>
<td><font color="blue"><%#Eval("Apellido")%></font></td>
<td><font color="blue"><%#Eval("Nombre")%></font></td>
<td><font color="blue"><%#[Link]("{0:d}",
Eval("FechaNac"))%></font></td>
<td>
<font color="blue">
<asp:Image ImageUrl='<%#ObtenerImagen
(Eval("Codigo"))%>'
width="100px" height="80px" runat="server" />
</font>
</td>
</tr>
</ItemTemplate>
<AlternatingItemTemplate>
<tr bgcolor="blue">
<td><font color="white"><%#Eval("Codigo")%></font></td>
<td><font color="white"><%#Eval("Apellido")%></font></td>
<td><font color="white"><%#Eval("Nombre")%></font></td>
<td><font color="white"><%#[Link]("{0:d}",
Eval("FechaNac"))%></font></td>
<td>
<font color="white">
<asp:Image ImageUrl='<%#ObtenerImagen
(Eval("Codigo"))%>'
width="100px" height="80px" runat="server" />
</font>
</td>
</tr>
</AlternatingItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:DataList>
Nota: Recordar que al existir el elemento AlternatingItem las filas pares
tomaran este estilo y las impares el del ItemTemplate.
El diseño de la página debe quedar similar al gráfico 5.39:
Luis Dueñas Pag 577
La Biblia de Visual Basic .NET
Gráfico 5.39: Diseño de la Página Lista de Empleados
Escribir el siguiente código en la página:
Imports [Link]
Imports [Link]
Imports [Link]
Partial Class _Default
Inherits [Link]
Protected Sub Page_Load(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
'Si es la primera vez que carga la pagina
If Not [Link] Then
Dim obrEmpleado As New brEmpleado
Dim lobeEmpleado As New List(Of beEmpleado)
lobeEmpleado = [Link]
[Link] = lobeEmpleado
[Link]()
End If
Luis Dueñas Pag 578
La Biblia de Visual Basic .NET
End Sub
Protected Function ObtenerImagen(ByVal codigo As Integer) As String
Dim archivo As String = [Link]("{0}{1}.jpg", _
[Link]("Empleados/"), codigo)
If [Link](archivo) Then
Return ([Link]("~/Empleados/{0}.jpg", codigo))
Else
Return ("~/Empleados/[Link]")
End If
End Function
End Class
Nota: En el código anterior la función ObtenerImagen esta enlazada a la
propiedad ImageUrl del control web Image para devolver el archivo
correspondiente al código de empleado, sino existe se devuelve el archivo
[Link].
Importante: Observar que en el ejemplo anterior, la función del servidor
se enlazó a un control HTML y ahora a un control web, es decir podemos
usar código incrustado del servidor en ambos tipos de controles.
Modificar el archivo de configuración [Link] para agregar la clave
conNW en la sección appSettings, tal como se muestra:
<?xml version="1.0"?>
<configuration>
<[Link]>
<compilation debug="true" strict="false" explicit="true"
targetFramework="4.0"/>
</[Link]>
<appSettings>
<add key="conNW" value="uid=CursoNET; pwd=123456;
data source=DSOFT\DSOFT;initial catalog=Northwind"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 579
La Biblia de Visual Basic .NET
Gráfico 5.40: Ejecución de la Página Lista de Empleados
Luis Dueñas Pag 580
La Biblia de Visual Basic .NET
4.3. Creando Plantillas Jerárquicas
Como último tema sobre plantillas crearemos plantillas jerárquicas, es decir
dentro de un control enlazado a datos incluiremos otro control enlazado a
datos, similar a un TreeView con la diferencia de que el TreeView solo
puede ver una columna, en cambio con las plantillas jerarquicas podemos
ver la cantidad de columnas que deseemos.
A continuación, presentaremos un ejemplo de una lista de categorías que a
su vez cada categoría presenta una lista de productos, para esto
necesitamos crear una carpeta con las categorías y también un par de
imágenes para los iconos de expandir y contraer para ver los productos.
Demo 84
Crear un nuevo sitio web vacío: del menú “File”, seleccionar “New Web
Site”.
Seleccionar como lenguaje “Visual Basic” y como plantilla “ASP .NET
Empty Web Site”.
Seleccionar como ubicación del sitio web “HTTP” y escribir como
nombre: [Link]
Hacer una referencia a la librería [Link].
Agregar el archivo de hoja de estilo creado en el demo anterior: del
menú “Website”, seleccionar “Add Existing Item”.
Ingresar al Demo 83 y seleccionar el archivo “[Link]”.
Crear una carpeta llamada “Categorias” y agregar varios archivos de
imagen: del [Link] al [Link] y el archivo [Link]
Agregar una nueva página: del menú “Website”, seleccionar “Add New
Item”, “Web Form” y escribir como nombre “ProductosPor
[Link]”.
Ubicarse dentro del div de la nueva página e insertar una tabla de 3
filas por 1 columna.
Luis Dueñas Pag 581
La Biblia de Visual Basic .NET
Diseñar la página dentro de las celdas de la tabla como sigue:
Objeto Propiedad Valor
Literal1 Text Plantillas Jerárquicas en
fila 1, celda 1 DataList
Class Titulo
Literal2 Text Lista de Categorías y sus
fila 2, celda1 Productos
Class Subtitulo
DataList1 ID dlsCategoria
fila 3, celda 1
Ingresar a la vista “Source” y modificar el control DataList como sigue:
<asp:DataList ID="dlsCategoria" runat="server">
<HeaderTemplate>
<table width="600px">
<tr bgcolor="blue">
<td style="width:100px">
<font color="white">Codigo</font>
</td>
<td style="width:300px">
<font color="white">Nombre de Categoria</font>
</td>
<td style="width:200px">
<font color="white">Foto Categoria</font>
</td>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr bgcolor="white">
<td style="width:100px">
<font color="blue">
<img id="imgOpera" src="[Link]"
onclick='Expandir(this,<%#[Link]%>)'
alt="" style="cursor:hand" width="20px" height="20px" />
<%# [Link]%>
</font>
</td>
<td style="width:300px">
<font color="blue">
Luis Dueñas Pag 582
La Biblia de Visual Basic .NET
<%# [Link]%>
</font>
</td>
<td style="width:200px">
<font color="blue">
<asp:Image
ImageUrl='<%#ObtenerFotoCategoria([Link])%>'
Width="100px" Height="70px" runat="server" />
</font>
</td>
</tr>
<tr>
<td style="width:100px"></td>
<td style="width:500px" colspan="2">
<asp:DataList ID="dlsProducto"
DataSource="<%#ListarProductosPorCategoria
([Link])%>"
runat="server" style="display:none">
<HeaderTemplate>
<table>
<tr bgcolor="red">
<td style="width:100px">
<font color="white">Codigo</font>
</td>
<td style="width:200px">
<font color="white">Nombre del Producto</font>
</td>
<td style="width:100px">
<font color="white">Precio</font>
</td>
<td style="width:100px">
<font color="white">Stock</font>
</td>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr bgcolor="white">
<td style="width:100px">
<font color="red">
<%# [Link]%>
Luis Dueñas Pag 583
La Biblia de Visual Basic .NET
</font>
</td>
<td style="width:200px">
<font color="red">
<%# [Link]%>
</font>
</td>
<td style="width:100px">
<font color="red">
<%# [Link]%>
</font>
</td>
<td style="width:100px">
<font color="red">
<%# [Link]%>
</font>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:DataList>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:DataList>
Nota: Para llenar los productos de cada categoría se hace uso de una
función del servidor que estará definida mas adelante.
Aumentar el siguiente script en la cabecera de la página (sección
Head):
<script language="javascript" type="text/javascript">
function Expandir(img, correlativo) {
if ([Link] == "[Link] {
[Link] = "[Link]
Luis Dueñas Pag 584
La Biblia de Visual Basic .NET
}
else {
[Link] = "[Link]
}
var tabla = [Link]("dlsCategoria_dlsProducto_" +
correlativo);
if ([Link] == "" || [Link] == "inline") {
[Link] = "none";
}
else {
[Link] = "inline";
}
}
</script>
Nota: La función anterior tiene como parámetros la imagen a la cual se dio
clic y el índice de la fila actual, lo que permite expandir o colapsar la lista
de productos que en realidad es una tabla con un nombre compuesto y al
final tiene dicho índice, el cual se obtiene con: [Link].
El diseño de la página debe quedar similar al gráfico 5.41:
Luis Dueñas Pag 585
La Biblia de Visual Basic .NET
Gráfico 5.41: Diseño de la Página Lista de Categorias y Productos
Escribir el siguiente código en la página:
Imports [Link]
Imports [Link]
Imports [Link]
Partial Class _ProductosPorCategorias
Inherits [Link]
Private lobeProducto As New List(Of beProducto)
Private CodigoCategoria As Integer
Protected Sub Page_Load(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
If Not [Link] Then
'Llenar las Categorias
Dim lobeCategoria As New List(Of beCategoria)
Dim obrCategoria As New brCategoria
lobeCategoria = [Link]
'Llenar los Productos
Luis Dueñas Pag 586
La Biblia de Visual Basic .NET
Dim obrProducto As New brProducto
lobeProducto = [Link]
Session("Productos") = lobeProducto
ViewState("N") = 0
'Enlazar el control
[Link] = lobeCategoria
[Link]()
End If
End Sub
Protected Function ObtenerFotoCategoria _
(ByVal codigo As Integer) As String
Dim Archivo As String = [Link]("{0}{1}.jpg", _
[Link]("Categorias/"), codigo)
If [Link](Archivo) Then
Return ([Link]("~/Categorias/{0}.jpg", codigo))
Else
Return ("~/Categorias/[Link]")
End If
End Function
Private Function BuscarProductos _
(ByVal obeProducto As beProducto) As Boolean
Return ([Link] = CodigoCategoria)
End Function
Protected Function ListarProductosPorCategoria _
(ByVal codCategoria As Integer) As List(Of beProducto)
lobeProducto = Session("Productos")
CodigoCategoria = codCategoria
Dim pred As New Predicate(Of beProducto) _
(AddressOf BuscarProductos)
Return ([Link](pred))
End Function
End Class
Nota: En el código anterior se esta usando predicados para filtrar los
productos de una cierta categoria.
Modificar el archivo de configuración [Link] para agregar la clave
conNW en la sección appSettings, tal como se muestra:
Luis Dueñas Pag 587
La Biblia de Visual Basic .NET
<?xml version="1.0"?>
<configuration>
<[Link]>
<compilation debug="true" strict="false" explicit="true"
targetFramework="4.0"/>
</[Link]>
<appSettings>
<add key="conNW" value="uid=CursoNET; pwd=123456;
data source=DSOFT\DSOFT;initial catalog=Northwind"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 5.42: Ejecución de la Página Lista de Categorias y
Productos
Luis Dueñas Pag 588
La Biblia de Visual Basic .NET
Preguntas de Repaso
1. En que espacio de nombres se encuentra ASP .NET?
2. Con qué nombre se le conoce al IDE de Visual Studio para desarrollar
Sitios Web?
3. Menciona 3 Lenguajes con que podemos desarrollar aplicaciones web
en ASP .NET
4. Qué características de ASP .NET hacen que las aplicaciones sean mas
rápidas?
5. Por qué las páginas ASP .NET que usan controles web pueden verse en
cualquier Browser?.
6. Qué es un formulario web en ASP .NET?
7. Cómo se clasifican los controles del servidor?
8. Por qué una pagina ASP .NET es lenta solo la primera vez que carga?
9. Cómo se llama el proceso que ejecuta los servicios del IIS?
10. En cuantas ubicaciones se puede crear un nuevo sitio web?
11. Qué ejecutable debe correr en caso de que no este registrado ASP .NET
en IIS en vez de volver a instalar primero el IIS y luego Visual Studio?
12. Qué es un control web intrínseco?
13. Mencione 5 controles web intrínsecos.
14. Cuando se trabaja con archivos en una aplicación web, cuál es el
directorio por defecto donde se leen o escriben los archivos en disco?
Luis Dueñas Pag 589
La Biblia de Visual Basic .NET
15. A qué usuario debemos dar permiso en la carpeta para que la
aplicación web pueda leer o escribir un archivo en ASP .NET?
16. En que lado debe realizarse las validaciones de una página: en el
cliente o el servidor y porqué?
17. Cómo se llama el algoritmo de seguridad usado para comprobar si el
que usa el sistema, por ejemplo la pagina es un usuario o un programa.
18. Qué debe hacerse para que al generar varios números al azar con
consecutivamente no devuelvan el mismo número?
19. Cuál es la forma mas simple de subir un archivo desde la pagina hacia
el servidor?
20. Cuál es el tamaño máximo del archivo por defecto al usar el control
FileUpload y que debe hacerse para aumentar la capacidad?
21. Cuál es la alternativa mas simple para validar sin usar directamente
Javascript en el cliente en ASP NET?
22. Menciona 3 controles de validación de ASP .NET?
23. Con qué control web se valida que un campo sea obligatorio?
24. Qué control de validación usaría para validar una fecha?
25. Qué control de validación usaría para validar un RUC, DNI ó teléfono?
26. Menciona 3 propiedades comunes de todos los controles de validación.
27. Cuál es la propiedad mas importante del control de validación que
indica qué control se debe validar?
28. Cómo se llama el control que muestra un resumen con los mensajes de
error de todos los controles de validación?
Luis Dueñas Pag 590
La Biblia de Visual Basic .NET
29. Para qué se usan las Hojas de Estilo en Cascada?
30. Qué ventajas tiene usar archivos CSS en una página ASP .NET?
31. Para qué se usan las páginas principales y qué extensión tienen?
32. Qué ventajas tiene usar páginas principales en ASP .NET?
33. Menciona los 3 controles web de navegación.
34. Con qué control web podemos ver la ubicación donde nos encontramos
en el sitio web?
35. Cómo se llama el archivo XML donde se definen las páginas que tendrá
el sitio web?
36. Cómo se llama el objeto que permite enlazar un mapa de sitio en un
Menú o en un TreeView?
37. Cuál es la forma más simple de implementar fichas en un sitio web de
ASP .NET?
38. Con qué propiedad del control web MultiView se especifica que vista
(View) se va a visualizar?
39. Que propiedad tienen los controles web que indica que se debe guardar
el estado o los valores en el cliente para que no se pierdan al hacer
Postback?
40. Cuál es el control web mas usado en una aplicación con ASP .NET?
41. Cómo se llama la propiedad que permite crear dinámicamente las
columnas en un control GridView?
42. Qué pasos debe realizar para personalizar columnas en un GridView?
43. Cuantos tipos de paginación podemos tener en una aplicación web?
Luis Dueñas Pag 591
La Biblia de Visual Basic .NET
44. Qué propiedades debe configurase para paginar un GridView?
45. En qué evento hay que programar la paginación del GridView?
46. Qué propiedad debe configurase para ordenar las columnas en un
GridView?
47. En qué evento hay que programar la ordenación en el GridView?
48. Qué evento del control GridView puede usarse para crear dinámica
mente controles?
49. Qué instrucción de enlace de datos es mas eficiente: [Link] o
[Link]?
50. Con qué propiedad del GridView se especifica el registro que se va a
editar?
51. Cuál es la diferencia entre guardar un dato usando el objeto Session y
usando el objeto ViewState?
52. Qué se debe hacer para que una columna del GridView al pasar al
modo edición no sea siempre un TextBox?
53. Cuál es la ventaja de usar plantillas en controles enlazados a datos?
54. Menciona 3 controles web que soporten plantillas.
55. Si se usa un control Repeater y se enlaza a un origen de datos, que
hace falta para visualizar sus datos?
56. Cuál es el principal elemento de una plantilla que nunca debe faltar y
especifica el diseño de las filas a repetirse?
57. Con qué etiquetas (tags) se indica en una plantilla que vamos a usar
código incrustado del servidor, por ejemplo para llamar a una función?
Luis Dueñas Pag 592
La Biblia de Visual Basic .NET
58. Cuál es la diferencia del control DataList con respecto al Repeater?
59. Qué indica el elemento AlternatingItemTemplate en una plantilla?
60. En qué tipo de controles (HTML o Web) puede usarse el código
incrustado del servidor?
61. Qué es una plantilla jerárquica y para qué sirve?
62. En una plantilla de un DataList con qué código incrustado del servidor
se obtiene el índice de la fila actual enlazada al origen de datos?
Luis Dueñas Pag 593
La Biblia de Visual Basic .NET
Capitulo 6: Desarrollando Aplicaciones WPF
WPF es un conjunto de componentes que permiten crear aplicaciones de
alto impacto visual usando para ello un lenguaje de marcado de
aplicaciones XML conocido por sus siglas como XAML, además las
aplicaciones construidas en WPF pueden ser para Windows o ejecutarse en
un Browser (XBAPs).
A diferencia de las aplicaciones tradicionales Windows o Web en WPF se
reduce enormemente la escritura del código en un lneguaje como Visual
Basic ya que se podría hacer la mayor parte usando solo XAML, es decir a
nivel de diseño. Además otras ventajas de WPF son la capacidad para
manejar multimedia, documentos, enlace de datos, graficos en 3D,
animaciones, etc.
Al inicio de este capítulo conoceremos los fundamentos de WPF: su
arquitectura, características y clasificación de controles, además veremos
como usar controles WPF creando aplicaciones Windows y Aplicaciones
para el Browser XAML (XBAPs).
Luego veremos todo lo relacionado al enlace de datos, desde como usar
controles para realizar enlace simple y complejo, cómo dar formato o
transformar los valores de los controles enlazados a datos, hasta usar
plantillas para personalizar la apariencia del control, inclusive como crear
plantillas jerárquicas. Además se incluye el control DataGrid.
En la tercera sección trataremos sobre el manejo de documentos en WPF,
presentaremos documentos fijos usando el DocumentViewer, crearemos
anotaciones y también trabajaremos con documentos dinámicos usando el
control FlowDocumentReader.
Por último, aprenderemos como incorporar la funcionalidad de multimedia
en nuestras aplicaciones WPF, desde incluir voz hasta reproducir audio y
video usando el control MediaElement.
Luis Dueñas Pag 594
La Biblia de Visual Basic .NET
1. Creando Aplicaciones Básicas en WPF
Iniciaremos este capítulo con una introducción a WPF, en la cual veremos
sus fundamentos: arquitectura, características y cómo se clasifican sus
controles.
Después aprenderemos a crear aplicaciones básicas en WPF tanto en
Windows como para el Explorador, ambas usan los mismos controles WPF,
la diferencia es que el contenedor de los controles en una aplicación
Windows WPF es el objeto Window y en el Explorador es el objeto Page.
Además en WPF para Windows las aplicaciones tienen plena confianza y
pueden ejecutar cualquier acción en el sistema, en cambio en WPF para el
Explorador (por defecto) solo tiene confianza parcial y no puede ejecutar
todas las acciones como usar diálogos.
También veremos como usar cuadros de diálogos, los cuales pueden ser
cuadros de mensajes, cuadros de diálogos comunes como abrir, guardar e
imprimir y cuadros de diálogos personalizados.
1.1. Introducción a WPF
Windows Presentations Foundation (WPF) es un modelo de programación
unificado para trabajar con aplicaciones de alto impacto visual que usen
gráficos, documentos, multimedia, etc. El núcleo de WPF es un motor de
representación independiente de la resolución y basado en vectores
construido para aprovechar al máximo el hardware de gráficos moderno.
Arquitectura de WPF
La arquitectura de WPF esta compuesta por un conjunto de 3 componentes
principales que son:
PresentationFramework: Es un componente manejado por el CLR que
se encarga de proveer los controles WPF.
Luis Dueñas Pag 595
La Biblia de Visual Basic .NET
PresentationCore: Es un componente manejado por el CLR que
contiene las características básicas de WPF.
Milcore: Es un componente No manejado por el CLR que permite la
integración con DirectX para manejar gráficos en 3D.
En el gráfico 6.1 se puede apreciar la arquitectura de los componentes que
forman parte de WPF.
Gráfico 6.1: Arquitectura de componentes de WPF
El espacio de nombres donde se encuentran la mayoría de clases de WPF
es: [Link], y las principales clases de WPF son las siguientes:
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
Luis Dueñas Pag 596
La Biblia de Visual Basic .NET
Para obtener más información sobre la Arquitectura de WPF ver la
referencia 36 al final del libro.
Características de WPF
Entre las principales características de WPF que lo diferencian de otros
componentes del .NET Framework como Windows Forms o Web Forms
tenemos:
Lenguaje de Marcado de Aplicaciones XML (XAML): Este permite en
forma declarativa mediante etiquetas (tags) realizar la presentación y el
trabajo con controles WPF, minimizando el uso de un lenguaje de
programación .NET.
Tipos de Aplicaciones WPF: Se pueden crear aplicaciones Windows
independientes (exe) basadas en ventanas, o aplicaciones que se
ejecutan en un explorador (Browser) conocidas como XBAPs que son
siglas de XAML Browser Applications.
Controles Integrados: Sin importar el tipo de aplicación WPF, los
controles están disponibles para ambos tipos de aplicaciones.
Enlace de Datos: WPF disponde de un nuevo modelo de enlace de
datos que permite enlazar cualquier origen de datos a un control o
destino de enlace.
Gráficos: WPF permite crear gráficos independientes de la resolución,
con presición mejorada, gráficos avanzados en 2D y 3D.
Animación: También podemos crear animaciones de forma simple,
podemos animar alguna propiedad de un control.
Multimedia: Con WPF podemos aprovechar reproducir voz mediante la
librería Speech, o reproducir audio y video mediante el control
MediaElement.
Documentos: WPF permite trabajar con 3 tipos de documentos que son
documentos de flujo, documentos fijos y documentos de XML Paper
Luis Dueñas Pag 597
La Biblia de Visual Basic .NET
Specification (XPS). Además podemos crear anotaciones sobre dichos
documentos.
Estilos y Plantillas: Ambos permiten cambiar la apariencia de un control
para simplificar el diseño de una aplicación WPF.
Recursos: Podemos definir una sección donde se encuentren
elementos reusables como por ejemplo estilos, plantillas, etc.
Clasificación de Controles WPF
Los controles WPF los podemos clasificar en:
Botones: Button y RepeatButton.
Cuadros de diálogo: OpenFileDialog, PrintDialog y SaveFileDialog.
Entradas manuscritas digitales: InkCanvas y InkPresenter.
Documentos: DocumentViewer, FlowDocumentPageViewer, Flow
DocumentReader, FlowDocumentScrollViewer y StickyNoteControl.
Entrada: TextBox, RichTextBox y PasswordBox.
Diseño: Border, BulletDecorator, Canvas, DockPanel, Expander, Grid,
GridView, GridSplitter, GroupBox, Panel, ResizeGrip, Separator,
ScrollBar, ScrollViewer, StackPanel, Thumb, Viewbox, Virtualizing
StackPanel, Window y WrapPanel.
Multimedia: Image, MediaElement y SoundPlayerAction.
Menús: ContextMenu, Menu y ToolBar.
Navegación: Frame, Hyperlink, Page, NavigationWindow y TabControl.
Selección: CheckBox, ComboBox, ListBox, TreeView y RadioButton,
Slider.
Información para el usuario: AccessText, Label, Popup, ProgressBar,
StatusBar, TextBlock y ToolTip.
Luis Dueñas Pag 598
La Biblia de Visual Basic .NET
1.2. Trabajando con Ventanas
Al crear aplicaciones WPF para Windows se crea por defecto una clase
window o ventana sobre la cual se realiza el diseño usando un contenedor
principal, por defecto el Grid y Controles WPF.
Las ventanas tienen propiedades comunes como “Title” que indica el texto
a mostrar en la barra de titulo, “ResizeMode” que indica si la ventana es
modificable o no, “WindowStartupLocation” que especifica la ubicación
donde se mostrará la ventana o “WindowState” que especifica si se
mostrará maximizada, minimizada o normal.
Para navegar entre ventanas se usa los métodos Show y ShowDialog, el
primero muestra la ventana como no modal y el segundo como modal, es
decir el segundo como diálogo.
Por su parte el diseño sobre la ventana tiene que realizarse sobre un
contenedor que por defecto es el Grid, sobre el cual se pueden definir filas
y columnas para realizar un mejor diseño y sobre estas celdas ubicar los
controles WPF.
También existen otros contenedores para agrupar controles como
StackPanel que agrupa en forma vertical, DockPanel que agrupa en forma
horizontal, WrapPanel que agrupa en forma consecutiva y va bajando, etc.
Finalmente, para programar se hace sobre eventos de la ventana o de los
controles, en el caso de la ventana sus principales eventos son: “Loaded”
que ocurre cuando carga la ventana, Closing que ocurre cuando se está
cerrando, “Closed” cuando ya se cerró y “Unloaded” cuando se descargó.
Todo procedimiento manejador de eventos en WPF debe tener 2
parámetros: sender de tipo [Link] y e de tipo [Link].
RoutedEventArgs.
Para obtener más información sobre ventanas de WPF ver la referencia 37
al final del libro.
A continuación una aplicación WPF para Windows que tiene 2 ventanas, la
primera permite registrar los datos del alumno en un archivo de texto:
Nombre, FechaNac, Sexo y Distrito; mientras la segunda permite listar los
Luis Dueñas Pag 599
La Biblia de Visual Basic .NET
alumnos registrados en un ListView de 4 columnas usando para el llenado
una clase de entidad llamada beAlumno.
Demo 85
Crear una nueva aplicación WPF para Windows: del menú “File”,
seleccionar “New Project”.
En el diálogo elegir “Visual Basic”, luego “Windows”, seleccionar “WPF
Application” similar al diálogo mostrado en la figura 6.2.
Gráfico 6.2: Diálogo de crear nueva aplicación WPF Windows
Escribir en el nombre de la aplicación “Demo85” y clic en “OK”.
Por defecto se crearán 2 archivos xaml: “[Link]” y “Main
[Link]”
Nota: El primero contiene la definición de los espacios de nombre usados
por WPF y cual es la ventana (archivo xaml) que inicia, que por defecto es
“[Link]”.
Cambiar de nombre a la ventana “[Link]” por “Ficha
[Link]”.
Luis Dueñas Pag 600
La Biblia de Visual Basic .NET
Escribir el siguiente código en el archivo xaml:
<Window x:Class="FichaAlumno"
xmlns="[Link]
xmlns:x="[Link]
Title="Aplicación WPF Windows de Alumnos" Height="300" Width="350"
WindowStartupLocation="CenterScreen" ResizeMode="NoResize">
<Grid>
<[Link]>
<LinearGradientBrush>
<GradientStop Color="Aqua" Offset="1"/>
<GradientStop Color="Blue" Offset="0.5"/>
</LinearGradientBrush>
</[Link]>
<[Link]>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="120"/>
<ColumnDefinition Width="50*"/>
</[Link]>
<[Link]>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="60"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30*"/>
</[Link]>
<Label Name="lblTitulo" [Link]="1" [Link]="1"
[Link]="2" Content="Ficha de Registro del Alumno"
HorizontalAlignment="Center" Foreground="White" FontSize="16"/>
<Label Name="lblNombre" [Link]="2" [Link]="1"
Content="Nombre:" Foreground="White"
VerticalAlignment="Center" />
<TextBox Name="txtNombre" [Link]="2" [Link]="2"
Width="100" Height="20"
HorizontalAlignment="Left"/>
<Label Name="lblFechaNac" [Link]="3" [Link]="1"
Content="Fecha Nac:" Foreground="White"
Luis Dueñas Pag 601
La Biblia de Visual Basic .NET
HorizontalAlignment="Left" VerticalAlignment="Center"/>
<DatePicker Name="dpFechaNac" [Link]="3" [Link]="2"
Width="100" HorizontalAlignment="Left"/>
<Label Name="lblSexo" [Link]="4" [Link]="1"
Content="Sexo:" Foreground="White"
HorizontalAlignment="Left" VerticalAlignment="Center"/>
<Grid [Link]="4" [Link]="2"
HorizontalAlignment="Left" VerticalAlignment="Center">
<[Link]>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="100"/>
</[Link]>
<[Link]>
<RowDefinition Height="20"/>
<RowDefinition Height="20"/>
</[Link]>
<RadioButton Name="rbMasculino" [Link]="0"
[Link]="0" Height="20"/>
<TextBlock Name="lblMasculino" [Link]="0"
[Link]="1" Height="20" Foreground="White">
Masculino</TextBlock>
<RadioButton Name="rbFemenino" [Link]="1"
[Link]="0" Height="20"/>
<TextBlock Name="lblFemenino" [Link]="1"
[Link]="1" Height="20" Foreground="White">
Femenino</TextBlock>
</Grid>
<Label Name="lblDistrito" [Link]="5" [Link]="1"
Content="Distrito:" Foreground="White"
HorizontalAlignment="Left" VerticalAlignment="Center"/>
<ComboBox Name="cboDistrito" [Link]="5" [Link]="2"
HorizontalAlignment="Left" Width="120" Height="20"/>
<DockPanel [Link]="6" [Link]="1" [Link]="2"
HorizontalAlignment="Center">
<Button Name="btnRegistrar"
Content="Registrar" Cursor="Hand" Width="80" Height="25"
ToolTip="Grabar los datos del Alumno"/>
<Button Name="btnListar"
Content="Listar" Cursor="Hand" Width="80" Height="25"
ToolTip="Visualiza un diálogo con la lista de alumnos"/>
Luis Dueñas Pag 602
La Biblia de Visual Basic .NET
</DockPanel>
</Grid>
</Window>
Nota: En el código anterior se define un fondo azul lineal degradado para
el Grid y también se definen 4 columnas y 8 filas sobre las cuales se ubican
los controles WPF.
El diseño de la ventana debe quedar como se muestra en el gráfico 6.3.
Gráfico 6.3: Diseño de la ventana Ficha del Alumno
Insertar un archivo de texto para definir los distritos: del menú
“Project”, seleccionar “Add New Item”, en la categoría “General”,
seleccionar “Text File” y escribir como nombre: “[Link]”.
Ingresar los Distritos en cada línea del archivo, por ejemplo: Ate,
Barranco, Comas, Chorrillos, Miraflores, Pueblo Libre, San Isidro, SJL,
San Miguel y Otros.
Escribir el siguiente código en el archivo vb asociado al xaml:
Imports [Link]
Class FichaAlumno
Private Ruta As String = "C:\Data\DemosLibro\LibroVB2010\Demo85\"
Private Sub ListarDistritos(ByVal sender As [Link], _
Luis Dueñas Pag 603
La Biblia de Visual Basic .NET
ByVal e As [Link]) Handles [Link]
Dim Archivo As String = Ruta + "[Link]"
If [Link](Archivo) Then
Dim Distritos() As String = [Link](Archivo)
[Link] = Distritos
End If
End Sub
Private Sub RegistrarAlumno(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If [Link] <> "" Then
If [Link] IsNot Nothing Then
If [Link] OrElse [Link] Then
If [Link] > -1 Then
Using sw As New StreamWriter(Ruta + "[Link]", True)
[Link]("{0},{1},{2},{3}", _
[Link], [Link]("{0:d}", _
[Link]), _
If([Link], "Masculino", "Femenino"), _
[Link])
End Using
[Link]()
[Link] = Nothing
[Link] = False
[Link] = False
[Link] = -1
Else
[Link]("Selecciona el Distrito")
[Link]()
End If
Else
[Link]("Selecciona el Sexo")
End If
Else
[Link]("Selecciona la Fecha")
[Link]()
End If
Else
[Link]("Ingresa el Nombre")
[Link]()
Luis Dueñas Pag 604
La Biblia de Visual Basic .NET
End If
End Sub
Private Sub MostrarDialogoListar(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim oLista As New ListaAlumnos
[Link]()
End Sub
End Class
Nota: En el código anterior al cargar la ventana se verifica si existe el
archivo “[Link]” y si es así se lee todas sus líneas y se enlaza al
combo de distritos. Además para registrar el alumno en el archivo de texto
“[Link]” es necesario ingresar todos los datos.
Agregar otra ventana al proyecto: del menú “Project”, seleccionar “Add
Window”, escribir como nombre: “[Link]” y click en “Add”.
Escribir el siguiente código en el archivo xaml:
<Window x:Class="ListaAlumnos"
xmlns="[Link]
xmlns:x="[Link]
Title="Lista de Alumnos Registrados" Height="300" Width="430"
WindowStartupLocation="CenterScreen" ResizeMode="NoResize">
<Grid>
<ListView Name="lvwAlumno">
<[Link]>
<RadialGradientBrush>
<GradientStop Color="orange" Offset="1"/>
<GradientStop Color="yellow" Offset="0.5"/>
</RadialGradientBrush>
</[Link]>
<[Link]>
<GridView>
<GridViewColumn Header="Nombre" Width="100"
DisplayMemberBinding="{Binding Path=Nombre}"/>
<GridViewColumn Header="Fecha Nac" Width="100"
DisplayMemberBinding="{Binding Path=FechaNac}"/>
<GridViewColumn Header="Sexo" Width="100"
DisplayMemberBinding="{Binding Path=Sexo}"/>
Luis Dueñas Pag 605
La Biblia de Visual Basic .NET
<GridViewColumn Header="Distrito" Width="100"
DisplayMemberBinding="{Binding Path=Distrito}"/>
</GridView>
</[Link]>
</ListView>
</Grid>
</Window>
Nota: En el código anterior se define un fondo radial naranja para el Grid y
se agrega un ListView con 4 columnas enlazadas a una entidad.
El diseño de la ventana debe quedar como se muestra en el gráfico 6.4.
Gráfico 6.4: Diseño de la ventana Lista de Alumnos
Agregar una clase entidad para los alumnos: del menú “Project”,
seleccionar “Add Class”, escribir como nombre: “beAlumno” y “Add”.
Escribir el siguiente código en la clase beAlumno:
Public Class beAlumno
Public Property Nombre As String
Public Property FechaNac As String
Public Property Sexo As String
Public Property Distrito As String
End Class
Cerrar la ventana de la clase y regresar a la ventana Lista de Alumnos.
Luis Dueñas Pag 606
La Biblia de Visual Basic .NET
Escribir el siguiente código en el archivo vb asociado al archivo
“[Link]”:
Imports [Link]
Public Class ListaAlumnos
Private Sub LeerArchivo(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim Archivo As String = _
"C:\Data\DemosLibro\LibroVB2010\Demo85\[Link]"
If [Link](Archivo) Then
Dim Alumnos() As String = [Link](Archivo)
Dim Alumno() As String
Dim obeAlumno As beAlumno
For I = 0 To [Link] - 1
obeAlumno = New beAlumno
Alumno = Alumnos(I).Split(",")
[Link] = Alumno(0)
[Link] = Alumno(1)
[Link] = Alumno(2)
[Link] = Alumno(3)
[Link](obeAlumno)
Next
End If
End Sub
End Class
Nota: En el código anterior al cargar la ventana se verifica si existe el
archivo “[Link]” y si es así se lee todas sus líneas y se recorre cada
línea para llenar el objeto obeAlumno y agregarlo al ListView.
Regresar a la ventana “[Link]” y cambiar la ventana que
inicia (atributo StartupUri) a “[Link]”.
Grabar y luego ejecutar la aplicación pulsando F5.
Se mostrará una ventana similar al de la figura 6.5.
Luis Dueñas Pag 607
La Biblia de Visual Basic .NET
Gráfico 6.5: Ejecución de la ventana Ficha del Alumno
Clic al botón “Registrar” para ver que se active la validación, luego
registrar varios alumnos.
Finalmente, clic al botón “Listar” para ver todos los alumnos registrados
Gráfico 6.6: Ejecución de la ventana Lista de Alumnos
Luis Dueñas Pag 608
La Biblia de Visual Basic .NET
1.3. Trabajando con Páginas
Al crear aplicaciones WPF del Explorador XAML o XBAP se crea por defecto
una clase page o página sobre la cual se realiza el diseño usando un
contenedor principal, por defecto el Grid y Controles WPF.
Las aplicaciones WPF del Explorador XAML se pueden alojar solo en
Microsoft Internet Explorer a partir de la versión 6, pero también en
contenedores de navegación alternativos:
Frame, para hospedar islas de contenido navegable en páginas o
ventanas.
NavigationWindow, para hospedar contenido navegable en una ventana
completa.
Los controles WPF para las páginas son los mismos que para una ventana,
la diferencia principal es que desde una aplicación WPF XBAP por defecto
no se puede ejecutar cualquier acción como en Windows, ya que tiene solo
confianza parcial. Si deseamos que pueda trabajar con diálogos, archivos,
el registro de Windows, etc hay que darle plena confianza al ensamblado.
La otra diferencia al programar con páginas es que no existen los eventos
“Closing” y “Closed” que son exclusivos de la ventana, solo el “Loaded” y
“Unloaded”.
Para navegar entre páginas existe la clase NavigationService que tiene el
método “Navigate” para ir a una determinada página, los métodos
“GoBack” para retroceder y “GoForward” para avanzar a la siguiente
página, además de propiedades para validar el avance como “CanGoBack”,
“CanGoForward” y “CurrentSource” que devuelve la URI de la última página
navegada.
Para obtener más información sobre navegación ver la referencia 38 al final
del libro.
A continuación, un ejemplo basado en el demo anterior de Registro y Lista
de Alumnos pero esta vez como una aplicación del explorador XAML o
XBAP, en donde aprenderemos cómo navegar entre páginas y cómo
configurar la seguridad de la aplicación XBAP para darle confianza total.
Luis Dueñas Pag 609
La Biblia de Visual Basic .NET
Demo 86
Crear una nueva aplicación WPF del Explorador XAML: del menú “File”,
seleccionar “New Project”.
En el diálogo elegir “Visual Basic”, luego “Windows”, seleccionar “WPF
Browser Application” similar al diálogo mostrado en la figura 6.7.
Gráfico 6.7: Diálogo de crear nueva aplicación WPF del Navegador
Escribir en el nombre de la aplicación “Demo86” y clic en “OK”.
Se crearán 2 archivos xaml: “[Link]” y “[Link]”
Cambiar de nombre a la página “[Link]” por “[Link]”.
Copiar todo lo que está dentro de la sección Grid de la ventana
[Link] del demo anterior a la sección grid de la página:
<Page x:Class="FichaAlumno"
xmlns="[Link]
xmlns:x="[Link]
xmlns:mc="[Link]
compatibility/2006"
Luis Dueñas Pag 610
La Biblia de Visual Basic .NET
xmlns:d="[Link]
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400"
Title=" Aplicación WPF del Explorador">
<Grid>
<[Link]>
<LinearGradientBrush>
<GradientStop Color="Aqua" Offset="1"/>
<GradientStop Color="Blue" Offset="0.5"/>
</LinearGradientBrush>
</[Link]>
<[Link]>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="120"/>
<ColumnDefinition Width="50*"/>
</[Link]>
<[Link]>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="60"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30*"/>
</[Link]>
<Label Name="lblTitulo" [Link]="1" [Link]="1"
[Link]="2"
Content="Ficha de Registro del Alumno"
HorizontalAlignment="Center"
Foreground="White" FontSize="16"/>
<Label Name="lblNombre" [Link]="2" [Link]="1"
Content="Nombre:" Foreground="White"
VerticalAlignment="Center" />
<TextBox Name="txtNombre" [Link]="2" [Link]="2"
Width="100" Height="20"
HorizontalAlignment="Left"/>
<Label Name="lblFechaNac" [Link]="3" [Link]="1"
Content="Fecha Nac:" Foreground="White"
Luis Dueñas Pag 611
La Biblia de Visual Basic .NET
HorizontalAlignment="Left" VerticalAlignment="Center"/>
<DatePicker Name="dpFechaNac" [Link]="3" [Link]="2"
Width="100" HorizontalAlignment="Left"/>
<Label Name="lblSexo" [Link]="4" [Link]="1"
Content="Sexo:" Foreground="White"
HorizontalAlignment="Left" VerticalAlignment="Center"/>
<Grid [Link]="4" [Link]="2" HorizontalAlignment="Left"
VerticalAlignment="Center">
<[Link]>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="100"/>
</[Link]>
<[Link]>
<RowDefinition Height="20"/>
<RowDefinition Height="20"/>
</[Link]>
<RadioButton Name="rbMasculino" [Link]="0"
[Link]="0" Height="20"/>
<TextBlock Name="lblMasculino" [Link]="0"
[Link]="1" Height="20" Foreground="White">
Masculino</TextBlock>
<RadioButton Name="rbFemenino"
[Link]="1" [Link]="0" Height="20"/>
<TextBlock Name="lblFemenino" [Link]="1"
[Link]="1" Height="20" Foreground="White">
Femenino</TextBlock>
</Grid>
<Label Name="lblDistrito" [Link]="5" [Link]="1"
Content="Distrito:" Foreground="White"
HorizontalAlignment="Left" VerticalAlignment="Center"/>
<ComboBox Name="cboDistrito" [Link]="5" [Link]="2"
HorizontalAlignment="Left" Width="120" Height="20"/>
<DockPanel [Link]="6" [Link]="1" [Link]="2"
HorizontalAlignment="Center">
<Button Name="btnRegistrar"
Content="Registrar" Cursor="Hand" Width="80" Height="25"
ToolTip="Grabar los datos del Alumno"/>
<Button Name="btnListar"
Content="Listar" Cursor="Hand" Width="80" Height="25"
ToolTip="Visualiza una pagina con la lista de alumnos registrados"/>
Luis Dueñas Pag 612
La Biblia de Visual Basic .NET
</DockPanel>
</Grid>
</Page>
Nota: En realidad con respecto al demo anterior solo ha cambiado el título
de la página y el Tooltip del botón Listar.
El diseño de la página debe quedar como se muestra en el gráfico 6.8.
Gráfico 6.8: Diseño de la página Ficha del Alumno
Agregar el archivo de texto [Link] y la clase de entidad
[Link] creadas en el demo anterior al proyecto actual.
Escribir el siguiente código en el archivo vb asociado al xaml:
Imports [Link]
Class FichaAlumno
Private Ruta As String = "C:\Data\DemosLibro\LibroVB2010\Demo86\"
Private Sub ListarDistritos(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim Archivo As String = Ruta + "[Link]"
If [Link](Archivo) Then
Dim Distritos() As String = [Link](Archivo)
[Link] = Distritos
Luis Dueñas Pag 613
La Biblia de Visual Basic .NET
End If
End Sub
Private Sub RegistrarAlumno(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
If [Link] <> "" Then
If [Link] IsNot Nothing Then
If [Link] OrElse [Link] Then
If [Link] > -1 Then
Using sw As New StreamWriter(Ruta + "[Link]", True)
[Link]("{0},{1},{2},{3}", _
[Link], [Link]("{0:d}", _
[Link]), _
If([Link], "Masculino", "Femenino"), _
[Link])
End Using
[Link]()
[Link] = Nothing
[Link] = False
[Link] = False
[Link] = -1
Else
[Link]("Selecciona el Distrito")
[Link]()
End If
Else
[Link]("Selecciona el Sexo")
End If
Else
[Link]("Selecciona la Fecha")
[Link]()
End If
Else
[Link]("Ingresa el Nombre")
[Link]()
End If
End Sub
Private Sub MostrarPaginaListar(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Luis Dueñas Pag 614
La Biblia de Visual Basic .NET
Dim oLista As New ListaAlumnos
[Link](New ListaAlumnos, [Link])
End Sub
End Class
Nota: En el código anterior solo ha cambiado la ruta del archivo a Demo86
y el procedimiento manejador de eventos “MostrarPaginaListar” para
navegar a la otra página usando el método Navigate de la clase Navigation
Service.
Agregar otra página al proyecto: del menú “Project”, seleccionar “Add
Page”, escribir como nombre: “[Link]” y click en “Add”.
Copiar todo lo que está dentro de la sección Grid de la ventana
[Link] del demo anterior a la sección grid de la nueva
página y aumentar al final un botón para regresar a la página anterior:
<Page x:Class="ListaAlumnos"
xmlns="[Link]
xmlns:x="[Link]
xmlns:mc="[Link]
compatibility/2006"
xmlns:d="[Link]
mc:Ignorable="d"
d:DesignHeight="350" d:DesignWidth="400"
Title="ListaAlumnos">
<[Link]>
<RadialGradientBrush>
<GradientStop Color="orange" Offset="1"/>
<GradientStop Color="yellow" Offset="0.5"/>
</RadialGradientBrush>
</[Link]>
<Grid>
<[Link]>
<RowDefinition Height="300"/>
<RowDefinition Height="30"/>
</[Link]>
<ListView Name="lvwAlumno" Height="300"
VerticalAlignment="Top">
<[Link]>
<RadialGradientBrush>
Luis Dueñas Pag 615
La Biblia de Visual Basic .NET
<GradientStop Color="orange" Offset="1"/>
<GradientStop Color="yellow" Offset="0.5"/>
</RadialGradientBrush>
</[Link]>
<[Link]>
<GridView>
<GridViewColumn Header="Nombre" Width="100"
DisplayMemberBinding="{Binding Path=Nombre}"/>
<GridViewColumn Header="Fecha Nac" Width="100"
DisplayMemberBinding="{Binding Path=FechaNac}"/>
<GridViewColumn Header="Sexo" Width="100"
DisplayMemberBinding="{Binding Path=Sexo}"/>
<GridViewColumn Header="Distrito" Width="100"
DisplayMemberBinding="{Binding Path=Distrito}"/>
</GridView>
</[Link]>
</ListView>
<Button Name="lblRegresar" Foreground="Blue" Content="Regresar"
[Link]="1" HorizontalAlignment="Center">
</Button>
</Grid>
</Page>
Nota: En realidad con respecto al demo anterior solo ha cambiado el alto y
ancho de la página y ha aumentado el botón para Regresar.
El diseño de la página debe quedar como se muestra en el gráfico 6.9.
Luis Dueñas Pag 616
La Biblia de Visual Basic .NET
Gráfico 6.9: Diseño de la página Lista de Alumnos
Escribir el siguiente código en el archivo vb asociado al archivo
“[Link]”:
Imports [Link]
Class ListaAlumnos
Private Sub LeerArchivo(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim Archivo As String = _
"C:\Data\DemosLibro\LibroVB2010\Demo86\[Link]"
If [Link](Archivo) Then
Dim Alumnos() As String = [Link](Archivo)
Dim Alumno() As String
Dim obeAlumno As beAlumno
For I = 0 To [Link] - 1
obeAlumno = New beAlumno
Alumno = Alumnos(I).Split(",")
[Link] = Alumno(0)
[Link] = Alumno(1)
[Link] = Alumno(2)
[Link] = Alumno(3)
[Link](obeAlumno)
Next
Luis Dueñas Pag 617
La Biblia de Visual Basic .NET
End If
End Sub
Private Sub RegresarPaginaAnterior(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link]()
End Sub
End Class
Nota: En realidad con respecto al demo anterior solo ha cambiado la ruta
del archivo a Demo86 y ha aumentado el código para regresar a la página
anterior.
Regresar a la ventana “[Link]” y cambiar la página que inicia
(atributo StartupUri) a “[Link]”.
Nota: Antes de ejecutar la aplicación debemos configurar la seguridad de
la aplicación WPF para el Browser cambiándola de confianza parcial a plena
confianza, sino al ejecutar ocurrirá un error al leer y escribir en archivos.
Clic derecho sobre el nombre del proyecto y del menú contextual elegir
“Properties”.
Aparecerá la ventana de propiedades, seleccionar la ficha “Security”
Gráfico 6.10: Ficha Seguridad de la ventana de propiedades
Luis Dueñas Pag 618
La Biblia de Visual Basic .NET
Cambiar la seguridad eligiendo la primera opción en vez de la segunda:
“This is a full trust application”, luego cerrar la ventana.
Grabar y luego ejecutar la aplicación pulsando F5.
Se mostrará una página similar al de la figura 6.11.
Gráfico 6.11: Ejecución de la página Ficha del Alumno
Clic al botón “Registrar” para ver que se active la validación, luego
registrar algunos alumnos.
Ahora, clic al botón “Listar” para ver todos los alumnos registrados
Luis Dueñas Pag 619
La Biblia de Visual Basic .NET
Gráfico 6.12: Ejecución de la página Lista de Alumnos
Finalmente, clic al botón “Regresar” para ir a la página anterior.
Luis Dueñas Pag 620
La Biblia de Visual Basic .NET
1.4. Usando Cuadros de Diálogo
En WPF las aplicaciones Windows se componen de una ventana principal
pero a veces se requieren más de una ventana o ventanas secundarias a
las cuales se les denomina cuadros de diálogo.
Los cuadros de diálogo pueden ser de 2 tipos: modales y no modales; los
cuadros de diálogo modales necesitan cerrarse para seguir trabajando con
la ventana principal, en cambio, los cuadros de diálogo no modales no, se
puede seguir trabajando con la ventana principal una vez abierto (no es
necesario cerrar).
WPF permite crear 3 tipos de cuadros de diálogo: cuadros de mensaje,
cuadros de diálogo comunes de Windows y cuadros personalizados por el
usuario. En este tema nos centraremos en los cuadros de diálogos
comunes de Windows, entre los cuales tenemos: abrir, guardar e imprimir.
Para usar los cuadros de diálogo de archivo es necesario usar el espacio de
nombres Microsoft.Win32 los cuales tienen las clases OpenFileDialog para
manejar el diálogo de abrir archivo y SaveFileDialog para manejar el
diálogo de guardar archivo.
Ambos diálogos tienen el método ShowDialog que muestra el diálogo y
devuelve un valor lógico que es True en el caso que el usuario acepte la
operación de abrir o guardar o False si el usuario cancela la operación.
Por su parte para usar el diálogo de Imprimir se usa la clase PrintDialog
que se encuentra en [Link], es decir forma parte de los
controles de WPF. Esta clase tiene el método ShowDialog para mostrar el
diálogo y el método PrintVisual que permite imprimir el contenido de
cualquier control, es decir un gráfico.
Para obtener más información sobre cuadros de diálogo ver la referencia
39 al final del libro.
A continuación, un ejemplo de una aplicación Windows WPF que es un
Editor de Textos que tiene un Menú con 4 opciones: nuevo, abrir, guardar
e imprimir textos escritos sobre un RichTextBox. Aquí se usan los cuadros
de diálogo comunes de Windows.
Luis Dueñas Pag 621
La Biblia de Visual Basic .NET
Demo 87
Crear una nueva aplicación Windows WPF: del menú “File”, seleccionar
“New Project”.
En el diálogo elegir “Visual Basic”, luego “Windows”, seleccionar “WPF
Application”.
Escribir en el nombre de la aplicación “Demo87” y clic en “OK”.
Cambiar de nombre a la ventana “[Link]” por “[Link]”.
Escribir el siguiente código en el archivo xaml:
<Window x:Class="Editor"
xmlns="[Link]
xmlns:x="[Link]
Title="Editor de Textos WPF" Height="300" Width="350"
WindowState="Maximized">
<Grid>
<[Link]>
<RowDefinition Height="30"/>
<RowDefinition Height="300*"/>
</[Link]>
<Menu Name="mnuEditor" [Link]="0"
[Link]="SeleccionaOpcion" />
<RichTextBox Name="txtEditor" [Link]="1"
VerticalScrollBarVisibility="Visible" />
</Grid>
</Window>
Nota: En el código anterior se definen 2 filas sobre las cuales se ubican los
controles WPF Menu y RichTextBox, el menú tiene asociado un
procedimiento manejador de eventos al dar clic en cada opción.
El diseño de la ventana debe quedar como se muestra en el gráfico
6.13.
Luis Dueñas Pag 622
La Biblia de Visual Basic .NET
Gráfico 6.13: Diseño de la ventana Editor de Textos WPF
Escribir código en el archivo vb asociado al xaml:
Imports Microsoft.Win32 'OpenFileDialog, SaveFileDialog
Imports [Link]
Class Editor
Private Sub CrearOpcionesMenu(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link]("Nuevo")
[Link]("Abrir")
[Link]("Guardar")
[Link]("Imprimir")
End Sub
Private Sub SeleccionaOpcion(ByVal sender As [Link], _
ByVal e As [Link])
Dim mnuOpcion As MenuItem = [Link]
If [Link] = "Nuevo" Then
[Link]()
[Link] = ""
ElseIf [Link] = "Abrir" Then
Dim ofd As New OpenFileDialog
[Link] = "Abrir un archivo de texto"
[Link] = "Archivos de texto|*.txt"
If [Link] = True Then
Luis Dueñas Pag 623
La Biblia de Visual Basic .NET
[Link] _
([Link]([Link]), "Text")
[Link] = [Link]([Link])
End If
ElseIf [Link] = "Guardar" Then
Dim sfd As New SaveFileDialog
[Link] = "Guardar un archivo de texto"
[Link] = "Archivos de texto|*.txt"
If [Link] = True Then
[Link]()
[Link] _
([Link]([Link]), "Text")
[Link] = [Link]([Link])
End If
ElseIf [Link] = "Imprimir" Then
Dim pd As New PrintDialog
If [Link]() = True Then
[Link](Me, "Mira esto")
End If
End If
End Sub
End Class
Nota: En el código anterior se agregan 4 opciones al menú al cargar la
ventana y al seleccionar una opción se evalua el texto de la cabecera de la
opción y de acuerdo al valor se realiza una acción.
Regresar a la ventana “[Link]” y cambiar la ventana que
inicia (atributo StartupUri) a “[Link]”.
Grabar y luego ejecutar la aplicación pulsando F5.
Se mostrará una ventana similar al de la figura 6.14.
Luis Dueñas Pag 624
La Biblia de Visual Basic .NET
Gráfico 6.14: Ejecución de la ventana Editor de Textos WPF
Probar cada opción del menú, sobre todo abrir, guardar e impimir y
observar como se presentan los diálogos comunes de Windows.
Realizar una prueba de impresión al seleccionar la opción Imprimir.
Nota: Si no tiene impresora conectada puede enviar la salida a un archivo
XPS, el cual después será usado al aprender como leer documentos XPS.
Luis Dueñas Pag 625
La Biblia de Visual Basic .NET
2. Usando Enlace de Datos
En esta parte veremos como WPF implementa el enlace de datos para
trabajar de forma simple la presentación de los datos almacenados en los
orígenes de datos sobre la IU mediante los controles enlazados a datos.
Una de las principales ventajas de WPF con respecto a Windows Forms o
ASP .NET es que el enlace de datos se encuentra disponible en la mayoría
de controles que pueden enlazarse a diferentes orígenes de datos, tales
como objetos del CLR por ejemplo Listas, objetos de ADO .NET como por
ejemplo DataTable, objetos XML, Servicios Web, etc.
Primero revisaremos qué es el enlace de datos y como nos ayuda a
simplificar el trabajo con los datos, para lo cual veremos primero como
trabajar sin enlace de datos usando la lectura y escritura de datos.
Luego en la segunda parte implementaremos el enlace de datos tanto
simple usando la propiedad DataContext y también el enlace complejo
usando la propiedad ItemsSource de los controles de listas como ListBox,
ComboBox, ListView, etc.
Como tercer tema aprenderemos a crear convertidores de datos
personalizados que ayuden a mejorar los datos que se presentan en los
controles enlazados usando para ello una clase que implemente la
interface de datos IValueConverter.
Finalmente, veremos como usar las plantillas de datos para mejorar el
diseño de los controles enlazados a datos y cambiar su aspecto por
defecto, por ejemplo en vez de que el ListBox o ComboBox presenten una
sola columna podemos crear una plantilla que permita crear varias
columnas y usarla en dichos controles de listas.
En este último tema también trataremos de las plantillas jerárquicas de
datos que permiten realizar la presentación de datos en varios niveles
sobre un control, por ejemplo en el TreeView para que muestre una tabla
dentro de otra como si fuera un TreeTable o TreeGrid.
Luis Dueñas Pag 626
La Biblia de Visual Basic .NET
2.1. Introducción al Enlace de Datos
Para trabajar con datos lo primero que se hace es obtener la data desde un
“Repositorio de Datos” como por ejemplo una base de datos, luego esta es
almacenada dentro de la aplicación en una estructura en memoria a la cual
se le denomina “Orígen de Datos” como por ejemplo un arreglo o lista de
objetos, finalmente estos datos deben presentarse en pantalla en la
Interface de Usuario (IU) sobre los controles.
Para realizar esta presentación de los datos existen 2 técnicas o
mecanismos:
Método Tradicional: Consiste en leer del origen de datos y escribir los
valores sobre los controles de la IU. Es una forma antigua de presentar
datos y hay que escribir demasiado código.
Método del Enlace de Datos (Data Binding): Consiste en crear una
conexión entre el origen de datos y los controles de la IU, de tal forma
que sea automática los cambios sobre el origen en la IU y viceversa.
Las ventajas de WPF con respecto al enlace de datos son:
Mayor cantidad de controles que permiten enlace de datos.
Mayor cantidad de propiedades que se pueden enlazar a datos.
Más orígenes de datos enlazables como arreglos, listas de objetos,
tablas, XML, servicios web, etc.
Intermediarios que realizan operaciones de ordenación, filtro y
navegación por los datos, tal como el CollectionView.
Uso de convertidores de datos, plantillas de datos y reglas de validación
de datos, etc.
Para obtener más información sobre el enlace de datos ver la referencia 40
al final del libro.
A continuación veremos un par de ejemplos de como trabajar de forma
tradicional para presentar los datos: primero una lista de datos y luego una
consulta simple de datos.
Luis Dueñas Pag 627
La Biblia de Visual Basic .NET
Demo 88
Crear una nueva aplicación Windows WPF: del menú “File”, seleccionar
“New Project”.
En el diálogo elegir “Visual Basic”, luego “Windows”, seleccionar “WPF
Application”.
Escribir en el nombre de la aplicación “Demo88” y clic en “OK”.
Hacer una referencia a las librerías [Link] y
[Link].
Cambiar de nombre a la ventana “[Link]” por “Lista
[Link]”.
Escribir el siguiente código en el archivo xaml:
<Window x:Class="ListaEmpleados"
xmlns="[Link]
xmlns:x="[Link]
Title="Leer y Escribir en un control Lista" Height="350" Width="350"
ResizeMode="NoResize" WindowStartupLocation="CenterScreen">
<Grid>
<ListBox Name="lstEmpleado">
<[Link]>
<ImageBrush ImageSource="C:\Data\DemosLibro\LibroVB2010\
Imagenes\JPG\Empleados\[Link]" Opacity="0.5"/>
</[Link]>
</ListBox>
</Grid>
</Window>
Nota: En el código anterior solo se incluye un control ListBox con un fondo
de imágen que esta semi transparente mediante la propiedad opacity.
El diseño de la ventana debe quedar como se muestra en el gráfico
6.15.
Luis Dueñas Pag 628
La Biblia de Visual Basic .NET
Gráfico 6.15: Diseño de la ventana Lista de Empleados
Escribir código en el archivo vb asociado al xaml:
Imports [Link]
Imports [Link]
Class ListaEmpleados
Private Sub ListarEmpleados(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim obrEmpleado As New brEmpleado
Dim lobeEmpleado As List(Of beEmpleado) = [Link]
For I = 0 To [Link] - 1
[Link]([Link]("{0} {1}", _
lobeEmpleado(I).Apellido, lobeEmpleado(I).Nombre))
Next
End Sub
End Class
Nota: En el código anterior al cargar la ventana se llena una lista de
objetos de tipo empleado y luego se recorre cada elemento de la lista para
mostrar el apellido y el nombre del empleado en el control ListBox.
Regresar a la ventana “[Link]” y cambiar la ventana que
inicia (atributo StartupUri) a “[Link]”.
Luis Dueñas Pag 629
La Biblia de Visual Basic .NET
Agregar un archivo de configuración a la aplicación: del menú “Project”,
seleccionar “Add New Item”, en la categoría “General” seleccionar
“Application Configuration File”.
Agregar en el archivo de configuración la clave conNW en la sección
appSettings:
<configuration>
<appSettings>
<add key="conNW" value="uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 6.16: Ejecución de la ventana Lista de Empleados
Luis Dueñas Pag 630
La Biblia de Visual Basic .NET
Demo 89
Crear una nueva aplicación Windows WPF: del menú “File”, seleccionar
“New Project”.
En el diálogo elegir “Visual Basic”, luego “Windows”, seleccionar “WPF
Application”.
Escribir en el nombre de la aplicación “Demo89” y clic en “OK”.
Hacer una referencia a las librerías [Link] y
[Link].
Cambiar de nombre a la ventana “[Link]” por “Consulta
[Link]”.
Escribir el siguiente código en el archivo xaml:
<Window x:Class="ConsultaEmpleados"
xmlns="[Link]
xmlns:x="[Link]
Title="Consulta de Empleados - Leer y Escribir" Height="350" Width="350"
WindowStartupLocation="CenterScreen" ResizeMode="NoResize">
<Grid>
<[Link]>
<ImageBrush ImageSource="C:\Data\DemosLibro\LibroVB2010\
Imagenes\JPG\Empleados\[Link]" Opacity="0.5"/>
</[Link]>
<[Link]>
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="100" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="30*" />
</[Link]>
<[Link]>
<ColumnDefinition Width="50" />
Luis Dueñas Pag 631
La Biblia de Visual Basic .NET
<ColumnDefinition Width="100" />
<ColumnDefinition Width="120" />
<ColumnDefinition Width="50*" />
</[Link]>
<Label Name="lblTitulo" [Link]="0" [Link]="1"
[Link]="2" Content="Consulta de Empleados"
FontSize="16" HorizontalAlignment="Center" />
<Label Name="lblCodigo" [Link]="1" [Link]="1"
VerticalAlignment="Center" Content="Codigo"
FontSize="12" HorizontalAlignment="Left" />
<TextBox Name="txtCodigo" [Link]="1" [Link]="2"
Width="50" Height="20" HorizontalAlignment="Left" />
<Label Name="lblApellido" [Link]="2" [Link]="1"
Content="Apellido" VerticalAlignment="Center"
FontSize="12" HorizontalAlignment="Left" />
<TextBox Name="txtApellido" [Link]="2" [Link]="2"
Width="100" Height="20" HorizontalAlignment="Left" />
<Label Name="lblNombre" [Link]="3" [Link]="1"
Content="Nombre" VerticalAlignment="Center"
FontSize="12" HorizontalAlignment="Left" />
<TextBox Name="txtNombre" [Link]="3" [Link]="2"
Width="100" Height="20" HorizontalAlignment="Left" />
<Label Name="lblFechaNac" [Link]="4" [Link]="1"
Content="Fecha Nac" VerticalAlignment="Center"
FontSize="12" HorizontalAlignment="Left" />
<DatePicker Name="dpFechaNac" [Link]="4" [Link]="2"
Width="100" Height="20" HorizontalAlignment="Left" />
<Label Name="lblFoto" [Link]="5" [Link]="1"
Content="Foto" VerticalAlignment="Center"
FontSize="12" HorizontalAlignment="Left" />
<Image Name="imgFoto" [Link]="5" [Link]="2"
VerticalAlignment="Center" Width="120" Height="100" />
<DockPanel [Link]="6" [Link]="1" [Link]="2"
HorizontalAlignment="Center">
<Button Name="btnPrimero" Content="<<" Width="35"
Height="25" Cursor="Hand" ToolTip="Ir al primer registro"/>
<Button Name="btnAnterior" Content="<" Width="35"
Height="25" Cursor="Hand" ToolTip="Ir al anterior registro"/>
<TextBox Name="txtPosicion" Width="80" Height="25"
IsReadOnly="True" HorizontalContentAlignment="Center"/>
Luis Dueñas Pag 632
La Biblia de Visual Basic .NET
<Button Name="btnSiguiente" Content=">" Width="35"
Height="25" Cursor="Hand" ToolTip="Ir al siguiente registro"/>
<Button Name="btnUltimo" Content=">>" Width="35"
Height="25" Cursor="Hand" ToolTip="Ir al último registro"/>
</DockPanel>
</Grid>
</Window>
Nota: En el código anterior se define 9 filas y 4 columnas en el Grid para
ubicar los controles: 3 textos para mostrar el código, apellido y nombre, un
datepicker para la fecha y un image para la foto. Además hay 4 botones
para realizar el desplazamiento de registro.
El diseño de la ventana debe quedar como se muestra en el gráfico
6.17.
Gráfico 6.17: Diseño de la ventana Consulta de Empleados
Escribir código en el archivo vb asociado al xaml:
Imports [Link]
Imports [Link]
Imports [Link]
Class ConsultaEmpleados
Private lobeEmpleado As New List(Of beEmpleado)
Luis Dueñas Pag 633
La Biblia de Visual Basic .NET
Private N As Integer
Private Function ObtenerImagen(ByVal Codigo As Integer) As String
Dim Ruta As String = _
"C:\Data\DemosLibro\LibroVB2010\Imagenes\JPG\Empleados\"
Dim Archivo As String = [Link]("{0}{1}.jpg", Ruta, Codigo)
If Not [Link](Archivo) Then _
Archivo = [Link]("{0}[Link]", Ruta)
Return (Archivo)
End Function
Private Sub MostrarEmpleado()
[Link] = lobeEmpleado(N).Codigo
[Link] = lobeEmpleado(N).Apellido
[Link] = lobeEmpleado(N).Nombre
[Link] = lobeEmpleado(N).FechaNac
[Link] = New BitmapImage _
(New Uri(ObtenerImagen(lobeEmpleado(N).Codigo)))
[Link] = [Link]("{0} de {1}", N + 1, _
[Link])
End Sub
Private Sub CargarEmpleados(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim obrEmpleado As New brEmpleado
lobeEmpleado = [Link]
MostrarEmpleado()
End Sub
Private Sub IrAlPrimerRegistro(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
N=0
MostrarEmpleado()
End Sub
Private Sub IrAnteriorRegistro(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If N > 0 Then N = N - 1
MostrarEmpleado()
End Sub
Luis Dueñas Pag 634
La Biblia de Visual Basic .NET
Private Sub IrSiguienteRegistro(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
If N < [Link] - 1 Then N = N + 1
MostrarEmpleado()
End Sub
Private Sub IrUltimoRegistro(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
N = [Link] - 1
MostrarEmpleado()
End Sub
End Class
Nota: En el código anterior al cargar la ventana se llena la lista de objetos
y se llama a la subrutina MostrarEmpleado que presenta los datos de un
registro incluyendo la foto para lo cual se usa un índice del registro que
deseamos presentar, cada vez que usamos los botones de desplazamiento
se cambia el índice al registro que queremos mostrar.
Importante: Para cargar la foto en el control image se asigna a la
propiedad Source del image a un objeto BitmapImage el cual debe pasar la
URI con la ruta del archivo de imagen, para esto se usa la función Obtener
Imagen que permite asignar el archivo [Link] a los códigos que no tengan
su archivo correspondiente.
Regresar a la ventana “[Link]” y cambiar la ventana que
inicia (atributo StartupUri) a “[Link]”.
Agregar un archivo de configuración a la aplicación: del menú “Project”,
seleccionar “Add New Item”, en la categoría “General” seleccionar
“Application Configuration File”.
Agregar en el archivo de configuración la clave conNW en la sección
appSettings:
<configuration>
<appSettings>
<add key="conNW" value="uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind"/>
Luis Dueñas Pag 635
La Biblia de Visual Basic .NET
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 6.18: Ejecución de la ventana Consulta de Empleados
Luis Dueñas Pag 636
La Biblia de Visual Basic .NET
2.2. Usando Enlace de Datos
En este tema veremos como trabajar con enlace de datos entre los
controles WPF y el origen de datos, el cual generalmente será listas de
objetos en nuestro caso ya que las librerías de reglas de negocio devuelven
listas de objetos a la aplicación.
Existen dos tipos de enlaces: simple y complejo; el enlace simple
consiste en mostrar sobre el valor de una propiedad un dato enlazado por
ejemplo el valor de un campo de una fila o una propiedad de un objeto;
mientras que el enlace complejo podría mostrar varios valores de varias
columnas de una tabla o propiedades de una lista de objetos.
Para implementar el enlace complejo en WPF los controles de varias filas o
elementos como el ListBox, ComboBox, ListView, TreeView y DataGrid
tienen la propiedad ItemsSource que indica cual es su orígen de datos.
Los controles ListBox y ComboBox tienen las propiedades
DisplayMemberPath y SelectedValuePath donde se configura el nombre del
campo que se va a mostrar y guardar respectivamente.
Para implementar el enlace simple en WPF se configura la propiedad
DataContext del contenedor y luego en la propiedad respectiva de cada
control, por ejemplo Text para un TextBox, Content para un Label,
ImageSource para una imagen, etc, se realiza el enlace usando la clase
Binding con el atributo Path asignando el nombre del campo o propiedad.
Una vez enlazados los controles para realizar desplazamientos se puede
usar un intermediario de datos como el CollectionView que tiene
métodos como MoveCurrentToFirst para ir al primer registro, MoveCurrent
ToPrevious para regresar al anterior, MoveCurrentToNext para ir al
siguiente, MoveCurrentToLast para ir al último o MoveCurrentToPosition
para ir a cualquier posición. Además de un apr de propiedades que
verifican el desbordamiento: IsCurrentBeforeFirst y IsCurrentAfterLast.
Seguidamente presentaremos un par de ejemplos de cómo usar el enlace
de datos, el primero trata del enlace complejo en un control ListBox que
lista los nombres de los productos y el segundo muestra como implementar
el enlace simple en una consulta de productos.
Luis Dueñas Pag 637
La Biblia de Visual Basic .NET
Demo 90
Crear una nueva aplicación Windows WPF: del menú “File”, seleccionar
“New Project”.
En el diálogo elegir “Visual Basic”, luego “Windows”, seleccionar “WPF
Application”.
Escribir en el nombre de la aplicación “Demo90” y clic en “OK”.
Hacer una referencia a las librerías [Link] y
[Link].
Cambiar de nombre a la ventana “[Link]” por “Lista
[Link]”.
Escribir el siguiente código en el archivo xaml:
<Window x:Class="ListaProductos"
xmlns="[Link]
xmlns:x="[Link]
Title="Enlace de Datos - Lista de Productos" Height="350" Width="350"
ResizeMode="NoResize" WindowStartupLocation="CenterScreen">
<Grid>
<ListBox Name="lstProducto" Foreground="Blue"
DisplayMemberPath="Nombre" SelectedValuePath="Codigo">
<[Link]>
<ImageBrush ImageSource="C:\Data\DemosLibro\LibroVB2010\
Imagenes\JPG\Paisajes\[Link]" Opacity="0.5"/>
</[Link]>
</ListBox>
</Grid>
</Window>
Nota: En el código anterior solo se incluye un control ListBox con un fondo
de imágen que esta semi transparente mediante la propiedad opacity.
Además se configura las propiedades DisplayMemberPath para indicar que
se muestra el nombre del producto y SelectedValuePath para indicar que se
guarda el código del producto.
El diseño de la ventana debe quedar como se ve en el siguiente gráfico.
Luis Dueñas Pag 638
La Biblia de Visual Basic .NET
Gráfico 6.19: Diseño de la ventana Lista de Productos
Escribir código en el archivo vb asociado al xaml:
Imports [Link]
Imports [Link]
Class ListaProductos
Private Sub ListarProductos(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim obrProducto As New brProducto
Dim lobeProducto As List(Of beProducto) = [Link]
[Link] = lobeProducto
End Sub
Private Sub MostrarCodigo(ByVal sender As [Link], _
ByVal e As [Link]) _
Handles [Link]
[Link] = [Link]("El código es {0}", [Link])
End Sub
End Class
Nota: En el código anterior al cargar la ventana se llena la lista de objetos
de productos y se enlaza al control ListBox. Además cada vez que se
Luis Dueñas Pag 639
La Biblia de Visual Basic .NET
selecciona un producto de la lista se muestra en la barra de título de la
ventana el código seleccionado del producto.
Regresar a la ventana “[Link]” y cambiar la ventana que
inicia (atributo StartupUri) a “[Link]”.
Agregar un archivo de configuración a la aplicación: del menú “Project”,
seleccionar “Add New Item”, en la categoría “General” seleccionar
“Application Configuration File”.
Agregar en el archivo de configuración la clave conNW en la sección
appSettings:
<configuration>
<appSettings>
<add key="conNW" value="uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 6.20: Ejecución de la ventana Lista de Productos
Luis Dueñas Pag 640
La Biblia de Visual Basic .NET
Demo 91
Crear una nueva aplicación Windows WPF: del menú “File”, seleccionar
“New Project”.
En el diálogo elegir “Visual Basic”, luego “Windows”, seleccionar “WPF
Application”.
Escribir en el nombre de la aplicación “Demo91” y clic en “OK”.
Hacer una referencia a las librerías [Link] y
[Link].
Cambiar de nombre a la ventana “[Link]” por “Consulta
[Link]”.
Escribir el siguiente código en el archivo xaml:
<Window x:Class="ConsultaProductos"
xmlns="[Link]
xmlns:x="[Link]
Title="Enlace de Datos - Consulta de Productos" Height="350" Width="350"
WindowStartupLocation="CenterScreen" ResizeMode="NoResize">
<Grid Name="grdProducto">
<[Link]>
<ImageBrush
ImageSource="C:\Data\DemosLibro\LibroVB2010\Imagenes\JPG\Paisajes\Mac
[Link]" Opacity="0.5"/>
</[Link]>
<[Link]>
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="30*" />
</[Link]>
<[Link]>
Luis Dueñas Pag 641
La Biblia de Visual Basic .NET
<ColumnDefinition Width="50" />
<ColumnDefinition Width="60" />
<ColumnDefinition Width="160" />
<ColumnDefinition Width="50*" />
</[Link]>
<Label Name="lblTitulo" [Link]="1" [Link]="1"
[Link]="2" Content="Consulta de Productos"
FontSize="16" Foreground="Blue"
HorizontalAlignment="Center" />
<Label Name="lblCodigo" [Link]="2" [Link]="1"
VerticalAlignment="Center" Content="Codigo"
FontSize="12" Foreground="Blue"
HorizontalAlignment="Left" />
<TextBox Name="txtCodigo" [Link]="2" [Link]="2"
Width="50" Height="20" HorizontalAlignment="Left"
Text="{Binding Path=Codigo}"/>
<Label Name="lblNombre" [Link]="3" [Link]="1"
Content="Nombre" Foreground="Blue"
VerticalAlignment="Center" FontSize="12"
HorizontalAlignment="Left" />
<TextBox Name="txtNombre" [Link]="3" [Link]="2"
Width="160" Height="20" HorizontalAlignment="Left"
Text="{Binding Path=Nombre}"/>
<Label Name="lblPrecio" [Link]="4" [Link]="1"
Content="Precio" Foreground="Blue"
VerticalAlignment="Center" FontSize="12"
HorizontalAlignment="Left" />
<TextBox Name="txtPrecio" [Link]="4" [Link]="2"
Width="50" Height="20" HorizontalAlignment="Left"
Text="{Binding Path=PrecioUnitario}"/>
<Label Name="lblStock" [Link]="5" [Link]="1"
Content="Stock" Foreground="Blue"
VerticalAlignment="Center" FontSize="12"
HorizontalAlignment="Left" />
<TextBox Name="txtStock" [Link]="5" [Link]="2"
Width="50" Height="20" HorizontalAlignment="Left"
Text="{Binding Path=Stock}"/>
<DockPanel [Link]="6" [Link]="1" [Link]="2"
HorizontalAlignment="Center">
<Button Name="btnPrimero" Content="<<" Width="35"
Luis Dueñas Pag 642
La Biblia de Visual Basic .NET
Height="25" Cursor="Hand" ToolTip="Ir al primer registro"/>
<Button Name="btnAnterior" Content="<" Width="35"
Height="25" Cursor="Hand" ToolTip="Ir al anterior registro"/>
<TextBox Name="txtPosicion" Width="80" Height="25"
IsReadOnly="True" HorizontalContentAlignment="Center"/>
<Button Name="btnSiguiente" Content=">" Width="35"
Height="25" Cursor="Hand" ToolTip="Ir al siguiente registro"/>
<Button Name="btnUltimo" Content=">>" Width="35"
Height="25" Cursor="Hand" ToolTip="Ir al último registro"/>
</DockPanel>
<Button Name="btnBuscar" [Link]="7" [Link]="1"
[Link]="2" Content="Buscar x Código" Width="110"
Height="25" Cursor="Hand" ToolTip="Ir al último registro"/>
</Grid>
</Window>
Nota: En el código anterior se define 9 filas y 4 columnas en el Grid para
ubicar los controles: 4 textos para mostrar el código, nombre, precio y
stock de los productos. Además hay 4 botones para realizar el
desplazamiento de registro y un botón para buscar por código.
El diseño de la ventana debe quedar como se ve en el siguiente gráfico.
Gráfico 6.21: Diseño de la ventana Consulta de Productos
Luis Dueñas Pag 643
La Biblia de Visual Basic .NET
Escribir código en el archivo vb asociado al xaml:
Imports [Link]
Imports [Link]
Imports [Link]
Class ConsultaProductos
Private lobeProducto As New List(Of beProducto)
Private WithEvents cv As CollectionView
Private nCodigo As Integer
Private Sub CargarProductos(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim obrProducto As New brProducto
lobeProducto = [Link]
[Link] = lobeProducto
cv = [Link](lobeProducto)
MostrarPosicion(Nothing, Nothing)
End Sub
Private Sub MostrarPosicion(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
[Link] = [Link]("{0} de {1}", _
[Link] + 1, [Link])
End Sub
Private Sub IrAlPrimerRegistro(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link]()
End Sub
Private Sub IrAnteriorRegistro(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link]()
If [Link] Then [Link]()
End Sub
Private Sub IrSiguienteRegistro(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link]()
If [Link] Then [Link]()
Luis Dueñas Pag 644
La Biblia de Visual Basic .NET
End Sub
Private Sub IrUltimoRegistro(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link]()
End Sub
Private Function BuscarProducto(ByVal obeProducto As beProducto) _
As Boolean
Return ([Link] = nCodigo)
End Function
Private Sub BuscarPorCodigo(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim strCodigo As String = InputBox _
("Ingresa el código", "Búsqueda de Productos", "1")
If strCodigo <> "" Then
Dim exito As Boolean = [Link](strCodigo, nCodigo)
If exito Then
Dim pred As New Predicate(Of beProducto) _
(AddressOf BuscarProducto)
Dim pos As Integer = [Link](pred)
If pos > -1 Then
[Link](pos)
Else
[Link]("No existe el código ingresado", "Aviso")
End If
Else
[Link]("El código debe ser entero", "Aviso")
End If
Else
[Link]("El código esta vacío", "Aviso")
End If
End Sub
End Class
Nota: En el código anterior al cargar la ventana se llena la lista de
productos y se enlaza la propiedad DataContext del Grid a la lista de
objetos, luego se crea el CollectionView usando el método GetDefaultView
de la clase CollectionViewSource.
Luis Dueñas Pag 645
La Biblia de Visual Basic .NET
Importante: Para mostrar la posición actual se usa el evento Current
Changed del CollectionView y para buscar por código se usa predicados.
Regresar a la ventana “[Link]” y cambiar la ventana que
inicia (atributo StartupUri) a “[Link]”.
Agregar un archivo de configuración a la aplicación: del menú “Project”,
seleccionar “Add New Item”, en la categoría “General” seleccionar
“Application Configuration File”.
Agregar en el archivo de configuración la clave conNW en la sección
appSettings:
<configuration>
<appSettings>
<add key="conNW" value="uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 6.22: Ejecución de la ventana Consulta de Productos
Luis Dueñas Pag 646
La Biblia de Visual Basic .NET
2.3. Usando Conversión de Datos
Cuando enlazamos controles a datos los valores que se muestran son
exactamente como se encuentran en el origen de datos; pero la mayoría de
veces, queremos que estos valores se muestren en un formato
personalizado por ejemplo los números con 2 decimales, los datos de tipo
fecha y hora solo debe mostrase la fecha, o en vez de ver un texto ver una
imagen, etc.
Todo esto se logra en WPF usando convertidores de datos personalizados
para lo cual debemos crear una clase que implemente la interface
IValueConverter ubicada en el espacio de nombres [Link],
a continuación, programar los métodos Convert y ConvertBack. Los
convertidores pueden cambiar los datos de un tipo a otro, traducir datos
basados en información de referencia cultural o modificar otros aspectos de
la presentación.
Los convertidores de valores tienen en cuenta la referencia cultural. Los
métodos Convert y ConvertBack tienen un parámetro culture que indica la
información de referencia cultural. Si la información de referencia cultural
es no importante para la conversión, puede pasar por alto este parámetro
en el convertidor personalizado.
Los métodos Convert y ConvertBack también cuentan con un parámetro
denominado parameter para que pueda usar la misma instancia del
convertidor con parámetros distintos. Por ejemplo, puede escribir a un
convertidor de formato que genere formatos de datos diferentes basados
en el parámetro de entrada que use. Puede utilizar la propiedad
ConverterParameter de la clase Binding para pasar un parámetro como
argumento a los métodos Convert y ConvertBack.
A continuación veremos un par de ejemplos sobre como usar conversión
de datos en el enlace de datos, el primer ejemplo muestra una lista de
productos con la columna precio unitario con 2 decimales uando una clase
de conversión llamada FormatoDecimal, además las columnas del ListView
pueden ordenarse en forma ascendente o descendente por cualquiera de
los campos mostrados: código, nombre, precio unitario o stock.
Luis Dueñas Pag 647
La Biblia de Visual Basic .NET
En el segundo ejemplo se muestra una consulta de empleados que
muestra su código, apellido, nombre, fecha de nacimiento y foto del
empleado, aquí se crean 2 clases de conversión de datos: una para
mostrar solo la fecha de nacimiento sin hora y el segundo para mostrar la
ruta de la imagen de la foto del empleado según su código.
Demo 92
Crear una nueva aplicación Windows WPF: del menú “File”, seleccionar
“New Project”.
En el diálogo elegir “Visual Basic”, luego “Windows”, seleccionar “WPF
Application”.
Escribir en el nombre de la aplicación “Demo92” y clic en “OK”.
Hacer una referencia a las librerías [Link] y
[Link].
Crear una clase para la conversión a 2 decimales: del menú “Project”,
seleccionar “Add Class”, escribir como nombre: “[Link]” y
clic en “Add”.
Escribir el siguiente código en la clase:
Public Class FormatoDecimal
Implements IValueConverter
Public Function Convert(ByVal value As Object, _
ByVal targetType As [Link], ByVal parameter As Object, _
ByVal culture As [Link]) As Object _
Implements [Link]
Return ([Link]("{0:n2}", value))
End Function
Public Function ConvertBack(ByVal value As Object, _
ByVal targetType As [Link], ByVal parameter As Object, _
ByVal culture As [Link]) As Object _
Implements [Link]
Return ([Link]("{0:n2}", value))
End Function
Luis Dueñas Pag 648
La Biblia de Visual Basic .NET
End Class
Nota: En el código anterior ambos métodos reciben un valor de un cierto
tipo por ejemplo decimal y se devuelve una cadena formateada a 2
decimales.
Cerrar la ventana con la clase y compilar la aplicación para poder definir
un recurso que apunte a la clase creada.
Cambiar de nombre a la ventana “[Link]” por “Lista
[Link]”.
Escribir el siguiente código en el archivo xaml:
<Window x:Class="ListaProductos"
xmlns="[Link]
xmlns:x="[Link]
xmlns:ld="clr-namespace:Demo92"
Title="Conversión de Datos - Ordenación en ListView"
Height="350" Width="400"
Name="ListaProductos" ResizeMode="NoResize"
WindowStartupLocation="CenterScreen">
<[Link]>
<ld:FormatoDecimal x:Key="fd"/>
</[Link]>
<Grid>
<ListView Name="lvwProducto" Foreground="White"
[Link]="Ordenar" >
<[Link]>
<LinearGradientBrush>
<GradientStop Color="aqua" Offset="0.8"/>
<GradientStop Color="blue" Offset="0.3"/>
</LinearGradientBrush>
</[Link]>
<[Link]>
<GridView>
<GridViewColumn Header="Codigo" Width="60"
DisplayMemberBinding="{Binding Path=Codigo}" />
<GridViewColumn Header="Nombre"Width="180"
DisplayMemberBinding="{Binding Path=Nombre}"/>
<GridViewColumn Header="PrecioUnitario" Width="60"
Luis Dueñas Pag 649
La Biblia de Visual Basic .NET
DisplayMemberBinding="{Binding Path=PrecioUnitario,
Converter={StaticResource fd}}"/>
<GridViewColumn Header="Stock" Width="60"
DisplayMemberBinding="{Binding Path=Stock}"/>
</GridView>
</[Link]>
</ListView>
</Grid>
</Window>
Nota: En el código anterior se define un espacio de nombres en XAML con
el prefijo “ld” (siglas del autor: Luis Dueñas) que apunta al Demo92, luego
se incluye un recurso en la ventana llamado “fd” que apunta a la clase
FormatoDecimal y por último se aplica este recurso mediante el atributo
Converter en el enlace de datos del precio unitario.
Importante: Para ordenar los datos al dar clic en las cabeceras de las
columnas del ListView se asocia el procedimiento “Ordenar” al evento clic
del objeto “GridViewColumnHeader” del ListView.
El diseño de la ventana debe quedar como se ve en el siguiente gráfico.
Gráfico 6.23: Diseño de la ventana Lista de Productos
Luis Dueñas Pag 650
La Biblia de Visual Basic .NET
Crear una clase genérica para ordenar listas de objetos (en nuestro
caso lista de productos): del menú “Project”, seleccionar “Add Class”,
escribir como nombre: “[Link]” y clic en “Add”.
Escribir el siguiente código en la clase:
Imports [Link]
Public Class ucCompara(Of T)
Implements IComparer(Of T)
Private Campo As String
Private TipoOrden As TiposOrden
Public Enum TiposOrden
Ascendente = 0
Descendente = 1
End Enum
Public Sub New(ByVal vCampo As String, ByVal vTipoOrden As TiposOrden)
Campo = vCampo
TipoOrden = vTipoOrden
End Sub
Public Function Compare(ByVal x As T, ByVal y As T) As _
Integer Implements IComparer(Of T).Compare
Dim valX As Object = _
[Link](Campo).GetValue(x, Nothing)
Dim valY As Object = _
[Link](Campo).GetValue(y, Nothing)
If TipoOrden = [Link] Then
Return ([Link](valY))
Else
Return ([Link](valX))
End If
End Function
End Class
Nota: En el código anterior en el constructor se pasa como parámetro el
campo que queremos ordenar y el tipo de orden: 0 es ascendente y 1 es
descendente, luego usando reflection en el método Compare se devuelve
que objeto es mayor o menor según sea el tipo de orden.
Luis Dueñas Pag 651
La Biblia de Visual Basic .NET
Escribir código en el archivo vb asociado al xaml:
Imports [Link]
Imports [Link]
Class ListaProductos
Private lobeProducto As New List(Of beProducto)
Private Sub ListarProductos(ByVal sender As [Link], _
ByVal e As [Link]) _
Handles [Link]
Dim obrProducto As New brProducto
lobeProducto = [Link]()
[Link] = lobeProducto
End Sub
Private Sub Ordenar(ByVal sender As [Link], _
ByVal e As [Link])
Dim columna As GridViewColumnHeader = _
CType([Link], GridViewColumnHeader)
Dim campo As String = [Link]
Dim N As Integer = If([Link] = 0, 1, 0)
[Link] = _
If(N = 0, [Link], [Link])
[Link] = _
If(N = 0, [Link], [Link])
[Link] = N
Dim oucCompara As New _
ucCompara(Of beProducto)(campo, N)
[Link](oucCompara)
[Link] = Nothing
[Link] = lobeProducto
End Sub
End Class
Nota: En el código anterior al cargar la ventana se llena la lista de
productos y se enlaza la propiedad ItemsSource del ListView a la lista de
objetos, luego cada vez que se da clic en las cabeceras del ListView se
ordenan los datos y se cambia de color de fondo y texto la cabecera.
Luis Dueñas Pag 652
La Biblia de Visual Basic .NET
Importante: Para obtener la cabecera a la cual se dio clic se usa el
parámetro [Link] que devuelve el GridViewColumnHeader.
Regresar a la ventana “[Link]” y cambiar la ventana que
inicia (atributo StartupUri) a “[Link]”.
Agregar un archivo de configuración a la aplicación: del menú “Project”,
seleccionar “Add New Item”, en la categoría “General” seleccionar
“Application Configuration File”.
Agregar en el archivo de configuración la clave conNW en la sección
appSettings:
<configuration>
<appSettings>
<add key="conNW" value="uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 6.24: Ejecución de la ventana Lista de Productos
Luis Dueñas Pag 653
La Biblia de Visual Basic .NET
Demo 93
Crear una nueva aplicación Windows WPF: del menú “File”, seleccionar
“New Project”.
En el diálogo elegir “Visual Basic”, luego “Windows”, seleccionar “WPF
Application”.
Escribir en el nombre de la aplicación “Demo93” y clic en “OK”.
Hacer una referencia a las librerías [Link] y
[Link].
Agregar una clase para la conversión a solo fecha: del menú “Project”,
seleccionar “Add Class”, escribir como nombre: “[Link]” y
clic en “Add”.
Escribir el siguiente código en la clase FormatoFecha:
Public Class FormatoFecha
Implements IValueConverter
Public Function Convert(ByVal value As Object, _
ByVal targetType As [Link], ByVal parameter As Object, _
ByVal culture As [Link]) As Object _
Implements [Link]
Return ([Link]("{0:d}", value))
End Function
Public Function ConvertBack(ByVal value As Object, _
ByVal targetType As [Link], ByVal parameter As Object, _
ByVal culture As [Link]) As Object _
Implements [Link]
Return ([Link]("{0:d}", value))
End Function
End Class
Nota: En el código anterior los métodos devuelven una fecha como cadena
sin hora.
Luis Dueñas Pag 654
La Biblia de Visual Basic .NET
Agregar otra clase para la conversión a una ruta de archivos de
imágen: del menú “Project”, seleccionar “Add Class”, escribir como
nombre: “[Link]” y clic en “Add”.
Escribir el siguiente código en la clase FormatoImagen:
Imports [Link]
Public Class FormatoImagen
Implements IValueConverter
Private Ruta As String = _
"C:\Data\DemosLibro\LibroVB2010\Imagenes\JPG\Empleados\"
Private Archivo As String
Public Function Convert(ByVal value As Object, _
ByVal targetType As [Link], ByVal parameter As Object, _
ByVal culture As [Link]) As Object _
Implements [Link]
Archivo = [Link]("{0}{1}.jpg", Ruta, value)
If [Link](Archivo) Then
Return (Archivo)
Else
Return ([Link]("{0}[Link]", Ruta))
End If
End Function
Public Function ConvertBack(ByVal value As Object, _
ByVal targetType As [Link], ByVal parameter As Object, _
ByVal culture As [Link]) As Object _
Implements [Link]
Archivo = [Link]("{0}{1}.jpg", Ruta, value)
If [Link](Archivo) Then
Return (Archivo)
Else
Return ([Link]("{0}[Link]", Ruta))
End If
End Function
End Class
Luis Dueñas Pag 655
La Biblia de Visual Basic .NET
Nota: En el código anterior los métodos devuelven la ruta de un archivo de
imagen según el valor que debería ser el código del empleado, sino existe
el archivo se devuelve el archivo de imagen [Link].
Cerrar las ventanas con las 2 clases y compilar la aplicación para poder
definir un recurso que apunte a las clases creadas.
Cambiar de nombre a la ventana “[Link]” por “Consulta
[Link]”.
Escribir el siguiente código en el archivo xaml:
<Window x:Class="ConsultaEmpleados"
xmlns="[Link]
xmlns:x="[Link]
xmlns:ld="clr-namespace:Demo93"
Title="Conversión de Datos - Fechas e Imágenes"
Height="350" Width="350" ResizeMode="NoResize"
WindowStartupLocation="CenterScreen">
<[Link]>
<ld:FormatoFecha x:Key="ff" />
<ld:FormatoImagen x:Key="fi" />
</[Link]>
<Grid Name="grdEmpleado">
<[Link]>
<LinearGradientBrush>
<GradientStop Color="aqua" Offset="0.8"/>
<GradientStop Color="blue" Offset="0.3"/>
</LinearGradientBrush>
</[Link]>
<[Link]>
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="100" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="30*" />
</[Link]>
Luis Dueñas Pag 656
La Biblia de Visual Basic .NET
<[Link]>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="120" />
<ColumnDefinition Width="50*" />
</[Link]>
<Label Name="lblTitulo" [Link]="0" [Link]="1"
[Link]="2" Content="Consulta de Empleados"
FontSize="16" Foreground="White"
HorizontalAlignment="Center" />
<Label Name="lblCodigo" [Link]="1" [Link]="1"
VerticalAlignment="Center" Content="Codigo"
FontSize="12" Foreground="White"
HorizontalAlignment="Left" />
<TextBox Name="txtCodigo" [Link]="1" [Link]="2"
Width="50" Height="20" HorizontalAlignment="Left"
Text="{Binding Path=Codigo}"/>
<Label Name="lblApellido" [Link]="2" [Link]="1"
Content="Apellido" Foreground="White"
VerticalAlignment="Center" FontSize="12"
HorizontalAlignment="Left" />
<TextBox Name="txtApellido" [Link]="2" [Link]="2"
Width="100" Height="20" HorizontalAlignment="Left"
Text="{Binding Path=Apellido}"/>
<Label Name="lblNombre" [Link]="3" [Link]="1"
Content="Nombre" Foreground="White"
VerticalAlignment="Center" FontSize="12"
HorizontalAlignment="Left" />
<TextBox Name="txtNombre" [Link]="3" [Link]="2"
Width="100" Height="20" HorizontalAlignment="Left"
Text="{Binding Path=Nombre}"/>
<Label Name="lblFechaNac" [Link]="4" [Link]="1"
Content="Fecha Nac" VerticalAlignment="Center"
FontSize="12" Foreground="White"
HorizontalAlignment="Left" />
<TextBox Name="txtFechaNac" [Link]="4" [Link]="2"
Width="100" Height="20" HorizontalAlignment="Left"
Text="{Binding Path=FechaNac,Converter={StaticResource ff}}"/>
<Label Name="lblFoto" [Link]="5" [Link]="1"
Content="Foto" Foreground="White"
Luis Dueñas Pag 657
La Biblia de Visual Basic .NET
VerticalAlignment="Center" FontSize="12"
HorizontalAlignment="Left" />
<Image Name="imgFoto" [Link]="5" [Link]="2"
VerticalAlignment="Center" Width="120" Height="100"
Source="{Binding Path=Codigo,Converter={StaticResource fi}}"/>
<DockPanel [Link]="6" [Link]="1" [Link]="2"
HorizontalAlignment="Center">
<Button Name="btnPrimero" Content="<<" Width="35"
Height="25" Cursor="Hand" ToolTip="Ir al primer registro"/>
<Button Name="btnAnterior" Content="<" Width="35"
Height="25" Cursor="Hand" ToolTip="Ir al anterior registro"/>
<TextBox Name="txtPosicion" Width="80" Height="25"
IsReadOnly="True" HorizontalContentAlignment="Center"/>
<Button Name="btnSiguiente" Content=">" Width="35"
Height="25" Cursor="Hand" ToolTip="Ir al siguiente registro"/>
<Button Name="btnUltimo" Content=">>" Width="35"
Height="25" Cursor="Hand" ToolTip="Ir al último registro"/>
</DockPanel>
</Grid>
</Window>
Nota: En el código anterior se define un espacio de nombres en XAML con
el prefijo “ld” (siglas del autor: Luis Dueñas) que apunta al Demo93, luego
se incluye 2 recursos en la ventana: uno llamado “ff” que apunta a la clase
FormatoFecha y otro llamado “fi” que apunta a la clase FormatoImagen.
Por último se aplican estos recursos mediante el atributo Converter en el
enlace de datos, “ff” a la fecha de nacimiento y “fi” a la imágen.
El diseño de la ventana debe quedar como se ve en el gráfico 6.25.
Luis Dueñas Pag 658
La Biblia de Visual Basic .NET
Gráfico 6.25: Diseño de la ventana Consulta de Empleados
Escribir código en el archivo vb asociado al xaml:
Imports [Link]
Imports [Link]
Class ConsultaEmpleados
Private lobeEmpleado As New List(Of beEmpleado)
Private WithEvents cv As CollectionView
Private Sub CargarEmpleados(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim obrEmpleado As New brEmpleado
lobeEmpleado = [Link]
[Link] = lobeEmpleado
cv = [Link](lobeEmpleado)
MostrarPosicion(Nothing, Nothing)
End Sub
Private Sub MostrarPosicion(ByVal sender As Object, _
ByVal e As [Link]) Handles [Link]
[Link] = [Link]("{0} de {1}", _
[Link] + 1, [Link])
End Sub
Luis Dueñas Pag 659
La Biblia de Visual Basic .NET
Private Sub IrAlPrimerRegistro(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link]()
End Sub
Private Sub IrAnteriorRegistro(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link]()
If [Link] Then [Link]()
End Sub
Private Sub IrSiguienteRegistro(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link]()
If [Link] Then [Link]()
End Sub
Private Sub IrUltimoRegistro(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link]()
End Sub
End Class
Nota: En el código anterior al cargar la ventana se llena la lista de
empleados y se enlaza la propiedad DataContext del Grid a la lista de
objetos y se crea el CollectionView mediante el método GetDefaultView de
la clase CollectionViewSource. Para el desplazamiento se usa los métodos
del objeto CollectionView y también para mostrar la posición actual se
programa en el evento CurrentChanged.
Regresar a la ventana “[Link]” y cambiar la ventana que
inicia (atributo StartupUri) a “[Link]”.
Agregar un archivo de configuración a la aplicación: del menú “Project”,
seleccionar “Add New Item”, en la categoría “General” seleccionar
“Application Configuration File”.
Agregar en el archivo de configuración la clave conNW en la sección
appSettings:
Luis Dueñas Pag 660
La Biblia de Visual Basic .NET
<configuration>
<appSettings>
<add key="conNW" value="uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 6.26: Ejecución de la ventana Consulta de Empleados
Luis Dueñas Pag 661
La Biblia de Visual Basic .NET
2.4. Usando Plantillas de Datos
Las plantillas de datos se usan para mejorar la presentación de datos en los
controles enlazados a datos, por ejemplo los controles de listas ListBox y
ComboBox solo muestran una columna cuando están enlazados a un origen
de datos mediante la propiedad DisplayMemberPath, en cambio si usamos
plantillas de datos podrían mostrar varias columnas con cualquier tipo de
dato.
Para implementar plantillas de datos en controles WPF se debe crear un
objeto de tipo DataTemplate y asociarlo a la propiedad ItemTemplate del
control. Dentro del DataTemplate para definir varios controles es necesario
incluir un contenedor como el Grid, StackPanel, DockPanel, etc.
También hay controles como el TreeView que soporta plantilla jerárquica,
la cual se implementa con el objeto HierarchicalDataTemplate, para definir
a los detalles se usa su propiedad ItemTemplate.
Además cuando se trabaja con plantillas jerárquicas se debe tener un
origen de datos jerárquico es decir por ejemplo una lista de objetos que a
su vez tenga como propiedad otra lista de objetos de tal forma que se
enlace solo el objeto raíz y desde aquí se acceda a las demás listas.
Un origen de datos jerárquico también facilita la sincronización entre listas
en vez de estar programando podría ser automatico los filtros usando la
propiedad IsSynchronizedWithCurrentItem en true y configurando el objeto
CurrentItem en el enlace de datos como lo demuestra el siguiente demo.
Para obtener más información sobre plantillas de datos ver la referencia 41
al final del libro.
A continuación dos ejemplos de plantillas de datos, el primero es una
consulta de productos por categoría usando sincronización de controles y el
segundo es un ejemplo de plantillas jerárquicas que muestra las órdenes
con sus respectivos detalles. Para ambos ejercicios es necesario crear
nuevos procedimientos almacenados y agregar métodos a las librerías de
clases creadas, tanto las entidades de negocios, capa de datos y reglas de
negocio.
Luis Dueñas Pag 662
La Biblia de Visual Basic .NET
Creando los Procedimientos Almacenados
Crear los siguientes procedimientos almacenados:
1. Procedimiento almacenado que lista ordenes
Create Procedure usp_Orders_Sel
As
Select
[Link] As Orden,
[Link] As Cliente,
[Link]+' '+[Link] As Empleado,
[Link] As FechaOrden
From Orders o,Customers c,Employees e
Where
[Link]=[Link] And
[Link]=[Link]
Order By 1
2. Procedimiento almacenado que lista detalles de ordenes
Create Procedure usp_OrderDetails_Sel
As
Select
[Link] As IdOrden,
[Link] As IdProducto,
[Link] As DesProducto,
[Link] As PrecioUnitario,
[Link] As Cantidad,
[Link]*[Link] As PrecioTotal
From [Order Details] d,Products p
Where
[Link]=[Link]
Order By 1
Luis Dueñas Pag 663
La Biblia de Visual Basic .NET
Modificando la Librería de Entidades del Negocio
Del menú “File”, seleccionar “Open Project”.
Ingresar a la carpeta donde se encuentra la librería de entidades del
negocio: [Link] y abrir el proyecto.
Abrir la clase beCategoria y modificar el código como sigue:
Public Class beCategoria
Public Property Codigo() As Integer
Public Property Nombre() As String
Public Property ListaProductos As List(Of beProducto)
End Class
Agregar una nueva clase entidad para las ordenes: del menú “Project”,
seleccionar “Add Class”, ingresar como nombre: “[Link]” y “Add”.
Escribir el siguiente código para la clase:
Public Class beOrden
Public Property IdOrden() As Integer
Public Property NombreCliente() As String
Public Property NombreEmpleado() As String
Public Property FechaOrden() As DateTime
Public Property ListaDetalles As List(Of beDetalle)
End Class
Agregar una nueva clase entidad para los detalles: del menú “Project”,
seleccionar “Add Class”, ingresar el nombre: “[Link]” y clic “Add”.
Escribir el siguiente código para la clase:
Public Class beDetalle
Public Property IdOrden() As Integer
Public Property IdProducto() As Integer
Public Property NombreProducto() As String
Public Property PrecioUnitario() As Decimal
Public Property Cantidad() As Short
Public Property PrecioTotal() As Decimal
End Class
Luis Dueñas Pag 664
La Biblia de Visual Basic .NET
Compilar la librería de entidades y cerrar el proyecto.
Modificando la Librería de Acceso a Datos
Del menú “File”, seleccionar “Open Project”.
Ingresar a la carpeta donde se encuentra la librería de acceso a datos:
[Link] y abrir el proyecto.
Agregar una nueva clase de datos para las ordenes: del menú “Project”,
seleccionar “Add Class”, ingresar como nombre: “[Link]” y “Add”.
Escribir el siguiente código para la clase:
Imports [Link]
Imports [Link]
Public Class daOrden
Public Function fListar(ByVal con As SqlConnection) As List(Of beOrden)
Dim lobeOrden As New List(Of beOrden)
Dim cmd As New SqlCommand("usp_Orders_Sel", con)
[Link] = [Link]
[Link] = 60
Dim drd As SqlDataReader = _
[Link]([Link])
If drd IsNot Nothing Then
Dim posOrden As Integer = [Link]("Orden")
Dim posCliente As Integer = [Link]("Cliente")
Dim posEmpleado As Integer = [Link]("Empleado")
Dim posFechaOrden As Integer = [Link]("FechaOrden")
Dim obeOrden As beOrden
Do While [Link]
obeOrden = New beOrden
With obeOrden
.IdOrden = drd.GetInt32(posOrden)
.NombreCliente = [Link](posCliente)
.NombreEmpleado = [Link](posEmpleado)
.FechaOrden = [Link](posFechaOrden)
End With
Luis Dueñas Pag 665
La Biblia de Visual Basic .NET
[Link](obeOrden)
Loop
[Link]()
End If
Return (lobeOrden)
End Function
End Class
Agregar una nueva clase de datos para los detalles: del menú “Project”,
seleccionar “Add Class”, ingresar como nombre: “[Link]” y “Add”.
Escribir el siguiente código para la clase:
Imports [Link]
Imports [Link]
Public Class daDetalle
Public Function fListar(ByVal con As SqlConnection) As List(Of beDetalle)
Dim lobeDetalle As New List(Of beDetalle)
Dim cmd As New SqlCommand("usp_OrderDetails_Sel", con)
[Link] = [Link]
[Link] = 60
Dim drd As SqlDataReader = _
[Link]([Link])
If drd IsNot Nothing Then
Dim posIdOrden As Integer = [Link]("IdOrden")
Dim posIdProducto As Integer = [Link]("IdProducto")
Dim posDesProducto As Integer = [Link]("DesProducto")
Dim posPrecioUnitario As Integer = [Link]("PrecioUnitario")
Dim posCantidad As Integer = [Link]("Cantidad")
Dim posPrecioTotal As Integer = [Link]("PrecioTotal")
Dim obeDetalle As beDetalle
Do While [Link]
obeDetalle = New beDetalle
With obeDetalle
.IdOrden = drd.GetInt32(posIdOrden)
.IdProducto = drd.GetInt32(posIdProducto)
.NombreProducto = [Link](posDesProducto)
.PrecioUnitario = [Link](posPrecioUnitario)
Luis Dueñas Pag 666
La Biblia de Visual Basic .NET
.Cantidad = drd.GetInt16(posCantidad)
.PrecioTotal = [Link](posPrecioTotal)
End With
[Link](obeDetalle)
Loop
[Link]()
End If
Return (lobeDetalle)
End Function
End Class
Compilar la librería de acceso a datos y cerrar el proyecto.
Modificando la Librería de Reglas de Negocio
Del menú “File”, seleccionar “Open Project”.
Ingresar a la carpeta donde se encuentra la librería de reglas de
negocio: [Link] y abrir el proyecto.
Abrir la clase brCategoria y modificar el código como sigue:
Imports [Link]
Imports [Link]
Imports [Link]
Public Class brCategoria
Private strConexion As String
Private IdCategoria As String
Public Sub New()
Dim asr As New [Link]
strConexion = [Link]("conNW", [Link]("[Link]"))
End Sub
Public Function Listar() As List(Of beCategoria)
Dim lobeCategoria As New List(Of beCategoria)
Using con As New SqlConnection(strConexion)
Luis Dueñas Pag 667
La Biblia de Visual Basic .NET
Try
[Link]()
Dim odaCategoria As New daCategoria
lobeCategoria = [Link](con)
Catch ex As Exception
'Grabar el Log de error
lobeCategoria = Nothing
End Try
End Using
Return (lobeCategoria)
End Function
Private Function BuscarProductos(ByVal obeProducto As beProducto) _
As Boolean
Return ([Link] = IdCategoria)
End Function
Public Function ListarConProductos() As List(Of beCategoria)
Dim lobeCategoria As New List(Of beCategoria)
Using con As New SqlConnection(strConexion)
Try
[Link]()
Dim odaCategoria As New daCategoria
lobeCategoria = [Link](con)
Dim odaProducto As New daProducto
Dim lobeProducto As List(Of beProducto) = _
[Link](con)
Dim pred As New Predicate(Of beProducto) _
(AddressOf BuscarProductos)
For I = 0 To [Link] - 1
IdCategoria = lobeCategoria(I).Codigo
lobeCategoria(I).ListaProductos = _
[Link](pred)
Next
Catch ex As Exception
'Grabar el Log de error
lobeCategoria = Nothing
End Try
End Using
Return (lobeCategoria)
Luis Dueñas Pag 668
La Biblia de Visual Basic .NET
End Function
End Class
Nota: En el código anterior el método ListarConProductos se conecta a la
base de datos y ejecuta 2 consultas, una que trae todas las categorías y
otra que trae todos los productos, luego se recorre cada categoría y
usando un predicado se llena los productos de cada categoría.
Agregar una nueva clase de datos para las ordenes: del menú “Project”,
seleccionar “Add Class”, ingresar como nombre: “[Link]” y “Add”.
Escribir el siguiente código para la clase:
Imports [Link]
Imports [Link]
Imports [Link]
Public Class brOrden
Private strConexion As String
Private IdOrden As Integer
Public Sub New()
Dim asr As New [Link]
strConexion = [Link]("conNW", [Link]("[Link]"))
End Sub
Private Function BuscarDetalles(ByVal obeDetalle As beDetalle) _
As Boolean
Return ([Link] = IdOrden)
End Function
Public Function ListarConDetalles() As List(Of beOrden)
Dim lobeOrden As New List(Of beOrden)
Using con As New SqlConnection(strConexion)
Try
[Link]()
Dim odaOrden As New daOrden
lobeOrden = [Link](con)
Dim odaDetalle As New daDetalle
Dim lobeDetalle As List(Of beDetalle) = _
[Link](con)
Luis Dueñas Pag 669
La Biblia de Visual Basic .NET
Dim pred As New Predicate(Of beDetalle) _
(AddressOf BuscarDetalles)
For I = 0 To [Link] - 1
IdOrden = lobeOrden(I).IdOrden
lobeOrden(I).ListaDetalles = _
[Link](pred)
Next
Catch ex As Exception
'Grabar el Log de error
lobeOrden = Nothing
End Try
End Using
Return (lobeOrden)
End Function
End Class
Nota: En el código anterior el método ListarConDetalles se conecta a la
base de datos y ejecuta 2 consultas, una que trae todas las órdenes y otra
que trae todos los detalles, luego se recorre cada órden y usando un
predicado se llena los detalles de cada órden.
Compilar la librería de reglas de negocio y cerrar el proyecto.
Luis Dueñas Pag 670
La Biblia de Visual Basic .NET
Demo 94
Crear una nueva aplicación Windows WPF: del menú “File”, seleccionar
“New Project”.
En el diálogo elegir “Visual Basic”, luego “Windows”, seleccionar “WPF
Application”.
Escribir en el nombre de la aplicación “Demo94” y clic en “OK”.
Hacer una referencia a las librerías [Link] y
[Link].
Crear una clase para la conversión a 2 decimales: del menú “Project”,
seleccionar “Add Class”, escribir como nombre: “[Link]” y
clic en “Add”.
Escribir el siguiente código en la clase:
Public Class FormatoDecimal
Implements IValueConverter
Public Function Convert(ByVal value As Object, _
ByVal targetType As [Link], ByVal parameter As Object, _
ByVal culture As [Link]) As Object _
Implements [Link]
Return ([Link]("{0:n2}", value))
End Function
Public Function ConvertBack(ByVal value As Object, _
ByVal targetType As [Link], ByVal parameter As Object, _
ByVal culture As [Link]) As Object _
Implements [Link]
Return ([Link]("{0:n2}", value))
End Function
End Class
Agregar otra clase para la conversión a una ruta de archivos de
imágen: del menú “Project”, seleccionar “Add Class”, escribir como
nombre: “[Link]” y clic en “Add”.
Luis Dueñas Pag 671
La Biblia de Visual Basic .NET
Escribir el siguiente código en la clase FormatoImagen:
Imports [Link]
Public Class FormatoImagen
Implements IValueConverter
Private Ruta As String = _
"C:\Data\DemosLibro\LibroVB2010\Imagenes\JPG\Categorias\"
Private Archivo As String
Public Function Convert(ByVal value As Object, _
ByVal targetType As [Link], ByVal parameter As Object, _
ByVal culture As [Link]) As Object _
Implements [Link]
Archivo = [Link]("{0}{1}.jpg", Ruta, value)
If [Link](Archivo) Then
Return (Archivo)
Else
Return ([Link]("{0}[Link]", Ruta))
End If
End Function
Public Function ConvertBack(ByVal value As Object, _
ByVal targetType As [Link], ByVal parameter As Object, _
ByVal culture As [Link]) As Object _
Implements [Link]
Archivo = [Link]("{0}{1}.jpg", Ruta, value)
If [Link](Archivo) Then
Return (Archivo)
Else
Return ([Link]("{0}[Link]", Ruta))
End If
End Function
End Class
Cerrar las ventanas con las 2 clases y compilar la aplicación para poder
definir un recurso que apunte a las clases creadas.
Cambiar de nombre a la ventana “[Link]” por “Consulta
[Link]”.
Luis Dueñas Pag 672
La Biblia de Visual Basic .NET
Escribir el siguiente código en el archivo xaml:
<Window x:Class="ConsultaProductosCategoria"
xmlns="[Link]
xmlns:x="[Link]
xmlns:ld="clr-namespace:Demo94"
Title="Plantillas de Datos - Sincronización de Listas"
Height="400" Width="450" ResizeMode="NoResize"
WindowStartupLocation="CenterScreen"
Name="ConsultaProductosCategoria">
<[Link]>
<ld:FormatoDecimal x:Key="fd"/>
<ld:FormatoImagen x:Key="fi"/>
<DataTemplate x:Key="dtCategoria">
<Grid>
<[Link]>
<ColumnDefinition Width="70"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="220"/>
</[Link]>
<[Link]>
<RowDefinition Height="40"/>
</[Link]>
<Image Name="imgFoto" [Link]="0"
Source="{Binding Path=Codigo,
Converter={StaticResource fi}}"/>
<Label Name="lblCodigo" [Link]="1"
Content="{Binding Path=Codigo}"/>
<Label Name="lblNombre" [Link]="2"
Content="{Binding Path=Nombre}"/>
</Grid>
</DataTemplate>
<DataTemplate x:Key="dtProducto">
<Grid>
<[Link]>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="180"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="50"/>
</[Link]>
<Label Name="lblCodProd" [Link]="0"
Luis Dueñas Pag 673
La Biblia de Visual Basic .NET
Content="{Binding Path=Codigo}"
HorizontalAlignment="Right"
Foreground="Yellow"/>
<Label Name="lblNomProd" [Link]="1"
Content="{Binding Path=Nombre}"
Foreground="Yellow"/>
<Label Name="lblPrecio" [Link]="2"
Content="{Binding Path=PrecioUnitario,
Converter={StaticResource fd}}"
HorizontalAlignment="Right"
Foreground="Yellow"/>
<Label Name="lblStock" [Link]="3"
Content="{Binding Path=Stock}"
HorizontalAlignment="Right"
Foreground="Yellow"/>
</Grid>
</DataTemplate>
</[Link]>
<Grid Name="grdCategoria">
<[Link]>
<LinearGradientBrush>
<GradientStop Color="yellow" Offset="1"/>
<GradientStop Color="orange" Offset="0.5"/>
</LinearGradientBrush>
</[Link]>
<[Link]>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="370"/>
<ColumnDefinition Width="30*"/>
</[Link]>
<[Link]>
<RowDefinition Height="30"/>
<RowDefinition Height="40"/>
<RowDefinition Height="260"/>
<RowDefinition Height="30*"/>
</[Link]>
<Label Name="lblTitulo" [Link]="0" [Link]="1"
Foreground="Blue" FontSize="14" FontWeight="Bold"
HorizontalAlignment="Center">
Consulta de Productos x Categoría</Label>
Luis Dueñas Pag 674
La Biblia de Visual Basic .NET
<ComboBox Name="cboCategoria" [Link]="1" [Link]="1"
ItemsSource="{Binding Path=.}"
ItemTemplate="{StaticResource dtCategoria}"
IsSynchronizedWithCurrentItem="True">
<[Link]>
<LinearGradientBrush>
<GradientStop Color="aqua" Offset="0.8"/>
<GradientStop Color="blue" Offset="0.3"/>
</LinearGradientBrush>
</[Link]>
</ComboBox>
<ListBox Name="lstProducto" [Link]="2" [Link]="1"
ItemsSource="{Binding Path=[Link]}"
ItemTemplate="{StaticResource dtProducto}">
<[Link]>
<LinearGradientBrush>
<GradientStop Color="aqua" Offset="0.8"/>
<GradientStop Color="green" Offset="0.3"/>
</LinearGradientBrush>
</[Link]>
</ListBox>
</Grid>
</Window>
Nota: En el código anterior se definen 2 recursos para conversión de
datos: fd para FormatoDecimal y fi para FormatoImagen; también se
definen 2 plantillas de datos, dtCategoria con 3 columnas: una imágen,
código y nombre de la categoría y dtProducto con 4 columnas: código,
nombre, precio y stock del producto.
Importante: Para aplicar la plantilla de datos se usa la propiedad Item
Template y para sincronizar las 2 listas se configura la propiedad
IsSynchronizedWithCurrentItem de la primera lista en true y la propiedad
ItemsSource de la segunda lista en [Link] para filtrar
automáticamente los productos de acuerdo a la categoría seleccionada en
el ComboBox.
El diseño de la ventana debe quedar como se ve en el gráfico 6.27.
Luis Dueñas Pag 675
La Biblia de Visual Basic .NET
Gráfico 6.27: Diseño de la ventana Consulta de Productos x
Categoria
Escribir código en el archivo vb asociado al xaml:
Imports [Link]
Imports [Link]
Class ConsultaProductosCategoria
Private lobeCategoria As New List(Of beCategoria)
Private Sub CargarDatos(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim obrCategoria As New brCategoria
lobeCategoria = [Link]
[Link] = lobeCategoria
End Sub
End Class
Nota: En el código anterior al cargar la ventana se llena la lista de
categorías donde cada categoría tiene una lista de productos y se enlaza la
propiedad DataContext del Grid a la lista de categorías.
Luis Dueñas Pag 676
La Biblia de Visual Basic .NET
Regresar a la ventana “[Link]” y cambiar la ventana que
inicia (atributo StartupUri) a “[Link]”.
Agregar un archivo de configuración a la aplicación: del menú “Project”,
seleccionar “Add New Item”, en la categoría “General” seleccionar
“Application Configuration File”.
Agregar en el archivo de configuración la clave conNW en la sección
appSettings:
<configuration>
<appSettings>
<add key="conNW" value="uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 6.28: Ejecución de la ventana Consulta de Productos x
Categoría
Luis Dueñas Pag 677
La Biblia de Visual Basic .NET
Demo 95
Crear una nueva aplicación Windows WPF: del menú “File”, seleccionar
“New Project”.
En el diálogo elegir “Visual Basic”, luego “Windows”, seleccionar “WPF
Application”.
Escribir en el nombre de la aplicación “Demo95” y clic en “OK”.
Hacer una referencia a las librerías [Link] y
[Link].
Crear una clase para la conversión a 2 decimales: del menú “Project”,
seleccionar “Add Class”, escribir como nombre: “[Link]” y
clic en “Add”.
Escribir el siguiente código en la clase:
Public Class FormatoDecimal
Implements IValueConverter
Public Function Convert(ByVal value As Object, _
ByVal targetType As [Link], ByVal parameter As Object, _
ByVal culture As [Link]) As Object _
Implements [Link]
Return ([Link]("{0:n2}", value))
End Function
Public Function ConvertBack(ByVal value As Object, _
ByVal targetType As [Link], ByVal parameter As Object, _
ByVal culture As [Link]) As Object _
Implements [Link]
Return ([Link]("{0:n2}", value))
End Function
End Class
Agregar una clase para la conversión a solo fecha: del menú “Project”,
seleccionar “Add Class”, escribir como nombre: “[Link]” y
clic en “Add”.
Luis Dueñas Pag 678
La Biblia de Visual Basic .NET
Escribir el siguiente código en la clase FormatoFecha:
Public Class FormatoFecha
Implements IValueConverter
Public Function Convert(ByVal value As Object, _
ByVal targetType As [Link], ByVal parameter As Object, _
ByVal culture As [Link]) As Object _
Implements [Link]
Return ([Link]("{0:d}", value))
End Function
Public Function ConvertBack(ByVal value As Object, _
ByVal targetType As [Link], ByVal parameter As Object, _
ByVal culture As [Link]) As Object _
Implements [Link]
Return ([Link]("{0:d}", value))
End Function
End Class
Cerrar las ventanas con las 2 clases y compilar la aplicación para poder
definir un recurso que apunte a las clases creadas.
Cambiar de nombre a la ventana “[Link]” por “ListaDetalles
[Link]”.
Escribir el siguiente código en el archivo xaml:
<Window x:Class="ListaDetallesOrden"
xmlns="[Link]
xmlns:x="[Link]
xmlns:ld="clr-namespace:Demo95"
Title="Plantilla de Datos Jerárquica en control TreeView"
Height="400" Width="400" ResizeMode="CanResize"
WindowStartupLocation="CenterScreen"
Name="ListaDetallesOrden"
WindowState="Maximized">
<[Link]>
<ld:FormatoFecha x:Key="ff"/>
<ld:FormatoDecimal x:Key="fd"/>
<HierarchicalDataTemplate x:Key="hdtOrden"
Luis Dueñas Pag 679
La Biblia de Visual Basic .NET
ItemsSource="{Binding Path=ListaDetalles}">
<DockPanel>
<TextBlock Text="{Binding Path=IdOrden}"
Width="80" Foreground="White" />
<TextBlock Text="{Binding Path=NombreCliente}"
Width="200" Foreground="White"/>
<TextBlock Text="{Binding Path=NombreEmpleado}"
Width="150" Foreground="White"/>
<TextBlock Text="{Binding Path=FechaOrden,
Converter={StaticResource ff}}"
Width="70" Foreground="White"/>
</DockPanel>
<[Link]>
<DataTemplate>
<Grid>
<[Link]>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="240"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="50"/>
</[Link]>
<Label [Link]="0" Foreground="Yellow"
Content="{Binding Path=IdProducto}"/>
<Label [Link]="2" Foreground="Yellow"
Content="{Binding Path=NombreProducto}" />
<Label [Link]="4" Foreground="Yellow"
Content="{Binding Path=PrecioUnitario,
Converter={StaticResource fd}}"
HorizontalContentAlignment="Right"/>
<Label [Link]="6" Foreground="Yellow"
Content="{Binding Path=Cantidad}"
HorizontalContentAlignment="Right"/>
<Label [Link]="8" Foreground="Yellow"
Content="{Binding Path=PrecioTotal,
Converter={StaticResource fd}}"
Luis Dueñas Pag 680
La Biblia de Visual Basic .NET
HorizontalContentAlignment="Right"/>
</Grid>
</DataTemplate>
</[Link]>
</HierarchicalDataTemplate>
</[Link]>
<Grid>
<TreeView Name="tvwOrden"
ItemTemplate="{StaticResource hdtOrden}">
<[Link]>
<LinearGradientBrush>
<GradientStop Color="aqua" Offset="0.8"/>
<GradientStop Color="blue" Offset="0.4"/>
</LinearGradientBrush>
</[Link]>
</TreeView>
</Grid>
</Window>
Nota: En el código anterior se definen 2 recursos para conversión de
datos: fd para FormatoDecimal y ff para FormatoFecha; también se define
una plantilla de datos jerárquica llamada hdtOrden con 4 columnas para la
cabecera: Id de órden, nombre del cliente, nombre del empleado y fecha
de la orden y 5 columnas para los detalles: Id del producto, nombre del
producto, precio unitario, cantidad y precio total. Esta plantilla se aplica al
control TreeView en su propiedad ItemTemplate.
El diseño de la ventana debe quedar como se ve en el gráfico 6.29.
Luis Dueñas Pag 681
La Biblia de Visual Basic .NET
Gráfico 6.29: Diseño de la ventana Lista de Detalles de Ordenes
Escribir código en el archivo vb asociado al xaml:
Imports [Link]
Imports [Link]
Class ListaDetallesOrden
Private Sub CargarDatos(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Try
Dim obrOrden As New brOrden
Dim lobeOrden As List(Of beOrden) = [Link]
[Link] = lobeOrden
Catch ex As Exception
End Try
End Sub
End Class
Nota: En el código anterior al cargar la ventana se llena la lista de órdenes
donde cada órden tiene una lista de detalles y se enlaza la propiedad
ItemsSource del TreeView a la lista de órdenes.
Luis Dueñas Pag 682
La Biblia de Visual Basic .NET
Regresar a la ventana “[Link]” y cambiar la ventana que
inicia (atributo StartupUri) a “[Link]”.
Agregar un archivo de configuración a la aplicación: del menú “Project”,
seleccionar “Add New Item”, en la categoría “General” seleccionar
“Application Configuration File”.
Agregar en el archivo de configuración la clave conNW en la sección
appSettings:
<configuration>
<appSettings>
<add key="conNW" value="uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 6.30: Ejecución de la ventana Lista de Detalles de Ordenes
Luis Dueñas Pag 683
La Biblia de Visual Basic .NET
2.5. Usando el Control DataGrid
Hasta antes de la versión 2010 la única forma de mostrar un conjunto de
datos en filas y varias columnas era usar el ListView o aplicar una plantilla
al ListBox para que tenga varias columnas. Con .NET Framework 4 y Visual
Studio 2010 WPF trae el nuevo control DataGrid que simplifica este punto.
El control DataGrid proporciona una forma flexible de mostrar una
colección de datos en filas y columnas. El DataGrid incluye tipos de
columna integradas y una columna de plantilla para hospedar contenido
personalizado. El tipo de fila integrado incluye una sección de detalles
desplegable que se puede utilizar para mostrar contenido adicional debajo
de los valores de celda.
Para enlazar el DataGrid, configure la propiedad ItemsSource a un origen
de datos. Cada fila de la cuadrícula de datos se enlaza a un objeto en el
origen de datos, y cada columna de la cuadrícula de datos se enlaza a una
propiedad del objeto de datos.
De manera predeterminada, el control DataGrid genera automáticamente
columnas cuando se establece la propiedad ItemsSource. El tipo de
columna que se genera depende del tipo de datos de la columna. Los tipos
de columnas en el DataGrid pueden ser: DataGridTextColumn, DataGrid
CheckBoxColumn y DataGridComboBoxColumn.
Puede personalizar las columnas del DataGrid usando la propiedad
AutoGenerateColumns configurándola en false y creando sus propias
columnas, además puede personalizar el estilo usando la propiedad Style o
cambiar el aspecto de todo el control usando ControlTemplate.
Para obtener más información sobre el control DataGrid de WPF ver la
referencia 42 al final del libro.
A continuación un ejemplo de cómo crear columnas personalizadas en el
DataGrid para mostrar el código, nombre, precio unitario y stock de los
productos, alineando el precio y stock a la derecha y formateando a 2
decimales el precio.
Luis Dueñas Pag 684
La Biblia de Visual Basic .NET
Demo 96
Crear una nueva aplicación Windows WPF: del menú “File”, seleccionar
“New Project”.
En el diálogo elegir “Visual Basic”, luego “Windows”, seleccionar “WPF
Application”.
Escribir en el nombre de la aplicación “Demo96” y clic en “OK”.
Hacer una referencia a las librerías [Link] y
[Link].
Crear una clase para la conversión a 2 decimales: del menú “Project”,
seleccionar “Add Class”, escribir como nombre: “[Link]” y
clic en “Add”.
Escribir el siguiente código en la clase:
Public Class FormatoDecimal
Implements IValueConverter
Public Function Convert(ByVal value As Object, _
ByVal targetType As [Link], ByVal parameter As Object, _
ByVal culture As [Link]) As Object _
Implements [Link]
Return ([Link]("{0:n2}", value))
End Function
Public Function ConvertBack(ByVal value As Object, _
ByVal targetType As [Link], ByVal parameter As Object, _
ByVal culture As [Link]) As Object _
Implements [Link]
Return ([Link]("{0:n2}", value))
End Function
End Class
Cerrar la ventana con la clase creada y compilar la aplicación para
poder definir un recurso que permita usar la clase.
Luis Dueñas Pag 685
La Biblia de Visual Basic .NET
Cambiar de nombre a la ventana “[Link]” por “Lista
[Link]”.
Escribir el siguiente código en el archivo xaml:
<Window x:Class="ListaProductos"
xmlns="[Link]
xmlns:x="[Link]
xmlns:ld="clr-namespace:Demo96"
Title="Lista de Productos usando el control DataGrid"
Height="350" Width="525" ResizeMode="NoResize"
WindowStartupLocation="CenterScreen" >
<[Link]>
<ld:FormatoDecimal x:Key="fd"/>
</[Link]>
<Grid>
<DataGrid Name="dgProducto" AutoGenerateColumns="False">
<[Link]>
<LinearGradientBrush>
<GradientStop Color="Aqua" Offset="1"/>
<GradientStop Color="Green" Offset="0.5"/>
</LinearGradientBrush>
</[Link]>
<[Link]>
<DataGridTextColumn Header="Código" Width="60"
Binding="{Binding Path=Codigo}"/>
<DataGridTextColumn Header="Descripción" Width="250"
Binding="{Binding Path=Nombre}"/>
<DataGridTextColumn Header="Precio Unit" Width="80"
Binding="{Binding Path=PrecioUnitario,
Converter={StaticResource fd}}">
<[Link]>
<Style>
<Setter Property="FrameworkElement.
HorizontalAlignment"
Value="Right"/>
</Style>
</[Link]>
</DataGridTextColumn>
<DataGridTextColumn Header="Stock" Width="80"
Binding="{Binding Path=Stock}">
Luis Dueñas Pag 686
La Biblia de Visual Basic .NET
<[Link]>
<Style>
<Setter Property="FrameworkElement.
HorizontalAlignment"
Value="Right"/>
</Style>
</[Link]>
</DataGridTextColumn>
</[Link]>
</DataGrid>
</Grid>
</Window>
Nota: En el código anterior se define un recurso para conversión de datos
llamado fd para aplicar la clase FormatoDecimal y se incluye solo un control
DataGrid que define sus filas con un fondo degradado y 4 columnas, 2 de
las cuales tienen estilo para alinear a la derecha los datos.
El diseño de la ventana debe quedar como se ve en el gráfico 6.31.
Gráfico 6.31: Diseño de la ventana Lista de Productos
Escribir código en el archivo vb asociado al xaml:
Imports [Link]
Imports [Link]
Luis Dueñas Pag 687
La Biblia de Visual Basic .NET
Class ListaProductos
Private Sub ListarProductos(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim obrProducto As New brProducto
Dim lobeProducto As List(Of beProducto) = [Link]
[Link] = lobeProducto
End Sub
End Class
Nota: En el código anterior al cargar la ventana se llena la lista de
productos y se enlaza la propiedad ItemsSource del DataGrid a la lista de
productos.
Regresar a la ventana “[Link]” y cambiar la ventana que
inicia (atributo StartupUri) a “[Link]”.
Agregar un archivo de configuración a la aplicación: del menú “Project”,
seleccionar “Add New Item”, en la categoría “General” seleccionar
“Application Configuration File”.
Agregar en el archivo de configuración la clave conNW en la sección
appSettings:
<configuration>
<appSettings>
<add key="conNW" value="uid=sa;pwd=123456;
data source=Lduenas\MCTS;initial catalog=Northwind"/>
</appSettings>
</configuration>
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Luis Dueñas Pag 688
La Biblia de Visual Basic .NET
Gráfico 6.32: Ejecución de la ventana Lista de Productos
Importante: Por defecto el DataGrid trae incorporado la funcionalidad de
ordenar cada columna en forma ascendente y descendente al dar clic a las
cabeceras de las columnas.
Luis Dueñas Pag 689
La Biblia de Visual Basic .NET
3. Manejando Documentos
En esta parte trataremos el manejo de documentos en WPF, iniciando con
una revisión de las capacidades de manejo de documentos que tiene WPF
que incluyen los documentos estáticos, documentos dinámicos, controles
para manejo de documentos, anotaciones, documentos XPS, etc.
Luego pasaremos a manejar los documentos fijos que mantienen siempre
el contenido aunque cambie el tamaño de la ventana o la resolución de la
pantalla, para lo cual veremos el control DocumentViewer. En esta parte
veremos como trabajar con documentos XPS mediante la clase
XpsDocument y el control DocumentViewer, aquí crearemos como ejemplo
un visor de archivos XPS.
Seguidamente veremos como trabajar con anotaciones en WPF que
incluyen las notas rápidas y el resaltado de texto, aquí crearemos como
ejemplo un visor para archivos de Word y Excel, a los cuales le podremos
incluir las anotaciones.
Finalmente, se verá el trabajo con documentos dinámicos usando los
controles FlowDocumentReader, FlowDocumentPageViewer y Flow
DocumentScrollViewer, aquí crearemos como ejemplo un visor de archivos
de texto.
Luis Dueñas Pag 690
La Biblia de Visual Basic .NET
3.1. Introducción al Manejo de Documentos
WPF permite el manejo de documentos lo cual incluye la presentación, el
empaquetado y la seguridad. Para esto clasifica a los documentos en 2
categorías: fijos y dinámicos.
Los documentos fijos son aquéllos que mantienen su ubicación y tamaño
sin importar el dispositivo, es decir son del tipo “Lo que se ve es lo que se
obtiene” o sus siglas en inglés WYSIWYG (What You See Is What You
Get), entre sus usos tenemos las publicaciones, procesamiento de texto,
diseño de formularios, etc, donde lo que se en pantalla es lo mismo que
saldrá impreso.
Por su parte los documentos dinámicos se ajustan o cambian de ubicación
y tamaño de acuerdo al tamaño de la ventana, la resolución de la pantalla,
etc, con el objetivo principal de facilitar la lectura al usuario. Además, los
documentos dinámicos tienen varias características integradas que
incluyen la búsqueda, modos de presentación que optimizan la legibilidad y
la capacidad de cambiar el tamaño y aspecto de las fuentes.
WPF tiene controles que permiten visualizar documentos; para los
documentos fijos se usa el control DocumentViewer que muestra contenido
de tipo FixedDocument y para los documentos dinámicos se tienen los
controles: FlowDocumentReader, FlowDocumentPageViewer y Flow
DocumentScrollViewer, de ellos el primero permite elegir varios tipos de
visualización de página.
También podemos incluir en nuestros documentos comentarios o
“anotaciones” para agregar notas rápidas o resaltar información de interés
usando Microsoft Annotations Framework.
Finalmente, WPF permite trabajar con documentos XPS (XML Paper
Specification) que son documentos fijos y que se usa como formato de
impresión nativa en Windows Vista, para lo cual se tiene la clase
XpsDocument que se encuentra en [Link].
Para obtener más información sobre Documentos en WPF ver la referencia
43 al final del libro.
Luis Dueñas Pag 691
La Biblia de Visual Basic .NET
3.2. Trabajando con Documentos Fijos
Según Microsoft: “Los documentos fijos están diseñados para las
aplicaciones que requieren una presentación What You See Is What You
Get (WYSIWYG) precisa, independiente del hardware de pantalla o de
impresión utilizado”.
Los usos típicos para los documentos fijos incluyen la creación de
publicaciones, el procesamiento de textos y el diseño de formularios, donde
es vital que se respete el diseño de página original.
Un documento fijo mantiene la colocación posicional precisa de los
elementos de contenido con independencia del dispositivo de pantalla o de
impresión utilizado. El diseño de la página permanece inalterado en todos
los casos, aunque la calidad del documento se maximiza de acuerdo con las
funciones de cada dispositivo.
Por su parte, un documento XML Paper Specification (XPS) es un paquete
que contiene uno o más documentos fijos junto con todos los recursos y la
información necesarios para la presentación.
XPS también es el formato de archivo nativo de cola de impresión de
Windows Vista. XpsDocument se almacena en el conjunto de datos ZIP
estándar, y puede incluir una combinación de XML y componentes binarios,
como imágenes y archivos de fuente.
La clase XpsDocument tiene los siguientes usos:
Lectura, escritura y almacenamiento de contenido y recursos de
documentos fijos en un único archivo portátil y fácil de distribuir.
Presentación de documentos con la aplicación Visor de XPS.
Generación de documentos en el formato de salida de cola de
impresión de Windows Vista.
Enrutamiento directo de documentos a las impresoras compatibles con
XPS.
A continuación un ejemplo de cómo leer documentos fijos XPS en WPF.
Luis Dueñas Pag 692
La Biblia de Visual Basic .NET
Demo 97
Crear una nueva aplicación Windows WPF: del menú “File”, seleccionar
“New Project”.
En el diálogo elegir “Visual Basic”, luego “Windows”, seleccionar “WPF
Application”.
Escribir en el nombre de la aplicación “Demo97” y clic en “OK”.
Hacer una referencia a la librería donde está Xps: del menú “Project”,
seleccionar “Add References”, del diálogo elegir: “ReachFramework”.
Gráfico 6.33: Diálogo de Referencia de la librería ReachFramework
Cambiar de nombre a la ventana “[Link]” por “Visor
[Link]”.
Escribir el siguiente código en el archivo xaml:
<Window x:Class="VisorXPS"
xmlns="[Link]
xmlns:x="[Link]
Title="Visor de documentos XPS" Height="500" Width="600"
ResizeMode="NoResize"
Luis Dueñas Pag 693
La Biblia de Visual Basic .NET
WindowStartupLocation="CenterScreen">
<Grid>
<[Link]>
<RowDefinition Height="50"/>
<RowDefinition Height="400*"/>
</[Link]>
<DockPanel [Link]="0" VerticalAlignment="Center"
HorizontalAlignment="Center">
<TextBlock Text="Selecciona archivo XPS: "/>
<TextBox Name="txtArchivo" Width="400"/>
<Button Name="btnAbrir" Content="..." Width="25"
Cursor="Hand" ToolTip="Abrir archivo XPS"/>
</DockPanel>
<DocumentViewer Name="dvXPS" [Link]="1">
<[Link]>
<LinearGradientBrush>
<GradientStop Color="Aqua" Offset="1"/>
<GradientStop Color="LightBlue" Offset="0.5"/>
</LinearGradientBrush>
</[Link]>
</DocumentViewer>
</Grid>
</Window>
Nota: En el código anterior se definen 2 filas para el Grid, en la primera va
un DockPanel que contiene un bloque de texto con un mensaje, un cuadro
de texto y un botón para mostrar el diálogo de abrir para seleccionar el
archivo XPS. En la segunda fila va el DocumentViewer que tiene un fondo
degradado.
El diseño de la ventana debe quedar como se ve en el gráfico 6.34.
Luis Dueñas Pag 694
La Biblia de Visual Basic .NET
Gráfico 6.34: Diseño de la ventana Visor de XPS
Escribir código en el archivo vb asociado al xaml:
Imports Microsoft.Win32 'OpenFileDialog
Imports [Link] 'FileAccess
Imports [Link] 'XpsDocument
Class VisorXPS
Private Sub AbrirArchivoXPS(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim ofd As New OpenFileDialog
[Link] = "Selecciona archivo XPS a abrir"
[Link] = "Archivos de documentos XPS|*.xps"
If [Link] = True Then
[Link] = [Link]
Dim xps As New XpsDocument([Link], [Link])
[Link] = [Link]
End If
End Sub
End Class
Luis Dueñas Pag 695
La Biblia de Visual Basic .NET
Nota: En el código anterior al dar clic en el botón “Abrir” se muestra el
diálogo de abrir con archivos XPS, al elegir uno se crea un objeto
XpsDocument para enlazar el archivo al visor.
Importante: Para enlazar el documento XPS al visor (DocumentViewer) se
usa la propiedad Document que recibe un FixedDocument el cual se
obtiene a través del método GetFixedDocumentSequence del objeto
XpsDocument.
Regresar a la ventana “[Link]” y cambiar la ventana que
inicia (atributo StartupUri) a “[Link]”.
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 6.35: Ejecución de la ventana Visor de XPS
Luis Dueñas Pag 696
La Biblia de Visual Basic .NET
3.3. Creando Anotaciones en Documentos
Las anotaciones permiten aumentar comentarios a ciertas partes del texto
de un documento y puede ser de 3 tipos: una nota rápida, un resaltado o
una nota de tinta. Los controles WPF de visualización de documentos ya
sean fijos como el DocumentViewer o dinámicos como el FlowDocument
Reader, FlowDocumentPageViewer y FlowDocumentScrollViewer permiten
anotaciones.
Para implementar anotaciones en documentos es necesario usar la clase
AnnotationService ubicada en el espacio de nombres [Link].
Annotations y luego se podrá crear un resaltado con CreateHighlight
Command o una nota rápida con CreateTextStickyNoteCommand o una
nota de tinta con CreateInkStickyNoteCommand.
Para quitar los resaltados se usa ClearHighlightsCommand, para eliminar
notas de texto rápidas se usa DeleteStickyNotesCommand y para eliminar
todas las anotaciones del documento se usa DeleteAnnotationsCommand.
Para crear una anotación, el usuario suele seleccionar primero algún texto
o elemento de interés y, a continuación, hacer clic con el botón secundario
del mouse para mostrar un ContextMenu de opciones de anotación.
Para obtener más información sobre Anotaciones en WPF ver la referencia
44 al final del libro.
A continuación un ejemplo que demuestra como crear y eliminar
anotaciones en documentos de Word y Excel usando un visor de
documentos creado convirtiendo dichos archivos en archivos XPS y luego
visualizándolos mediante el DocumentViewer usando para ello la clase
XpsDocument.
En el ejemplo una vez seleccionado el archivo de Word o Excel y convertido
a XPS, debe seleccionar un texto, palabra o párrafo y dar clic derecho para
mostrar un menú contextual con las opciones de anotaciones, ya sea para
crear o para eliminar.
Luis Dueñas Pag 697
La Biblia de Visual Basic .NET
Demo 98
Crear una nueva aplicación Windows WPF: del menú “File”, seleccionar
“New Project”.
En el diálogo elegir “Visual Basic”, luego “Windows”, seleccionar “WPF
Application”.
Escribir en el nombre de la aplicación “Demo98” y clic en “OK”.
Hacer una referencia a la librería donde está Xps: del menú “Project”,
seleccionar “Add References”, del diálogo elegir: “ReachFramework”.
Cambiar de nombre a la ventana “[Link]” por “Visor
[Link]”.
Escribir el siguiente código en el archivo xaml:
<Window x:Class="VisorOffice"
xmlns="[Link]
xmlns:x="[Link]
xmlns:ann="clr-namespace:[Link];assembly=
PresentationFramework"
Title="Visor de documentos Office" Height="500" Width="600"
ResizeMode="NoResize"
WindowStartupLocation="CenterScreen">
<Grid>
<[Link]>
<RowDefinition Height="50"/>
<RowDefinition Height="400*"/>
</[Link]>
<DockPanel [Link]="0" VerticalAlignment="Center"
HorizontalAlignment="Center">
<TextBlock Text="Selecciona archivo Office: "/>
<TextBox Name="txtArchivo" Width="400"/>
<Button Name="btnAbrir" Content="..." Width="25"
Cursor="Hand" ToolTip="Abrir archivo XPS"/>
</DockPanel>
<DocumentViewer Name="dvXPS" [Link]="1">
<[Link]>
<LinearGradientBrush>
Luis Dueñas Pag 698
La Biblia de Visual Basic .NET
<GradientStop Color="Aqua" Offset="1"/>
<GradientStop Color="LightBlue" Offset="0.5"/>
</LinearGradientBrush>
</[Link]>
<[Link]>
<ContextMenu>
<MenuItem Command="[Link]" />
<Separator />
<MenuItem Command="ann:AnnotationService.
CreateHighlightCommand"
Header="Adicionar Resaltado" />
<MenuItem Command="ann:AnnotationService.
CreateTextStickyNoteCommand"
Header="Adicionar Nota de Texto" />
<MenuItem Command="ann:AnnotationService.
CreateInkStickyNoteCommand"
Header="Adicionar Nota Tinta" />
<Separator />
<MenuItem Command="ann:AnnotationService.
ClearHighlightsCommand"
Header="Eliminar Resaltado" />
<MenuItem Command="ann:AnnotationService.
DeleteStickyNotesCommand"
Header="Eliminar Notas" />
<MenuItem Command="ann:AnnotationService.
DeleteAnnotationsCommand"
Header="Eliminar Todo" />
</ContextMenu>
</[Link]>
</DocumentViewer>
</Grid>
</Window>
Nota: En el código anterior se definen 2 filas para el Grid, en la primera va
un DockPanel que contiene un bloque de texto con un mensaje, un cuadro
de texto y un botón para mostrar el diálogo de abrir para seleccionar el
archivo doc o xls. En la segunda fila va el DocumentViewer que tiene un
fondo degradado y un menú contextual con 7 opciones, una para copiar, 3
para agregar anotaciones y 3 para eliminar anotaciones.
El diseño de la ventana debe quedar como se ve en el gráfico 6.36.
Luis Dueñas Pag 699
La Biblia de Visual Basic .NET
Gráfico 6.36: Diseño de la ventana Visor de Office
Escribir código en el archivo vb asociado al xaml:
Imports Microsoft.Win32 'OpenFileDialog
Imports [Link] 'FileAccess
Imports [Link] 'XpsDocument
Imports [Link] 'Marshal
Imports [Link] 'AnnotationService
Imports [Link] 'XmlStreamStore
Class VisorOffice
Private Sub AbrirArchivoOffice(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim ofd As New OpenFileDialog
[Link] = "Selecciona archivo Office a abrir"
[Link] = "Archivos de Office|*.doc;*.xls"
If [Link] = True Then
[Link] = [Link]
Dim docXPS As String = [Link]("{0}\{1}.xps", _
[Link]([Link]), _
Luis Dueñas Pag 700
La Biblia de Visual Basic .NET
[Link]([Link]))
If [Link]([Link]) = ".doc" Then
Dim oWord As Object = CreateObject("[Link]")
Dim oDocumentos As Object = [Link]
Dim oDocumento As Object = [Link]([Link])
[Link](docXPS, 18)
[Link](True)
[Link](oDocumento)
oDocumento = Nothing
[Link](oDocumentos)
oDocumentos = Nothing
[Link]()
[Link](oWord)
oWord = Nothing
Else
Dim oExcel As Object = CreateObject("[Link]")
Dim oLibros As Object = [Link]
Dim oLibro As Object = [Link]([Link])
Dim oHoja As Object = [Link]
[Link](1, docXPS)
[Link](oHoja)
oHoja = Nothing
[Link](True)
[Link](oLibro)
oLibro = Nothing
[Link](oLibros)
oLibros = Nothing
[Link]()
[Link](oExcel)
oExcel = Nothing
End If
Dim xps As New XpsDocument(docXPS, [Link])
[Link] = [Link]
Dim fs As New FileStream("[Link]", [Link], _
[Link])
Dim X As AnnotationService = New AnnotationService(dvXPS)
Dim data As XmlStreamStore = New XmlStreamStore(fs)
If [Link] Then
[Link]()
End If
Luis Dueñas Pag 701
La Biblia de Visual Basic .NET
[Link](data)
End If
End Sub
End Class
Nota: En el código anterior al dar clic en el botón “Abrir” se muestra el
diálogo de abrir con archivos doc y xls, dependiendo del tipo de archivo a
abrir se crea una instancia de Word o de Excel y se usa el método
ExportAsFixedFormat para convertir el archivo en XPS, luego se crea un
XpsDocument con dicho archivo y se enlaza al visor, finalmente se habilita
las anotaciones sobre el documento.
Importante: Si se crea instancias de Word o Excel mediante código, es
necesario definir explícitamente todas los objetos usados y luego cerrarlos
y liberarlos de memoria, sino se queda “pegado” el ejecutable en memoria.
Regresar a la ventana “[Link]” y cambiar la ventana que
inicia (atributo StartupUri) a “[Link]”.
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 6.37: Ejecución de la ventana Visor de Office
Luis Dueñas Pag 702
La Biblia de Visual Basic .NET
3.4. Trabajando con Documentos Dinámicos
Según Microsoft: “los documentos dinámicos están diseñados para
optimizar su presentación y legibilidad y son óptimos para su uso cuando la
facilidad de lectura constituye el principal escenario de consumo del
documento”.
En lugar de establecerse en un diseño predefinido, este tipo de
documentos ajusta y recoloca dinámicamente su contenido basándose en
las variables de tiempo de ejecución, tales como el tamaño de la ventana,
la resolución del dispositivo y las preferencias opcionales del usuario.
Una página web constituye un ejemplo sencillo de un documento dinámico
donde se da formato al contenido de la página dinámicamente para
ajustarlo a la ventana activa.
Para mostrar un documento dinámico, WPF tiene 3 controles:
FlowDocumentReader: Tiene distintos modos de visualización, incluido
el modo de visualización de una sola página (una página a la vez), dos
páginas a la vez (formato de lectura de libro) y desplazamiento
continuo (sin límite).
FlowDocumentPageViewer: Muestra el contenido en el modo de
visualización de una sola página.
FlowDocumentScrollViewer: Muestra el contenido en modo de desplaza
miento continuo.
Nota: De manera predeterminada, se muestra siempre una barra de
desplazamiento vertical y la barra de desplazamiento horizontal se vuelve
visible cuando es necesario. La IU predeterminada para FlowDocument
ScrollViewer no incluye barra de herramientas; sin embargo, se puede
utilizar la propiedad IsToolBarVisible para habilitar una barra de
herramientas integrada.
A continuación un ejemplo de visualización de documentos dinámicos de
tipo texto: txt, xml, html mediante el control FlowDocumentReader que
permite ver el documento de varias formas.
Luis Dueñas Pag 703
La Biblia de Visual Basic .NET
Demo 99
Crear una nueva aplicación Windows WPF: del menú “File”, seleccionar
“New Project”.
En el diálogo elegir “Visual Basic”, luego “Windows”, seleccionar “WPF
Application”.
Escribir en el nombre de la aplicación “Demo99” y clic en “OK”.
Cambiar de nombre a la ventana “[Link]” por “Visor
[Link]”.
Escribir el siguiente código en el archivo xaml:
<Window x:Class="VisorTexto"
xmlns="[Link]
xmlns:x="[Link]
Title="Visor de archivos de Texto: Txt, Xml y Html"
Height="500" Width="600"
WindowStartupLocation="CenterScreen">
<Grid>
<[Link]>
<RowDefinition Height="50"/>
<RowDefinition Height="400*"/>
</[Link]>
<DockPanel [Link]="0" VerticalAlignment="Center"
HorizontalAlignment="Center">
<TextBlock Text="Selecciona archivo Texto: "/>
<TextBox Name="txtArchivo" Width="400"/>
<Button Name="btnAbrir" Content="..." Width="25"
Cursor="Hand" ToolTip="Abrir archivo XPS"/>
</DockPanel>
<FlowDocumentReader Name="fdrTexto" [Link]="1" />
</Grid>
</Window>
Nota: En el código anterior se definen 2 filas para el Grid, en la primera va
un DockPanel que contiene un bloque de texto con un mensaje, un cuadro
de texto y un botón para mostrar el diálogo de abrir para seleccionar el
archivo txt, xml o html. En la segunda fila va el FlowDocumentReader.
Luis Dueñas Pag 704
La Biblia de Visual Basic .NET
El diseño de la ventana debe quedar como se ve en el gráfico 6.38.
Gráfico 6.38: Diseño de la ventana Visor de Texto
Escribir código en el archivo vb asociado al xaml:
Imports Microsoft.Win32 'OpenFileDialog
Imports [Link] 'FileAccess
Imports [Link] 'Encoding
Imports [Link] 'FlowDocument,Paragraph
Class VisorTexto
Private Sub AbrirArchivoTexto(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim ofd As New OpenFileDialog
[Link] = "Selecciona archivo de texto a abrir"
[Link] = "Archivos de texto txt, xml y html|*.txt;*.xml;*.html"
If [Link] = True Then
[Link] = [Link]
Dim Contenido() As String = [Link] _
([Link], [Link])
Dim parrafo As New Paragraph
For I = 0 To [Link] - 1
Luis Dueñas Pag 705
La Biblia de Visual Basic .NET
[Link](Contenido(I))
Next
Dim fd As New FlowDocument(parrafo)
[Link] = fd
End If
End Sub
End Class
Nota: En el código anterior al dar clic en el botón “Abrir” se muestra el
diálogo de abrir con archivos txt, xml y html, al seleccionar un archivo se
lee todas sus líneas y se hace un recorrido por cada una para agregarla a la
colección de líneas del objeto párrafo y finalmente se crea un objeto Flow
Document pasando como parámetro el párrafo, éste es enlazado a la
propiedad document del visor (FlowDocumentReader).
Regresar a la ventana “[Link]” y cambiar la ventana que
inicia (atributo StartupUri) a “[Link]”.
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 6.39: Ejecución de la ventana Visor de Office
Luis Dueñas Pag 706
La Biblia de Visual Basic .NET
4. Manejando Multimedia
En esta última parte veremos cómo trabajar con Multimedia en WPF, es
decir con voz, audio y video. Para esto primero daremos una introducción
al manejo de multimedia en WPF, revisando las APIs Multimedia que básica
mente constan de dos clases que son MediaElement y MediaPlayer.
Además conoceremos los modos de reproducción que son el modo
independiente y el modo reloj (Clock).
Seguidamente, veremos como usando la librería [Link]
podemos implementar el reconocimiento de voz en nuestras aplicaciones
mejorando la accesibilidad. Especificamente, usaremos la clase Speech
Synthesizer que se encuentra en el espacio de nombres [Link].
Synthesis.
Con esta clase podremos reproducir la voz usando métodos como Speak o
su correspondiente versión asíncrona que es SpeakAsync. Además
podremos controlar las características de la voz como la velocidad usando
la propiedad Rate o el volúmen usando la propiedad Volume.
Finalmente, trataremos como reproducir audio y video usando la clase
MediaElement que tiene la propiedad Source para especificar la URI con el
archivo a reproducir, el método Play que permite reproducir el audio o
video y programar en los eventos MediaOpened que ocurre cuando inicia la
reproducción y MediaEnded que ocurre cuando finaliza la reproducción.
Todos estos temas se entenderán mejor con los ejemplos que incluyen un
reproductor de voz, un reproductor de sonido o audio y un reproductor de
video para dar un final feliz a esta obra.
Luis Dueñas Pag 707
La Biblia de Visual Basic .NET
4.1. Introducción al Manejo de Multimedia
Las características multimedia de WPF permiten integrar audio y vídeo en
las aplicaciones para mejorar la experiencia del usuario.
APIs Multimedia
Las clases MediaElement y MediaPlayer se utilizan para presentar contenido
de audio o vídeo. Estas clases se pueden controlar interactivamente o
mediante un reloj. Estas clases pueden utilizar el control Microsoft Windows
Media Player 10 para la reproducción multimedia. La clase que se utiliza
depende del escenario.
MediaElement es una clase UIElement compatible con sistema de diseño
que se puede utilizar como contenido de muchos [Link]én se
puede utilizar en Extensible Application Markup Language (XAML), así como
en el código. MediaPlayer, por otro lado, está diseñado para los objetos
Drawing y carece de compatibilidad de diseño. Los objetos multimedia
cargados mediante MediaPlayer únicamente se pueden presentar utilizando
VideoDrawing o interactuando directamente con DrawingContext. Media
Player no se puede utilizar en XAML.
Modos de Reproducción Multimedia
Para entender la reproducción multimedia en WPF, es preciso entender los
distintos modos en que se pueden reproducir los objetos multimedia.
MediaElement y MediaPlayer se pueden utilizar en dos modos multimedia
diferentes: el modo independiente y el modo de reloj.
El modo multimedia se determina mediante la propiedad Clock. Cuando
Clock es null, el objeto multimedia está en modo independiente. Cuando
Clock no es null, el objeto multimedia está en modo de reloj. De manera
predeterminada, los objetos multimedia están en modo independiente.
Para obtener más información sobre multimedia ver la referencia 45 al final
del libro.
Luis Dueñas Pag 708
La Biblia de Visual Basic .NET
4.2. Implementando Voz
Aunque no es parte del Framework de WPF sino de .NET Framework,
incluir voz es una característica multimedia que nos ayuda a aumentar la
accesibilidad a las aplicaciones sobre todo para aquéllas personas que
tienen dificultades con la vista, o también para juegos, programas de
instrucciones, etc.
Existe el espacio de nombres [Link] que contienen tipos de
admiten el reconocimiento de voz, la cual se divide en los espacios de
nombres: AudioFormat, Recognition y Synthesis. Esta última es la que nos
permite implementar voz en nuestras aplicaciones.
La clase SpeechSynthesizer tiene métodos como Speak y SpeakAsync
que permiten emitir voz; la diferencia es que Speak no es asíncrono, es
decir mientras reproduce la voz la IU queda detenida hasta que termine,
mientras SpeakAsync es asíncrono, es decir no detiene la IU mientras
reproduce el sonido ya que ejecuta otro subproceso.
Esta clase también tiene propiedades como Volume que controla el
volumen de la voz y va en el rango de enteros de 0 a 100, también
podemos controlar la velocidad con que se pronuncia la voz usando la
propiedad Rate que va en el rango de enteros de -10 a 10.
En resumen, es muy fácil incluir la reproducción de voz en nuestras
aplicaciones, tal como se demuestra en el siguiente ejemplo en la cual se
crea un reproductor de voz que pronuncia cualquier palabra o frase escrita
y donde podemos controlar su velocidad y su volumen usando para ello los
controles Slider de WPF.
Luis Dueñas Pag 709
La Biblia de Visual Basic .NET
Demo 100
Crear una nueva aplicación Windows WPF: del menú “File”, seleccionar
“New Project”.
En el diálogo elegir “Visual Basic”, luego “Windows”, seleccionar “WPF
Application”.
Escribir en el nombre de la aplicación “Demo100” y clic en “OK”.
Agregar una referencia a la librería de reconocimiento de voz: del menú
“Project”, seleccionar “Add References” y del diálogo elegir “System.
Speech”.
Gráfico 6.40: Diálogo de Referencia de la librería Speech
Cambiar de nombre a la ventana “[Link]” por “Reproductor
[Link]”.
Escribir el siguiente código en el archivo xaml:
<Window x:Class="ReproductorVoz"
xmlns="[Link]
xmlns:x="[Link]
Title="Reproductor de Voz en WPF" Height="200" Width="300"
Luis Dueñas Pag 710
La Biblia de Visual Basic .NET
WindowStartupLocation="CenterScreen" ResizeMode="NoResize">
<Grid>
<[Link]>
<RadialGradientBrush>
<GradientStop Color="Yellow" Offset="1"/>
<GradientStop Color="Orange" Offset="0.5"/>
</RadialGradientBrush>
</[Link]>
<StackPanel VerticalAlignment="Center">
<TextBlock Name="tbMensaje" Text="Ingresa el Texto a Reproducir"
FontSize="14" HorizontalAlignment="Center"/>
<TextBox Name="txtFrase" Width="250"/>
<Button Name="btnReproducir" Content="Reproducir" Width="100"
Cursor="Hand" ToolTip="Reproducir voz del texto escrito"/>
<TextBlock Name="tbVolumen" Text="Volúmen"/>
<Slider Name="sldVolumen" Minimum="0" Maximum="100"/>
<TextBlock Name="tbVelocidad" Text="Velocidad"/>
<Slider Name="sldVelocidad" Minimum="-10" Maximum="10"/>
</StackPanel>
</Grid>
</Window>
Nota: En el código anterior se usa un Grid con fondo degradado en círculo
que tiene un StackPanel el cual contiene un bloque de texto con un
mensaje, un cuadro de texto para ingresar la frase, un botón para
reproducir y 2 bloques de textos y barras de desplazamiento para cambiar
el volumen y la velocidad de la voz.
El diseño de la ventana debe quedar como se ve en el gráfico 6.38.
Luis Dueñas Pag 711
La Biblia de Visual Basic .NET
Gráfico 6.41: Diseño de la ventana Reproductor de Voz
Escribir código en el archivo vb asociado al xaml:
Imports [Link] 'SpeechSynthesizer
Public Class ReproductorVoz
Private oVoz As New SpeechSynthesizer
Private Sub ReproducirVoz(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
[Link]([Link])
End Sub
Private Sub CambiarVolumen(ByVal sender As [Link], _
ByVal e As [Link](Of
[Link])) _
Handles [Link]
[Link] = [Link]
End Sub
Private Sub CambiarVelocidad(ByVal sender As [Link], _
ByVal e As [Link](Of
[Link])) _
Handles [Link]
[Link] = [Link]
End Sub
End Class
Nota: En el código anterior al dar clic en el botón “Reproducir” se llama al
método SpeakAsync del objeto SpeechSynthesizer para reproducir lo
Luis Dueñas Pag 712
La Biblia de Visual Basic .NET
escrito en el cuadro de texto. También al arrastrar las barras de
desplazamiento se cambia el volumen y la velocidad de la voz.
Regresar a la ventana “[Link]” y cambiar la ventana que
inicia (atributo StartupUri) a “[Link]”.
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 6.42: Ejecución de la ventana Reproductor de Voz
Nota: Cuando pruebe la reproducción notará que el traductor no pronuncia
tan bien el castellano y mejor lo hace en inglés.
Luis Dueñas Pag 713
La Biblia de Visual Basic .NET
4.3. Trabajando con Audio y Video
Agregar objetos multimedia a una aplicación es tan simple como agregar
un control MediaElement a la user interface (UI) de la aplicación y
proporcionar una clase Uri a los objetos multimedia que se desea incluir.
Todos los tipos de objetos multimedia que admite Microsoft Windows
Media Player 10 se admiten en WPF.
Las propiedades LoadedBehavior y UnloadedBehavior controlan el
comportamiento de MediaElement cuando IsLoaded es true o false,
respectivamente. La enumeración MediaState que establece el estado de
las propiedades afecta al comportamiento de reproducción multimedia.
Por ejemplo, el valor predeterminado de LoadedBehavior es Play y el valor
predeterminado de UnloadedBehavior es Close. Esto significa que, tan
pronto como se carga MediaElement y se completa el preprocesamiento, el
objeto multimedia empieza a reproducirse. Cuando se completa la
reproducción, se cierra el objeto multimedia y se liberan todos los recursos
multimedia.
Para especificar el archivo de sonido o video a reproducir hay que
configurar la propiedad Source del control MediaElement asignando la URI
con el archivo a reproducir.
Para reproducir el audio o video debemos usar el método Play del control
MediaElement e inmediatamente se desencadenará el evento MediaOpened
y cuando finaliza la reproducción ocurrirá el evento MediaEnded.
En el primer evento (MediaOpened) podemos determinar la duración del
audio o el video usando la propiedad NaturalDuration y en el último evento
(MediaEnded) podemos volver a iniciar la reproducción si se necesita.
En el siguiente ejemplo se muestra como reproducir una lista de archivos
de sonido y en el otro ejemplo se muestra como reproducir video mediante
el control MediaElement. Además en el último ejemplo se hace uso de un
reloj o Timer para WPF usando la clase DispatcherTimer.
Luis Dueñas Pag 714
La Biblia de Visual Basic .NET
Demo 101
Crear una nueva aplicación Windows WPF: del menú “File”, seleccionar
“New Project”.
En el diálogo elegir “Visual Basic”, luego “Windows”, seleccionar “WPF
Application”.
Escribir en el nombre de la aplicación “Demo101” y clic en “OK”.
Cambiar de nombre a la ventana “[Link]” por “Reproductor
[Link]”.
Escribir el siguiente código en el archivo xaml:
<Window x:Class="ReproductorSonido"
xmlns="[Link]
xmlns:x="[Link]
Title="Reproductor de Sonido en WPF" Height="420" Width="420"
ResizeMode="NoResize" WindowStartupLocation="CenterScreen">
<Grid Name="grdFondo">
<StackPanel>
<[Link]>
<LinearGradientBrush>
<GradientStop Color="Aqua" Offset="1"/>
<GradientStop Color="LightBlue" Offset="0.5"/>
</LinearGradientBrush>
</[Link]>
<Label Name="lblTitulo" HorizontalAlignment="Center"
FontSize="14">Selecciona archivos de sonido a reproducir</Label>
<DockPanel VerticalAlignment="Center"
HorizontalAlignment="Center">
<TextBox Name="txtArchivo" Width="350"/>
<Button Name="btnAbrir" Content="..." Width="25"
Cursor="Hand" ToolTip="Abrir archivo de sonido"/>
</DockPanel>
<ListBox Name="lstArchivo" Height="300">
<[Link]>
<RadialGradientBrush>
<GradientStop Color="Yellow" Offset="1"/>
<GradientStop Color="Orange" Offset="0.5"/>
Luis Dueñas Pag 715
La Biblia de Visual Basic .NET
</RadialGradientBrush>
</[Link]>
</ListBox>
<Button Name="btnReproducir" Content="Reproducir"
Cursor="Hand" Width="100" Height="25" IsEnabled="False" />
<MediaElement Name="meSonido" LoadedBehavior="Manual" />
</StackPanel>
</Grid>
</Window>
Nota: En el código anterior se usa un Grid que tiene un StackPanel con
fondo degradado el cual contiene un bloque de texto con un mensaje, un
DockPanel que tiene un cuadro de texto para el archivo seleccionado y un
botón para el diálogo de abrir, una lista para los archivos seleccionados de
audio la cual esta degradada en círculo, un botón para reproducir la lista y
finalmente un MediaElement para realizar la reproducción.
Importante: Es necesario iniciar la propiedad LoadBehaviour del control
MediaElement en Manual sino tratará de reproducir el video y ocurrirá error.
El diseño de la ventana debe quedar como se ve en el gráfico 6.43.
Gráfico 6.43: Diseño de la ventana Reproductor de Sonido
Luis Dueñas Pag 716
La Biblia de Visual Basic .NET
Escribir código en el archivo vb asociado al xaml:
Imports Microsoft.Win32 'OpenFileDialog
Class ReproductorSonido
Private C As Integer
Private Sub AgregarArchivoSonido(ByVal sender As [Link], _
ByVal e As [Link]) _
Handles [Link]
Dim ofd As New OpenFileDialog
[Link] = "Selecciona los archivos de sonido"
[Link] = "Archivos de sonido|*.mp3;*.wav"
If [Link] = True Then
[Link] = [Link]
[Link] = True
[Link]([Link])
End If
End Sub
Private Sub ReproducirLista(ByVal sender As [Link], _
ByVal e As [Link]) _
Handles [Link]
[Link]()
[Link] = 0
[Link] = New Uri([Link](C))
[Link]()
End Sub
Private Sub IniciarLista(ByVal sender As Object, _
ByVal e As [Link]) _
Handles [Link]
Dim duracion As TimeSpan = _
[Link]
[Link] = [Link]("Duracion: {0}:{1}", _
[Link], [Link])
End Sub
Private Sub FinalizarLista(ByVal sender As Object, _
ByVal e As [Link]) _
Handles [Link]
Luis Dueñas Pag 717
La Biblia de Visual Basic .NET
C += 1
[Link] = New Uri([Link](C))
[Link]()
[Link] = C
If C = [Link] Then C = 0
End Sub
End Class
Nota: En el código anterior al dar clic en el botón de “Abrir” se mostrará el
diálogo con archivos mp3 y wav, al seleccionarlo se agrega a la lista;
después de tener la lista completa al dar clic en el botón “Reproducir” se
inicia la reproducción del primer archivo de la lista y al finalizar el audio en
el evento MediaEnded se apunta al siguiente archivo de la lista para
reproducirlo, si se termina toda la lista se inicia nuevamente en el primero.
Regresar a la ventana “[Link]” y cambiar la ventana que
inicia (atributo StartupUri) a “[Link]”.
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 6.44: Ejecución de la ventana Reproductor de Sonido
Luis Dueñas Pag 718
La Biblia de Visual Basic .NET
Demo 102
Crear una nueva aplicación Windows WPF: del menú “File”, seleccionar
“New Project”.
En el diálogo elegir “Visual Basic”, luego “Windows”, seleccionar “WPF
Application”.
Escribir en el nombre de la aplicación “Demo102” y clic en “OK”.
Cambiar de nombre a la ventana “[Link]” por “Reproductor
[Link]”.
Escribir el siguiente código en el archivo xaml:
<Window x:Class="ReproductorVideo"
xmlns="[Link]
xmlns:x="[Link]
Title="Reproductor de Video en WPF" Height="420" Width="420"
ResizeMode="NoResize" WindowStartupLocation="CenterScreen">
<Grid Name="grdFondo">
<[Link]>
<LinearGradientBrush>
<GradientStop Color="aqua" Offset="0.8"/>
<GradientStop Color="blue" Offset="0.4"/>
</LinearGradientBrush>
</[Link]>
<StackPanel>
<Label Name="lblTitulo" HorizontalAlignment="Center"
Foreground="White" FontSize="14">
Selecciona archivo de video</Label>
<DockPanel VerticalAlignment="Center"
HorizontalAlignment="Center">
<TextBox Name="txtArchivo" Width="350"/>
<Button Name="btnAbrir" Content="..." Width="25"
Cursor="Hand" ToolTip="Abrir archivo de video"/>
</DockPanel>
<Button Name="btnReproducir" Content="Reproducir"
Cursor="Hand" Width="100" Height="25" IsEnabled="False" />
<MediaElement Name="meSonido" Width="350" Height="220"
LoadedBehavior="Manual" />
Luis Dueñas Pag 719
La Biblia de Visual Basic .NET
<Label Name="lblTiempo" HorizontalAlignment="Center">
00:00</Label>
<Slider Name="sldDuracion" Minimum="0" Maximum="100"/>
</StackPanel>
</Grid>
</Window>
Nota: En el código anterior se usa un Grid que tiene un fondo degradado
lineal el cual contiene un bloque de texto con un mensaje, un DockPanel
que tiene un cuadro de texto para el archivo seleccionado y un botón para
el diálogo de abrir, un botón para reproducir el video, un MediaElement
para ver el video y una etiqueta y una barra de desplazamiento para
avanzar el video.
El diseño de la ventana debe quedar como se ve en el gráfico 6.45.
Gráfico 6.45: Diseño de la ventana Reproductor de Video
Escribir código en el archivo vb asociado al xaml:
Imports Microsoft.Win32 'OpenFileDialog
Imports [Link] 'DispatcherTimer
Luis Dueñas Pag 720
La Biblia de Visual Basic .NET
Class ReproductorVideo
Private duracion As TimeSpan
Private X, C As Integer
Private WithEvents tmrDuracion As New DispatcherTimer
Private Min, Sec As Integer
Private Sub MostrarDialogoAbrir(ByVal sender As [Link], _
ByVal e As [Link]) Handles [Link]
Dim ofd As New OpenFileDialog
[Link] = "Selecciona archivo de video"
[Link] = "Archivos de video|*.mpg;*.mpeg;*.avi;*.mp4;*.wmv"
If [Link] = True Then
[Link] = [Link]
[Link] = True
End If
End Sub
Private Sub ReproducirVideo(ByVal sender As [Link], _
ByVal e As [Link]) _
Handles [Link]
[Link] = New Uri([Link])
[Link]()
End Sub
Private Sub FinalizarReproduccion(ByVal sender As Object, _
ByVal e As [Link]) _
Handles [Link]
Min = 0
Sec = 0
[Link] = 0
[Link]()
[Link] = False
End Sub
Private Sub MostrarTamañoVideo(ByVal sender As Object, _
ByVal e As [Link]) _
Handles [Link]
[Link] = New TimeSpan(0, 0, 1)
[Link] = True
[Link]()
Luis Dueñas Pag 721
La Biblia de Visual Basic .NET
duracion = [Link]
X = [Link] \ 100
[Link] = [Link]("Duracion Video (mm:ss) = {0}:{1}", _
[Link](2, "0"), _
[Link](2, "0"))
End Sub
Private Sub MostrarProgreso(ByVal sender As Object, _
ByVal e As EventArgs) Handles [Link]
C=C+1
If C Mod 60 = 0 Then
Min += 1
Sec = 0
Else
Sec += 1
End If
[Link] = [Link]("{0}:{1}", _
[Link](2, "0"), [Link](2, "0"))
If C Mod X = 0 Then
[Link] += 1
End If
End Sub
Private Sub ModificarAvance(ByVal sender As [Link], _
ByVal e As [Link](Of
[Link])) _
Handles [Link]
Dim seg As Integer = ([Link] * [Link]) / 100
If [Link] < 100 Then
[Link] = New TimeSpan(0, 0, seg)
[Link] = [Link]("{0}:{1}", _
[Link](2, "0"), _
[Link](2, "0"))
Else
[Link] = 0
[Link]()
[Link] = False
End If
End Sub
End Class
Luis Dueñas Pag 722
La Biblia de Visual Basic .NET
Nota: En el código anterior al dar clic en el botón de “Abrir” se mostrará el
diálogo con archivos de video, al dar clic en el botón “Reproducir” se inicia
la reproducción del video y se dispara el evento MediaOpened en el cual
se habilita un Timer y se muestra el tiempo de duración. El timer muestra
el tiempo de avance del video. Si se avanza o retrocede con la barra de
desplazamiento se actualiza la duración actual.
Importante: Para trabajar con procesos en segundo plano cada cierto
tiempo en WPF no se debe usar el Timer de [Link] sino el
DispatcherTimer de [Link].
Regresar a la ventana “[Link]” y cambiar la ventana que
inicia (atributo StartupUri) a “[Link]”.
Grabar y ejecutar la aplicación creada pulsando la tecla F5.
Gráfico 6.46: Ejecución de la ventana Reproductor de Video
Luis Dueñas Pag 723
La Biblia de Visual Basic .NET
Preguntas de Repaso
1. Qué se puede hacer en WPF que no se puede hacer en WinForms no
ASP .NET?
2. Cuáles son los principales componentes en la arquitectura de WPF?
3. Menciona 5 características de WPF.
4. Qué lenguaje de marcas usa WPF?
5. Cuántos tipos de aplicaciones se pueden crear en WPF?
6. Menciona 5 tipos de controles de WPF.
7. Cómo se llama el contenedor principal de controles que viene por
defecto en una ventana o página en WPF?
8. Menciona otros 3 contenedores de controles WPF.
9. Menciona el evento de inicio que ocurre al cargar una ventana y los
eventos de cierre de ventana.
10. Qué debe configurarse para que una cierta ventana de nuestra
aplicación inicie primero?
11. Qué es una aplicación WPF del Explorador o XBAP?
12. Que tipo de seguridad tiene por defecto una aplicación WPF del
explorador?
13. Qué clase se usa para navegar entre páginas de una aplicación del
explorador?
14. Qué se debe hacer para que una aplicación del explorador pueda
acceder a archivos, cuadros de diálogo, registro de Windows, etc.?
Luis Dueñas Pag 724
La Biblia de Visual Basic .NET
15. Cómo se clasifican los cuadros de diálogo?
16. Qué tipos de cuadros de diálogo se pueden crear en WPF?
17. Qué espacio de nombres se debe importar para usar los diálogos de
archivos de Windows?
18. Cuál es el único cuadro de diálogo interno de WPF?
19. Cómo se llama las clases para implementar los diálogos de abrir y
guardar respectivamente?
20. Con qué método del cuadro de diálogo de imprimir (PrintDialog) se
puede imprimir cualquier contenido inclusive gráficos?
21. Cuantas técnicas tenemos para presentar datos en una aplicación?
22. Cuáles son las ventajas principales de WPF en el enlace de datos con
respecto a WinForms y WebForms?
23. Cuántos tipos de enlaces (Data Bindings) existen?
24. Qué propiedad de los controles de listas implementa el enlace complejo
en WPF?
25. Menciona 3 controles que soporten enlace complejo.
26. Qué debe hacerse para crear enlace simple?
27. Menciona 3 controles que soporten enlace simple.
28. Cómo se llama la clase que hace de intermediario entre los controles y
el origen de datos en WPF?
29. Menciona los métodos de desplazamiento del objeto CollectionView.
Luis Dueñas Pag 725
La Biblia de Visual Basic .NET
30. Con qué propiedades del CollectionView se verifican el desbordamiento
de registro?
31. En qué evento del CollectionView podemos programar para mostrar la
posición actual del origen de datos cuando este cambie?
32. Qué propiedades de los controles listas permiten configurar el campo a
mostrar y el campo a guardar?
33. Para qué se usa la conversión de datos en WPF?
34. Qué interface tenemos que implementar para realizar la conversión de
datos?
35. Qué métodos hay que programar en una clase que implemente dicha
interface?
36. Cómo se aplica en el XAML una clase creada para formatear o convertir
un tipo de dato en en control enlazado?
37. Cómo se puede ordenar las columnas en el control ListView?
38. Cómo se obtiene la cabecera a la cual se dio clic en un ListView?
39. Cómo se crea un objeto CollectionView?
40. Para qué se usan las plantillas de datos en WPF?
41. Qué tipo de objeto permite crear una plantilla de datos y qué propiedad
del control enlazado debemos configurar para aplicar el objeto creado?
42. Cómo se sincronizan 2 listas enlazadas a datos sin necesidad de
programar el filtro?
43. Qué es una plantilla jerárquica y cómo se implementa en WPF?
44. Qué control de WPF soporta una plantilla jerárquica?
Luis Dueñas Pag 726
La Biblia de Visual Basic .NET
45. Qué requisitos debe tener el origen de datos antes de enlazar a un
control que usará una plantilla jerárquica?
46. Qué control WPF presenta de forma simple filas y columnas sin
necesidad de usar plantillas?
47. Cuáles son los tipos de columnas que puede tener el control DataGrid?
48. Qué es necesario hacer al DataGrid para que pueda ordenar los datos al
dar clic a la cabeceras de sus columnas?
49. Cuántos tipos de documentos maneja WPF?
50. Qué control se usa para visualizar documentos fijos como los XPS?
51. Qué controles se usan para visualizar documentos dinámicos como los
archivos de texto, xml, html, etc.
52. Qué sigifica XPS y cómo se implementa en WPF?
53. Cómo se llama la librería que permite trabajar con documentos XPS?
54. Qué propiedad del control DocumentViewer es necesario configurar
para enlazar un documento?
55. Menciona los 3 tipos de anotaciones que hay en WPF.
56. Qué clase es necesario usar para implementar anotaciones en WPF?
57. Menciona 3 métodos de la clase AnnotationService que sirvan para
crear anotaciones.
58. Menciona 3 métodos de la clase AnnotationService que sirvan para
eliminar o borrar anotaciones.
59. Cuál es la ventaja de los documentos dinámicos?
Luis Dueñas Pag 727
La Biblia de Visual Basic .NET
60. Cómo se puede convertir un archivo de Word o Excel a XPS?
61. Qué se debe hacer si se usa por código trabajar con Word o Excel
desde .NET?
62. Cuáles son las 2 clases que implementan Multimedia en WPF?
63. Cómo se llama la librería de clases que implementa el reconocimiento
de voz en WPF?
64. Cómo se llama la clase que permite reproducir voz?
65. Qué métodos tiene la clase SpeechSynthesizer para reproducir la voz?
66. Qué propiedades del objeto SpeechSynthesizer permiten controlar el
volumen y la velocidad de la voz?
67. Cómo se llama la clase (control) que permite reproducir audio y video?
68. Qué propiedad del control MediaElement especifica la URI con el
archivo de audio o video a reproducir?
69. Qué eventos ocurren al iniciar y finalizar la reproducción usando el
MediaElement?
70. Qué clase y en que espacio de nombres se encuentra el objeto que
permite ejecutar en segundo plano cada cierto tiempo una acción en
una aplicación WPD?
71. Ultima pregunta: Te gusto o no el libro?
Luis Dueñas Pag 728
La Biblia de Visual Basic .NET
Índice de Ejemplos del Libro
Demo 01: Información del Sistema
Demo 02: Información de Directorios Especiales de Windows
Demo 03: Explorador del Registro de Windows (RegEdit)
Demo 04: Administrador de Tareas
Demo 05: Explorador de Archivos V1.0
Demo 06: Chat
Demo 07: Dividir y Unir Archivos
Demo 08: Comprimir y Descomprimir Archivos
Demo 09: Cálculo del Área del Triángulo sin Librerías
Demo 10: Librería de Código de Usuario para Triángulo
Demo 11: Librería de Entidad de Negocio para Triángulo
Demo 12: Librería de Acceso a Datos para Triángulo
Demo 13: Librería de Reglas de Negocio para Triángulo
Demo 14: Cálculo del Área del Triángulo con Librerías
Demo 15: Lectura asíncrona de archivos de texto
Demo 16: Lectura asíncrona de archivos de texto con Barra de Progreso
Demo 17: Contador de palabras en archivos asíncrono
Demo 18: Servicio WCF que lista Empleados
Demo 19: Aplicación que usa el Servicio WCF que lista empleados en forma
asíncrona con Eventos
Demo 20: Librería de acceso a datos que lista empleados
Luis Dueñas Pag 729
La Biblia de Visual Basic .NET
Demo 21: Aplicación que usa la Librería que lista empleados en forma
asíncrona con Delegados CallBack.
Demo 22: Gráfico de Círculos usando For Paralelo
Demo 23: Lista de Empleados usando Tarea Paralela
Demo 24: Cifrado Simétrico por Caracter
Demo 25: Cifrado Simétrico por Bloques
Demo 26: Verificar archivos usando valores Hash
Demo 27: Conectarse a una base de datos de MS SQL Server
Demo 28: Visor de bases de datos de MS Access
Demo 29: Visor de archivos de MS Excel
Demo 30: Conectarse a una archivo DBF
Demo 31: Consulta de empleados por código que muestra nombre
Demo 32: Consulta de empleados por código que muestra todos sus datos
Demo 33: Consulta de productos por proveedor
Demo 34: Consulta de varias tablas
Demo 35: Mantenimiento conectado de empleados
Demo 36: Consulta de ordenes por cliente
Demo 37: Filtro de productos por código y nombre
Demo 38: Búsqueda de productos por código y nombre
Demo 39: Mantenimiento desconectado de empleados
[Link]: Librería de Entidades de Negocio Northwind
[Link]: Librería de Acceso a Datos Northwind
[Link]: Librería de Reglas del Negocio Northwind
Luis Dueñas Pag 730
La Biblia de Visual Basic .NET
Demo 40: Lista de Empleados con objetos que usa Librerías Northwind
Demo 41: Lista de Productos con objetos que usa Librerías Northwind
Demo 42: Filtro en Lista de objetos empleados con For - If
Demo 43: Filtro en Lista de objetos empleados con predicados
Demo 44: Filtro de productos por categoría con predicados
Demo 45: Ordenación y búsqueda de objetos para empleados
Demo 46: Mantenimiento de empleados con objetos
Demo 47: Filtro de empleados con LINQ a DataSet
Demo 48: Filtro de productos con LINQ a DataSet
Demo 49: Filtro de ordenes por cliente con LINQ a SQL
Demo 50: Filtro de productos por proveedor con LINQ a Entidades
Demo 51: Formulario en forma de elipse con gráficos
Demo 52: Formulario de Login con controles básicos
Demo 53: Manejo de Listas en Windows Forms
Demo 54: Explorador de Windows V2.0
Demo 55: Formulario MDI con gráfico de fondo
Demo 56: Crear Menú Principal dinámicamente desde un archivo XML
Demo 57: Crear Menú Contextual dinámicamente con un Calendario
Demo 58: Marquesina configurable
Demo 59: Editor de Documentos de Texto de Formato Enriquecido
Demo 60: Columnas Personalizadas en lista de Productos
Demo 61: Lista de Categorías con Imágenes desde Archivos
Luis Dueñas Pag 731
La Biblia de Visual Basic .NET
Demo 62: Personalizar Cabeceras para Filtrar Productos por Categoría
Demo 63: Gráfico de Barras de Precios de Productos
Demo 64: Paginación en una Lista de Productos
[Link]: Librería de Controles de Windows Forms
Demo 65: Aplicación de Prueba de Librería de Controles Windows
Demo 66: Reporte de Productos con PrintDocument
Demo 67: Reporte de Empleados con Informes Microsoft
Demo 68: Crear Documentos de Productos con MS Word
Demo 69: Crear Informes y Gráfico de Productos con MS Excel
Demo 70: Crear Gráfico de Productos con el Control Chart
Demo 71: Simple sitio web para navegar por 3 páginas
Demo 72: Ficha de Registro de Alumnos en archivos de texto
Demo 73: Seguridad usando un CAPTCHA
Demo 74: Bolsa de Trabajo con control FileUpload y controles de Validación
Demo 75: Ficha de Registro de Alumnos usando Hojas de Estilos
Demo 76: Sitio Web de un Instituto que usa Página Principal, Páginas de
Contenido y Controles de Navegación
Demo 77: Consultas de Datos usando fichas con controles de vistas
MultiView y Views
Demo 78: Lista de Productos con Columnas Personalizadas
Demo 79: Lista de Productos Paginada
Demo 80: Lista de Productos Paginada y Ordenada con Símbolos de Orden
Demo 81: Mantenimiento de Productos en el GridView
Luis Dueñas Pag 732
La Biblia de Visual Basic .NET
Demo 82: Lista de Categorías usando Plantillas en el control Repeater
Demo 83: Lista de Empleados usando Plantillas en el control DataList
Demo 84: Lista de Productos x Categoría usando Plantillas Jerárquicas
Demo 85: Aplicación WPF Windows que Registra y Lista Alumnos
Demo 86: Aplicación WPF para el Browser XAML (XBAP) de Alumnos
Demo 87: Editor de Textos WPF con Diálogos Comunes de Windows
Demo 88: Leer y Escribir en Lista de Empleados
Demo 89: Leer y Escribir en Consulta de Empleados
Demo 90: Enlace de Datos en Lista de Productos
Demo 91: Enlace de Datos en Consulta de Productos
Demo 92: Conversión de Datos y Ordenación en un ListView de Productos
Demo 93: Conversión de Datos en una Consulta de Empleados
Demo 94: Plantillas de Datos y Sincronización de Listas en Consulta de
Productos por Categoría
Demo 95: Plantilla de Datos Jerárquica en TreeView lista Detalles x Orden
Demo 96: Lista de Productos usando el control DataGrid
Demo 97: Visor de Documentos XPS como Documento Fijo
Demo 98: Visor de Archivos de Word y Excel con Anotaciones
Demo 99: Visor de Archivos de Texto como Documento Dinámico
Demo 100: Reproductor de Voz
Demo 101: Reproductor de Sonido
Demo 102: Reproductor de Video
Luis Dueñas Pag 733
La Biblia de Visual Basic .NET
Enlaces de Referencias
1. Información general y conceptual sobre .NET Framework
[Link]
2. Lenguajes .NET
[Link]
3. Bibliotecas de clases de .NET Framework
[Link]
4. Common Language Runtime (CLR)
[Link]
5. Lo Nuevo en .NET Framework 4
[Link]
6. Paseo rápido por el entorno de desarrollo integrado (IDE)
[Link]
7. Novedades de Visual Studio 2010
[Link]
8. Estructuras de Control de Flujo
[Link]
9. Tipos de Datos en Visual Basic
[Link]
10. Operadores en Visual Basic
[Link]
Luis Dueñas Pag 734
La Biblia de Visual Basic .NET
11. Variables en Visual Basic
[Link]
12. Novedades de Visual Basic 2010
[Link]
13. Entrada y Salida de archivos básica
[Link]
14. Objetos y Clases de Visual Basic
[Link]
15. Información general sobre la programación asíncrona
[Link]
16. Programación paralela en .NET Framework
[Link]
17. Servicios criptográficos
[Link]
18. Información general sobre ADO .NET
[Link]
19. Descargar archivo de Ubigeo 2008 del INEI
[Link]
20. Información sobre cadenas de conexión
[Link]
21. DataSets de ADO .NET
[Link]
Luis Dueñas Pag 735
La Biblia de Visual Basic .NET
22. LINQ y ADO .NET
[Link]
23. Introducción a los formularios Windows Forms
[Link]
24. Información General del Control DataGridView
[Link]
25. Desarrollar controles personalizados de formularios Windows Forms
[Link]
26. Funcionalidad para imprimir en formularios Windows Forms
[Link]
27. Informes de Microsoft
[Link]
28. Control ReportViewer
[Link]
29. Control Chart
[Link]
[Link]
30. Información general sobre ASP .NET
[Link]
31. Clase FileUpload
[Link]
fileupload(v=vs.80).aspx
Luis Dueñas Pag 736
La Biblia de Visual Basic .NET
32. Controles de Validación ASP .NET
[Link]
33. Páginas Principales en ASP .NET
[Link]
34. Clase GridView
[Link]
[Link]
35. Plantillas de Controles de Servidor Web ASP .NET
[Link]
36. Arquitectura de WPF
[Link]
37. Información general sobre ventanas de WPF
[Link]
38. Información general sobre navegación
[Link]
39. Información general sobre cuadros de diálogo
[Link]
40. Información general sobre el enlace de datos
[Link]
41. Información general sobre plantillas de datos
[Link]
Luis Dueñas Pag 737
La Biblia de Visual Basic .NET
42. Clase DataGrid de WPF
[Link]
[Link]
43. Documentos en WPF
[Link]
44. Información general sobre anotaciones
[Link]
45. Información general sobre Multimedia
[Link]
Luis Dueñas Pag 738