Formulario Splash 2, Fecha: 06 de julio de 2004
|
. |
Introducci�n:
Este articulo, es una segunda parte del articulo "Formulario Splash", publicado en este mismo sitio, donde se realiza la misma agenda, pero esta vez en VB.NET, ya que hay gente interesada en tener el c�digo fuente de la misma en dicho leguaje de programaci�n.Como en el articulo anterior me centre mas en explicar la creaci�n del formulario "Splash", y el resto de la agenda lo deje para la observaci�n de los interesados en el c�digo, en este aprovecho para dejar un poco de lado la creaci�n del formulario Splash (que ya se trato muy extensamente en el citado articulo y el interesado puede consultar el c�digo fuente en VB que se adjunta al articulo), y en este me centrare de lleno en la agenda en si.
Desarrollo de una agenda aplicando "programaci�n en tres capas" (Interfaz de usuario, Capa de negocios, Capa de acceso a datos).
Antes de nada me gustar�a explicar la idea lo mas detalladamente posible sobre que es lo que se pretende, as� se entender� mejor el c�digo y el por que se utiliza la programaci�n en tres capas en esta soluci�n.
Lo primero que hay que tener claro es que una agenda es un programa que nos servirá para guardar informaci�n relevante sobre personas, siendo lo primero que nos tenemos que plantear cuales son los datos "relevantes" o "importantes" para nosotros de una persona, y como guardaremos esta informaci�n (es decir el tipo de soporte f�sico, fichero de texto plano, SQL Server, fichero de ACCESS, etc.)
Los datos que yo utilizare ser�n los siguientes:
Dato Tipo Long. Nombre String 40 Direcci�n String 40 Poblaci�n String 40 Provincia String 35 C�d. Postal String 5 Tel�fono String 12 String 60 El soporte f�sico será un fichero XML, que se llamara "datos.xml", y aquí es donde la aplicaci�n de la "programaci�n en tres capas" es interesante, ya que en la capa de datos, pondremos todo el c�digo relativo al trabajo con el soporte f�sico, pudiendo cambiar esta clase por otra que implemente los mismos datos en un fichero ACCESS, o en una base de datos SQL Server, por ejemplo.
Solo me falta indicar que de estos campos, yo utilizare el Nombre como campo clave, si el soporte fuera otro, como un fichero ACCESS, pudiera optar por incluir un campo autonumerico como clave, pero como para este ejemplo no se guardan datos como el D.N.I., u otros que pudieran resultar mas identificativos utilizo este, ya que si hay dos Pepe, nos interesar�a poderles diferenciar de alguna forma poniendo sus apellidos, o a�adiendo n�meros: "Pepe 1", "Pepe 2", etc. (Como la agenda de un tel�fono m�vil).
Con las ideas claras, ya se puede dividir el programa, en la capa de acceso a datos he creado una clase llamada "FichAgenda", que contiene la funcionalidad relativa al trabajo con el fichero datos.xml, despu�s la L�gica de negocio, solo tiene una clase que es "Persona" y que contiene tanto los datos de la persona como la utilidad b�sica de crear modificar, borrar, etc. y llama a la clase FichAgenda para independizarla del soporte f�sico, despu�s el Interfaz de usuario que utiliza la clase Persona, que en este caso es un Windows Form.
La capa de acceso a datos.
Primero definimos como funcionara nuestra aplicaci�n, y en base a lo que queremos así, crearemos nuestra clase FichAgenda.
Para que nuestra agenda sea mas r�pida, la idea es la siguiente, cuando comience nuestra aplicaci�n cargara todos los datos del fichero "datos.xml" en un DataSet, y despu�s para guardar los mismos en dicho fichero lo mejor es sobrescribir dicho fichero con los datos que tenemos en el DataSet, que ser�n los correctos, para eso se crean los m�todos "CargarDatos" y "GuardarDatos", en esta clase tambi�n se incluye el formato del fichero y de esto se encarga un m�todo privado al que llamo "Estructura", y que retorna como resultado el DataTable "Contactos".
A continuaci�n vemos los tres m�todos, que son Shared (static en C#), como todos los m�todos y propiedades de esta clase, para que no tengamos que crear una instancia de dicha clase.
Private Shared _dtCargados As Boolean = False Private Shared _ds As DataSet . . Public Shared Sub CargarDatos() _ds = New DataSet ' Creamos una nueva instancia de un DataSet _ds.Tables.Add(Estructura()) ' Le a�adimos la estructura Try _ds.ReadXml("datos.xml") ' Leemos los datos del fichero datos.xml Catch Console.WriteLine("Error al leer el fichero de datos.") Try _dtCargados = True End Sub Public Shared Sub GuardarDatos() Dim miFS As New FileStream("datos.xml",FileMode.Create) Dim XmlW As New XmlTextWriter(miFS, System.Text.Encodign.Unicode) _ds.WriteXml(XmlW) ' Guardamos los datos XmlW.Close() End Sub . . Private Shared Function CargarDatos() As DataTable Dim dt As New DataTable("Contactos") Dim dc As DataColumn cd = New DataColumn("Nombre",System.Type.GetType("System.String")) dt.Columns.Add(dc) cd = New DataColumn("Direccion",System.Type.GetType("System.String")) dt.Columns.Add(dc) cd = New DataColumn("Poblacion",System.Type.GetType("System.String")) dt.Columns.Add(dc) cd = New DataColumn("Provincia",System.Type.GetType("System.String")) dt.Columns.Add(dc) cd = New DataColumn("CodPostal",System.Type.GetType("System.String")) dt.Columns.Add(dc) cd = New DataColumn("Telefono",System.Type.GetType("System.String")) dt.Columns.Add(dc) cd = New DataColumn("EMail",System.Type.GetType("System.String")) dt.Columns.Add(dc) Return dt End FunctionEstos dos m�todos y la funci�n "Estructura" son lo mas destacado en lo que respecta a la funcionalidad del fichero "datos.xml", pero esta clase a�ade, las funciones BorrarReg, Datos (que devuelve un DataTable con todos los registros), MirarPersona, ModificarReg y NuevoReg, que tanto por sus nombres como por lo sencillo de los mismos aconsejo consultar en el programa.
Solo a�adiré a esta explicaci�n sobre la capa de acceso a datos que es importante la propiedad de solo lectura DatosCargados, que sirve para controlar (como su nombre indica), si ya est�n los datos cargados en el DataSet privado "_ds", ya que en caso contrario la clase no funcionaria correctamente hasta que se llame al m�todo "CargarDatos".
La L�gica de negocio.
Como ya he indicado esta capa solo tendrá una clase que será "Persona", y que será la clase que proporcionara toda la utilidad sobre las personas de nuestra agenda al Interfaz de usuario, ya que esta ultima capa (el Interfaz de usuario), no puede tener acceso a la capa de acceso a datos.
Lo primero que tenemos que tener claro sobre la clase Persona es que depende de la clase FichAgenda, para su buen funcionamiento, por lo tanto una idea que hay que tener clara es que lo primero que ha de realizar es una llamada al m�todo CargarDatos de la misma, una buena idea seria llamarlo desde el constructor de la clase, ya que esto nos asegurar�a que al crear una instancia de la misma se llamase a dicho m�todo, pero como la idea inicial era que al iniciar el programa un subproceso se encargara de realizar la carga de los datos, cree un m�todo Shared llamado "MirarContactos", que se encarga de esto.
Hay otra propiedad Shared, que devuelve un DataTable, con los datos y que yo uso para asignar la propiedad DataSource del DataGrid1 que hay en el Interfaz de usuario, que comprueba si se han cargado los datos, y en caso contrario llama al citado m�todo "CargarDatos" de FichAgenda, a continuaci�n vemos el c�digo.
Public Shared Sub MirarContactos() FichAgenda.CargarDatos() End Sub Public Shared ReadOnly Property Contactos()As DataTable Get If Not FichAgenda.DatosCargados Then FichAgenda.CargarDatos() End If Return FichAgenda.Datos End Get End SubAdem�s de estos m�todos, esta clase implementa las Funciones A�adir, Borrar, Mirar y Modificar, que sirven para trabajar con la persona activa, excepto A�adir (de ahí que la haya declarado como Shared) que crea una nueva persona, Mirar es la funci�n que carga en la instancia los datos de la persona con la que queremos trabajar.
Public Function Mirar(ByVal Nombre As String) As Boolean If Nombre <> String.Empty Then Dim dr As DataRow = FichAgenda.MirarPersona(Nombre) If Not IsNothing(dr) Then _nombre = dr("Nombre").ToString() _direccion = dr("Direccion").ToString() _poblacion = dr("Poblacion").ToString() _provincia = dr("Provincia").ToString() _codPostal = dr("CodPostal").ToString() _telefono = dr("Telefono").ToString() _eMail = dr("EMail").ToString() _modificado = False Return True Else If _nombre <> String.Empty Then _nombre=String.Empty End If Return False End If Else Return False End If End Function Public Function Modificar() As Boolean If (_modificado) And (_nombre <> String.Empty) Then Dim los_datos(7) As String los_datos(0) = _nombre los_datos(1) = _direccion los_datos(2) = _poblacion los_datos(3) = _provincia los_datos(4) = _codPostal los_datos(5) = _telefono los_datos(6) = _eMail If FichAgenda.ModificarReg(los_datos) = Then _modificado = False Return True Else Return False End If Else Return False End If End Function Public Shared Function A�adir(ByVal Nombre As String) As Boolean Return FichaAgenda.NuevoReg(Nombre) End Function Public Function Borrar() As Boolean If _nombre <> String.Empty Then If (FichAgenda.BorrarReg(_nombre)) Then _nombre = String.Empty Return True Else Return False End If Else Return False End If End FunctionDespu�s tenemos como propiedades todos los datos de la persona, adem�s de DatosModificados, que nos indica si se ha realizado alguna modificaci�n en alg�n campo; para saber si tenemos cargada una persona correctamente en nuestra instancia yo utilizo el campo Nombre, ya que al ser el campo clave no puede estar vac�o, por eso su propiedad es de solo lectura (a diferencia de los dem�s), así, solo con ver si dicho campo esta vac�o (String.Empty) podemos saber si nuestra instancia contiene los datos de una persona.
Private _nombre As String = String.Empty Private _direccion As String = String.Empty Private _poblacion As String = String.Empty Private _provincia As String = String.Empty Private _codPostal As String = String.Empty Private _telefono As String = String.Empty Private _eMail As String = String.Empty Private _modificado As Boolean = False . . Public ReadOnly Property Nombre() As String Get Return _nombre End Get End Property Public Property Direccion() As String Get Return _direccion End Get Set(ByVal Value As String) _direccion = Value _modificado = True End Set End Property Public Property Poblacion() As String Get Return _poblacion End Get Set(ByVal Value As String) _poblacion = Value _modificado = True End Set End Property Public Property Provincia() As String Get Return _provincia End Get Set(ByVal Value As String) _provincia = Value _modificado = True End Set End Property Public Property CodPostal() As String Get Return _codPostal End Get Set(ByVal Value As String) _codPostal = Value _modificado = True End Set End Property Public Property Telefono() As String Get Return _telefono End Get Set(ByVal Value As String) _telefono = Value _modificado = True End Set End Property Public Property EMail() As String Get Return _eMail End Get Set(ByVal Value As String) _eMail = Value _modificado = True End Set End Property Public ReadOnly Property DatosModificados() As Boolean Get Return _modificado End Get End PropertyCon esto creo que esta suficientemente explicada la clase Persona.
El interfaz de usuario.
El interfaz de usuario ya lo dejo para la observaci�n de los interesados, directamente en el c�digo fuente del articulo.
Bueno, pues esta es una peque�a explicaci�n, y el c�digo fuente en VB.NET para los interesados que lo pidieron (el de C# esta en el articulo anterior), un saludo a todos y espero que haya sido �til.
Fichero con el c�digo de ejemplo: ACUESTA_FormularioSplashVB.zip - Tama�o 94,7 KB