Está en la página 1de 19

Abrir formularios (C#)

Fecha: 23/Oct/2006 (15/10/2006)


Autor: Francisco Juan González Pinzón

Introducción

Este ejemplo sirve para usuarios que recién están empezando a utilizar aplicaciones Windows, en C# (Sharp), ya
que como yo no sabia como abrir formularios en una misma ventana, pues bien aquí te explico lo mas claro posible
para que tengas una ventana de tu aplicación como principal y puedas abrir el resto de tus formularios en la misma.
Espero te sea de mucha utilidad, saludos.

El código:

El código para abrir más de una vez el mismo formulario:

/*
* Creo el objeto del segundo formulario
*/
Frt = new FormTwo();
// Mediante codigo indico al formulario segundo que aparesca.
Frt.Show();

Espacios de nombres usados en el código de este artículo:

System.Windows.Forms
Formulario con forma Redonda en C#
En el otro post puse como dar forma redonda a un Formulario desde VB.NET pues aqui
les pongo el codigo en C# para los que prefieren este lenguaje (yo soy uno de ellos )

//Importamos el Espacio de Nombre

using System.Drawing;

//Desde el evento Load del Formulario

private void Form1_Load(object sender, EventArgs e)

System.Drawing.Drawing2D.GraphicsPath objDraw = new

System.Drawing.Drawing2D.GraphicsPath();

objDraw.AddEllipse(0, 0, this.Width, this.Height);

this.Region = new Region(objDraw);

Constructores, inicializacion rapida de objetos y C# 3.0


La inicialización rápida de objetos es una nueva e interesante característica de C# 3.0,
pero me gustaria reflexionar un poco sobre su uso y el de nuestros amigos los
constructores.

Un constructor es el método de una instancia que implementa las acciones necesarias


para inicializar la instancia de la clase, y es invocado por el operador new cuando
instanciamos dicha clase. Por lo tanto, cuando desarrollamos una clase, el ó los
constructores deben de tener la capacidad de inicializar los aspectos básicos de
funcionamiento del objeto.

En C#, cuando no implementamos ningún constructor, el compilador asume que


tenemos un constructor sin parámetros, es decir, esto:

[more]

class MyClass
{
public String Field1 { get; private set; }
public String Field2 { get; private set; }
}
es lo mismo que esto:

class MyClass
{
public String Field1 { get; private set; }
public String Field2 { get; private set; }

public MyClass()
{
}
}

En el momento que definamos un constructor con parámetros, el compilador deja de


asumir la existencia del constructor sin ellos, el motivo me parece más que obvio, si
definimos un constructor con parámetros estamos diciendo que nuestra clase
necesita "otras cosas" para poder inicializarse correctamente; si queremos tener
otro sin parámetros tendremos que definirlo explicitamente.

Una ve las ventajas de usar un constructor paramétrizado, es por ejemplo


inicializar propiedades públicas con setter privado, y modificarlas desde el constructor
en base a los parámetros (seguro que no lo has hecho nunca xD); pero la principal
ventaja es que le dice al programador que se necesita para ser inicializado y poder
empezar a trabajar. A veces no necesitamos parámetros y otras veces es inevitable y
debemos definir un constructor sin parámetros, como por ejemplo para permitir la
serialización en Xml.

Definir constructores es bastante llevadero y poco pesado, ya que gracias a la


sobrecarga, se escriben rápido, sin repetir el código en cada uno de ellos y queda
bastante claro:

class MyControl : Control


{
public String Field1 { get; private set; }
public String Field2 { get; private set; }
public String Field3 { get; private set; }

// base: nos permite pasar parámetros a la


// clase de la que heredamos
public MyControl(Control parent, String text, String field1)
: base(parent, text)
{
this.Field1 = field1;
}

// this: nos permite invocar a otro constructor


// de la misma clase, de forma que lo que escribimos
// en este prosigue la labor del otro, evitandonos escribir
// otra vez lo mismo para cada constructor.
public MyControl(Control parent, String text, String field1,
String field2)
: this(parent, text, field1)
{
this.Field2 = field2;
}

// this: nos permite llamar a cualquier constructor


// de la misma clase.
public MyControl(Control parent, String text, String field1,
String field2, String field3)
: this(parent, text, field1,field2)
{
this.Field3 = field3;
}
}

También se pueden definir modificadores de acceso en los constructores, de forma que


haya constructores que solo se puedan usar desde dentro de la misma
clase(private), clase derivada(protected), ensamblado(internal) ó por todo el
mundo(public). Útil para controlar desde donde se pueden instanciar nuestros objetos, ó
cuantas veces, como en el patrón Singleton.

Además, podemos definir un constructor estático, sin parámetros, sin modificadores de


acceso, imposible de invocar directamente... pero que nos permite inicializar lo que
queramos antes que nigún miembro de la clase, estático ó de instancia, sea usado.

Bien, en C# 3.0 la inicialización rápida de objetos, permiten inicializar las propiedades


públicas de una clase de una pasada:

class MyControl : Control


{
public String Field1 { get; set; }
public String Field2 { get; set; }
public String Field3 { get; set; }
public String Field4 { get; private set; }
}

static void Main()


{
MyControl mc = new MyControl() { Field1 = "f1", Field2 = "f2",
Field3 = "f3" };
}

No voy a discutir de lo útil que es, porque definitivamente lo es, pero por supuesto no es
una caracteristica para reemplazar los constructores porque:

• No podemos inicializar campos privados ó propiedades públicas con setter


privado.
• Puede que necesitamos ejecutar alguna lógica ó incluso otros métodos en
función del tipo de parámetros.
• No denota cuales son las propiedades que necesita tener configuradas para poder
considerarse totalmente inicializado, de cara a alguien que consuma nuestra
clase a posteriori. Esto me parece lo más importante, ya que el código debe
intentar ser autodescriptivo.

Al igual que los métodos parciales, métodos extensores ó tipos anónimos, es una nueva
caracteristica para tener en cuenta y para usar cuando sea apropiado, no viene a
reemplazar nada, viene a complementar para "esos casos" donde hace falta.

Si tu clase necesita datos ó ser inicializada, implementa un constructor parametrizado.


Por la salud mental de nuestros compañeros de trabajo, hagamos un buen uso del
lenguaje :D
[VB & C# .Net] Enviar Emails en .Net
En este artículo vamos a mostrar como enviar un correo electrónico en .Net cuando
usemos un servidor SMTP que requiere autenticación. También mostraremos como
insertar ficheros adjuntos a nuestro correo.

El siguiente código vale tanto para aplicaciones de escritorio como para desarrollos
web.

Básicamente vamos a usar dos clases que pertenecen al espacio de nombres


System.Net.Mail, estas clases son:

• MailMessage, con la que podremos configurar nuestro mensaje.


• SmtpClient, con esta clase podremos enviar mails usando el protocolo SMTP.

Inicialmente, lo que haremos será configurar el mensaje usando la clase MailMessage y


finalmente enviaremos el correo usando la clase SmtpClient.

En primer lugar debemos de importar el NameSpace System.Net.Mail, para ello


debemos incluir en nuestro código:

• En Visual Basic: Imports System.Net.Mail


• En C#: using System.Net.Mail;

Como hemos comentado en la primera parte del código vamos a configurar el mensaje,
para ello vamos a usar las siguientes propiedades de la clase MailMessage:

• From, indicamos la dirección de correo origen así como su nombre.


• To, definimos el destinatario del correo electrónico.
• Subject, incluimos el asunto o titulo del mensaje.
• Body, definimos el cuerpo del mensaje.
• BodyEncoding, establecemos el tipo de codificación del cuerpo del mensaje, en
nuestro caso usaremos la codificación UTF-8.
• Priority, con esta propiedad definimos la prioridad del correo electrónico, los
tipos de prioridades pueden ser:
o High, el correo electrónico es de alta prioridad.
o Low, definimos el Email de baja prioridad.
o Normal, el mensaje es de prioridad normal.
• IsBodyHtml, indicamos si el correo es en formato HTML o no, en nuestro caso
enviaremos un Email en formato de texto.
• Attachments, incluimos los ficheros adjuntos que acompañaran el mensaje.

En la mayoría de las propiedades anteriormente mencionadas no nos detendremos a


explicar cómo definirlas ya que es simplemente asignarles un valor, pero a la propiedad
“Attachments” que es un objeto al cual le incluiremos los datos adjuntos la
explicaremos un poco más detenidamente. Para ello debemos de crear un objeto
“Attachment” que contendrá los ficheros adjuntos que deseamos incluir en el
mensaje. Usaremos la clase “Attachment” , que pertenece al espacio de nombres
“System.Net.Mail”, que representa los datos adjuntos del correo. En primer lugar
definiremos la clase “Attachment” indicando la ruta y nombre del fichero que queremos
adjuntar y finalmente, usando la propiedad “Attachments” de la clase “MailMessage”,
añadiremos el fichero adjunto a nuestro correo, un ejemplo de código será el siguiente:

En Visual Basic:

Dim MiFichero As Attachment = New Attachment(“Ruta y nombre de fichero”)


MiCorreo.Attachments.Add(MiFichero)

En C#:

Attachment MiFichero = new Attachment(@”Ruta y nombre de fichero”);


MiCorreo.Attachments.Add(MiFichero);

En esta primera fase de código vamos a configurar las propiedades anteriormente


mencionadas de la clase “MailMessage” para configurar el Email, el código será el
siguiente:

En Visual Basic:

‘Definimos la clase MailMessage


Dim MiCorreo As New MailMessage

‘Indicamos Email origen


MiCorreo.From = New System.Net.Mail.MailAddress(“Email origen”, “Nombre del
origen”)
‘Añadimos la dirección correo del destinatario
MiCorreo.[To].Add(“Correo destino”)
‘Incluimos el asunto del mensaje
MiCorreo.Subject =“Texto de mi Asunto”
‘Añadimos el cuerpo del mensaje
MiCorreo.Body = “Cuerpo del Mensaje”
‘Indicamos el tipo tipo de codificación del mensaje
MiCorreo.BodyEncoding = System.Text.Encoding.UTF8
‘Definimos la prioridad del mensaje
MiCorreo.Priority = System.Net.Mail.MailPriority.Normal
‘Indicamos si el cuerpo del mensaje es HTML o no
MiCorreo.IsBodyHtml = False
’Añadimos el fichero adjunto
Dim MiFichero As Attachment = New Attachment(“Ruta y nombre de fichero”)
MiCorreo.Attachments.Add(MiFichero)

En C#:

//Definimos la clase MailMessage


MailMessage MiCorreo = new System.Net.MailMessage();

//Indicamos Email origen


MiCorreo.From = new MailAddress(“Email origen”, “Nombre del origen”);
//Añadimos la dirección correo del destinatario
MiCorreo.To.Add(“Correo destino”);
//Incluimos el asunto del mensaje
MiCorreo.Subject = “Texto de mi Asunto”;
//Añadimos el cuerpo del mensaje
MiCorreo.Body = “Cuerpo del Mensaje”;
//Indicamos el tipo tipo de codificación del mensaje
MiCorreo.BodyEncoding = System.Text.Encoding.UTF8;
//Definimos la prioridad del mensaje
MiCorreo.Priority = System.Net.Mail.MailPriority.Normal;
//Indicamos si el cuerpo del mensaje es HTML o no
MiCorreo.IsBodyHtml = false;
//Añadimos el fichero adjunto
Attachment MiFichero = new Attachment(@”Ruta y nombre de fichero”);
MiCorreo.Attachments.Add(MiFichero);

El último paso será enviar nuestro correo, como hemos comentado anteriormente,
usaremos la clase “SmtpClient” que nos permitirá enviar nuestro email previamente
configurado usando la clase “MailMessage”.

La clase “SmtpClient” dispone de la propiedad “Host”, a la cual le indicaremos el


nombre o dirección IP de nuestro servidor SMTP.

En el caso que nuestro servidor SMTP requiera autenticación debemos indicarle a la


propiedad “Credentials”, de la clase “SmtpClient”, los valores de usuario y contraseña
para enviar las credenciales de autenticación que serán enviadas al servidor SMTP, en el
caso que nuestro servidor no requiera autenticación este apartado lo debemos de omitir.
Para crear nuestras credenciales usaremos la clase “NetworkCredential”, que pertenece
al NameSpace “System.Net”, y nos proporciona la posibilidad de crear una
autenticación basada en usuario y contraseña.

Ya que el envío de correos es una parte del código susceptible generar errores
usaremos ”Try-Catch“ para gestionar los posibles errores que se puedan generar.

El código completo para el envío de emails es el siguiente:

En Visual Basic:

‘Declaramos la clase SmtpClient


Dim MiSmtp As New SmtpClient
‘Definimos nuestro servidor SMTP
MiSmtp.Host = “Servidor SMTP”
‘Indicamos la auteticación de nuestro servidor SMTP
MiSmtp.Credentials = New System.Net.NetworkCredential(“Usuario”,
“Contraseña”)
Try
‘Enviamos el correo
MiSmtp.Send(MiCorreo)
Catch ex As Exception
MessageBox.Show(“ERROR: “ & ex.Message)
End Try

En C#:

//Declaramos la clase SmtpClient


SmtpClient MiSmtp = newSmtpClient();
//Definimos nuestro servidor SMTP
MiSmtp.Host = “Servidor SMTP”;
//Indicamos la auteticación de nuestro servidor SMTP
MiSmtp.Credentials = new System.Net.NetworkCredential(“Usuario”,
“Contraseña”);
try
{
//Enviamos el correo
MiSmtp.Send(MiCorreo);
}
catch (Exception ex)
{
MessageBox.Show(“ERROR: “ + ex.Message);
}

El código completo en Visual Basic:

‘Definimos la clase MailMessage


Dim MiCorreo As New MailMessage

‘Indicamos Email origen


MiCorreo.From = New System.Net.Mail.MailAddress(“Email origen”, “Nombre del
origen”)
‘Añadimos la dirección correo del destinatario
MiCorreo.[To].Add(“Correo destino”)
‘Incluimos el asunto del mensaje
MiCorreo.Subject =“Texto de mi Asunto”
‘Añadimos el cuerpo del mensaje
MiCorreo.Body = “Cuerpo del Mensaje”
‘Indicamos el tipo tipo de codificación del mensaje
MiCorreo.BodyEncoding = System.Text.Encoding.UTF8
‘Definimos la prioridad del mensaje
MiCorreo.Priority = System.Net.Mail.MailPriority.Normal
‘Indicamos si el cuerpo del mensaje es HTML o no
MiCorreo.IsBodyHtml = False
‘Añadimos el fichero adjunto
Dim MiFichero As Attachment = New Attachment(“Ruta y nombre de fichero”)
MiCorreo.Attachments.Add(MiFichero)

‘Declaramos la clase SmtpClient


Dim MiSmtp As New SmtpClient
‘Definimos nuestro servidor SMTP
MiSmtp.Host = “Servidor SMTP”
‘Indicamos la auteticación de nuestro servidor SMTP
MiSmtp.Credentials = New System.Net.NetworkCredential(“Usuario”,
“Contraseña”)
Try
‘Enviamos el correo
MiSmtp.Send(MiCorreo)

Catch ex As Exception
MessageBox.Show(“ERROR: “ & ex.Message)
End Try

El código completo en C#:

//Definimos la clase MailMessage


MailMessage MiCorreo = new System.Net.MailMessage();

//Indicamos Email origen


MiCorreo.From = new MailAddress(“Email origen”, “Nombre del origen”);
//Añadimos la dirección correo del destinatario
MiCorreo.To.Add(“Correo destino”);
//Incluimos el asunto del mensaje
MiCorreo.Subject = “Texto de mi Asunto”;
//Añadimos el cuerpo del mensaje
MiCorreo.Body = “Cuerpo del Mensaje”;
//Indicamos el tipo tipo de codificación del mensaje
MiCorreo.BodyEncoding = System.Text.Encoding.UTF8;
//Definimos la prioridad del mensaje
MiCorreo.Priority = System.Net.Mail.MailPriority.Normal;
//Indicamos si el cuerpo del mensaje es HTML o no
MiCorreo.IsBodyHtml = false;
//Añadimos el fichero adjunto
Attachment MiFichero = new Attachment(@”Ruta y nombre de fichero”);
MiCorreo.Attachments.Add(MiFichero);

//Declaramos la clase SmtpClient


SmtpClient MiSmtp = newSmtpClient();
//Definimos nuestro servidor SMTP
MiSmtp.Host = “Servidor SMTP”;
//Indicamos la auteticación de nuestro servidor SMTP
MiSmtp.Credentials = new System.Net.NetworkCredential(“Usuario”,
“Contraseña”);
try
{
//Enviamos el correo
MiSmtp.Send(MiCorreo);
}
catch (Exception ex)
{
MessageBox.Show(“ERROR: “ + ex.Message);
}

¿Cómo se utilizan los eventos en .net?


En un post anterior hablaba acerca de los delegados y su función, por
si no lo leyeron o no lo recuerda (o no les intersa leerlo) lo resumo en
pocas palabras. Los delegados son el mecanísmo por el cual
indicamos cómo debe ser un método para poder interactuar con un
evento o con un método que acepte un método como parámetro.
Dicho más claro, podemos utilizar un método como parámetro de otro
método, para indicar cómo debe ser el método parámetro utilizamos
un delegado. Para los eventos es lo mismo, podemos asociar métodos
a un evento, para indicar cómo deben ser los métodos utilizamos
delagados.

¿Qué es un evento?

Un evento es un suceso, en .net es la acción de invocar un método de


una clase cliente sin conocer cuál es este método. Por ejemplo un
objeto B lanza su evento E1, ya que E1 fue asociado a el método M1
del objeto A este método es disparado al disparar el evento, sin que
el objeto B lo sepa.

¿Cómo lo hacemos?

Bien, si nosotros desde nuestra clase servidor necesitamos informar a


una clase cliente que algo ocurrió pero no conocemos a la clase
cliente lo que hacemos es crear un evento. Un evento se utiliza
asociado a un delegado, definimos un delegado que indica cómo debe
ser el método que vamos a invocar y luego el evento que lo utiliza, a
partir de esto la clase cliente puede asociar cualquier método que
cumpla con el delegado al evento, para que nosotros desde la clase
servidor disparemos el eventos y éste llame al método, pero sin saber
a qué metodo llama, es más, puede llamar a múltiples métodos de
múltiples clases sin saberlo, pero basta de charla veamos un ejemplo.

Primer ejemplo

Un caso típico de la utlización de eventos son los Winform, es éstos


los eventos se utlizan para que un objeto, por ejemplo un botón,
informe al formulario que ha sido pulsado, hagamos la siguiente
prueba, creemos un proyecto Winform y agregemos un botón el
formulario que aparece por defecto.
Si hacemos doble click sobre el botón el IDE nos envía al código.

1: private void button1_Click(object sender, EventArgs e)


2: {
3: }

Aunque pocas veces nos detenemos a pensarlo, este método se


genera automáticamente y es asociado al evento Click del botón sin
que nos enteremos, abramos el archivo Form1.Designer.cs Si vamos
al método InitilizeComponent vemos el siguiente código

1: // button1
2: // this.button1.Location = new System.Drawing.Point(24, 28);
3: this.button1.Name = "button1";
4: this.button1.Size = new System.Drawing.Size(75, 23);
5: this.button1.TabIndex = 0;
6: this.button1.Text = "button1";
7: this.button1.UseVisualStyleBackColor = true;
8: this.button1.Click += new
System.EventHandler(this.button1_Click);
9: // // Form1 //

La línea donde se encuentra la mágia es esta

this.button1.Click += new System.EventHandler(this.button1_Click);

Esto nos dice que el objeto button1 tiene su evento Click asociado el
método button1_Click, ahora ¿qué significa System.EventHandler?, los
más suspicaces adivinan que se trata de un delegado y es verdad, si
nos ponemos sobre el código y presionamos F12 vemos la definición
public delegate void EventHandler(object sender, EventArgs e);

Es un delegado, en el cual se define que los métodos que lo utilicen


debe devolver void y recibir dos parámetros. Hasta ahora es muy
claro, se define un delegado con una firma tal y se asocia un método
que cumpla con dicho delegado al evento, perfecto, pero cómo se
declara el evento?.

Declarando un evento

Ponemos el cursos sobre Click y presionamos F12, saltamos al código


de la clase Component (porque un botón hereda de ella) y vemos el
siguiente código

public event EventHandler Click

Es la definición del evento, noten que después de la palabra event se


define qué delegado se utliza, para poder asociar el evento a
cualquier método que cumpla con el mismo, por último el nombre del
evento, en este caso Click.

Asociando más métodos a los eventos

Por lo tanto podemos asociar cualquier método que cumpla con el


delegado al evento, es cierto, hagamos la prueba, definamos un
evento del siguiente modo
1: private void Form1_Load(object sender, EventArgs e)
2: {
3: this.button1.Click += MiMetodo;
4: }
5: private void MiMetodo(object sender, EventArgs e)
6: {
7: MessageBox.Show("Evento generado por " + sender.ToString());
8: }

Nuestro método "MiMetodo" cumple con el delegado EventHandler y


dentro simplemente muestra un mensaje. en la línea
this.button1.Click += MiMetodo asociamos el método al evento,
noten que no creamos un objeto EventHandler, no es necesario
gracias a la inferencia de tipos, es decir, el compilador nos ahorra el
trabajo de hacerlo porque comprueba que nuestro método cumple
con el delegado esperado, se puede hacer de cualquiera de las dos
formas, es cuestión de gustos.

Si lo corremos vemos lo siguiente


Mágico, se ejecutó nuestro método, y también se ejecuto
Button1_OnClick, y se ejecutarán todos los que se encuentren
asociados, es más un método puede encontrarse asociado a múltiples
eventos y un evento a múltiples métodos.

Un ejemplo desde cero

Hagamos un ejemplo desde cero para cerrar el concepto Supongamos


que queremos que un formulario A al presionar un botón abra un
formulario B, este formulario B tiene un botón que al presionarlo
escribe un texto en un textbox del formulario A. ¿Cómo lo hacemos?.
Primero que nada identifiquemos quién es de los dos el que dispara el
evento y quién recibe el evento. Evidentemente si desde el formulario
B necesitamos que ocurra algo en el A es claro que el formulario B
llama al A a través de un evento, por lo tanto el evento debe
encontrarse definido en el formulario B y el método que se asocia al
evento en el A. Perfecto, hay algo más, necesitamos que cuando B
llame al método de A le pase un texto para que se imprima, entonces
el delegado tiene que tener un parámetro, para que el método reciba
el texto.

Definiendo el delegado

Como dije antes necesitamos pasarle al método un texto, por lo tanto


debe recibir un parámetro del tipo string y no regresar nada, entonces
creamos otro formulario y agregamos el siguiente código:

1: public partial class Form2 : Form


2: {
3: public delegate void DelegadoMensaje(string mensaje);
4: public event DelegadoMensaje MiEvento;
5:
6: private void button1_Click(object sender, EventArgs e)
7: {
8: this.MiEvento("Hola evento con parámetros!!!");
9: }
10:
11: public Form2()
12: {
13: InitializeComponent();
14: }
15:
16: private void Form2_Load(object sender, EventArgs e)
17: {
18:
19: }
20:
21: }
Vamos paso a paso, en la línea 3 definimos el delegado para indicar
cómo deben ser los métodos que se asocien al eventos, en este caso
serán métodos que reciban un texto como parámetro y no retornen
nada. En la línea 4 definimos el evento utilizando el delegado. Luego
en la línea 8 dentro del evento que dispara el botón llamamos al
evento y le pasamos un texto, en este momento se invocarán todos
los métodos que hayan sido asociados a él.

Falta llamar desde el Form1 al Form2 y asociar un método al evento


del Form2. Hagámoslo.

1: public partial class Form1 : Form


2: {
3: Form2 form2 = new Form2();
4:
5: public Form1()
6: {
7: InitializeComponent();
8: }
9:
10: private void button1_Click(object sender, EventArgs e)
11: {
12: form2.Show();
13: }
14:
15: private void Form1_Load(object sender, EventArgs e)
16: {
17: //this.button1.Click += MiMetodo;
18: form2.MiEvento += new
Form2.DelegadoMensaje(form2_MiEvento);
19: }
20:
21: void form2_MiEvento(string mensaje)
22: {
23: this.label1.Text = mensaje;
24: }
25:
26: private void MiMetodo(object sender, EventArgs e)
27: {
28: MessageBox.Show("Evento generado por " +
sender.ToString());
29: }
30:
31: }

En la línea 3 creamos un objeto del tipo Form2, en la línea 18


asociamos el método form2_MiEvento al evento, y luego en la línea
23 actualizamos el valor de la etiqueta, por lo tanto, el método
form2_MiEvento va a ser invocado desde el Form2 cuando se presione
el botón. Vamos a probarlo.
Funciona, perfecto, esto es sólo una introducción, hay muchas cosas
interesantes acerca de los eventos, se pueden utilizar en aplicaciones
de consola, en ASP.NET. Nos vemos en la próxima

ASP.NET MVC Framework


Ok, no descubro nada nuevo Microsoft está gestando un framework
de desarrollo Web que soporta el patrón MVC (model view controller)
tenía un poco de fiaca de postear sobre él y sobre todo estaba
esperando que se encuentre un poco más cocinado, ya me pasó con
Linq de hacer una aplicación que lleve a producción y en medio de
todo eso cambió la especificación, sí, ya sé soy un kamikaze y quién
no lo es un poco, de todos modos ya había utilizando año y medio
atrás monorail que es casi lo mismo, ASP.NET MVC tiene un poco del
estilo Microsoft en el sentido que algunas cosas son más fáciles, por
ejemplo se puede utilizar toda la potencia de Linq y Linq To Sql, en fin
basta de dar vueltas.

Aprovechando la generosidad de José María Aguilar para hacer un


template de ASP.NET MVC para Visual Web Developer express le eché
mano a esto, recomiendo que visiten el blog de José María es muy
bueno. Bien, tiempo atrás estuve en Microsoft viendo una
presentación acerca de este framework (hablando de cambio entre la
versión que nos presentaron y la actual hay cambios, en fin) y
terminé de caer en que no es muy diferente a monorail.

Vamos a dejarnos de previas y a comenzar.

Necesitamos bajar el Visual Web Developer express, el MVC


framework y el template de José María

El zip lo colocamos en

Mis documentos\Visual Studio 2008\Templates\ProjectTemplates\Visual


Web Developer

tal cual está sin descomprimir

Con todo esto listo abrimos el VWD (Visual Web Developer) y nos
aparece la siguiente opción
Hacemos Ok, y tenemos la siguiente estructura por defecto

ok, vamos a explicar qué es esto.

Qué es MVC

Es un patró de diseño, la idea es que una aplicación se compone de


tres elementos básico

Modelo: Representa el modelo de dominio, los datos, en general


entidades de datos o acceso a datos depende, también la forma de
manipularlos, lógica de negocios, etc.

Controller: Controlan la vista, la forma de interactuar.

View: La presentación, el render de los datos.

Bien, esto parece una simple arquitecutra en capas de lo más


pedorra, sin embargo es muy estricto, por ejemplo la vista no puede
hacer más que mostrar datos, nada de lógica de nada.
Entonces analicemos los archivos que se generan cuando creamos el
proyecto

Las tres carpetas que nos interesan son Models, Views y Controller
(aunque resulte increíble), este es un detalle importante, el
framework nos obliga a separar todo en carpetas porque va a tomar
decisiones de dónde ir a buscar cosas por convenciones una de éstas
es la estructura de directorios.

Necesitamos sí o sí tener estos directorios sino, no funciona nada,


bien, primer punto claro.

Ahora bien, vamos a ver qué nos dejó José María en la carpeta
Controllers, hay un archivo llamado HomeController y aquí otra
convención los controladores se llamarán siempre AlgoController, más
adelante vamos a ver por qué.

Vamos al código del HomeController, al método Index

public void Index()


{
RenderView("Index");
}

Otra convención es el nombre de los métodos públicos, éste método


publico Index dentro del controllador HomeController le dice al
framework que cuando desde el navegador haga

miSitio/home/index

Se va a invocar éste método, re loco no?, esto le llaman ruteo y en el


caso del ASP.NET MVC se puede alterar el comportamiento pero por
defecto es así.

Ahora qué es lo que se va a mostrar, vemos dentro del método Index


una invocación al método RenderView los más suspicaces se darán
cuenta que de esta manera llamamos a la vista, ahora, le decimos
RenderView("Index") notar que no le decimos ni la ruta ni la
extensión, otra convención, ya que nos encontramos en el
HomeController el framework va a buscar en Views/Home/Index, otra
vez nos obliga a trabajar ordenadamente, más aún, si quisieramos
pasarle datos a la vista para que los renderice se los pasamos como
parámetro y no mucho más, nada de ida y vuelta o de lógica en la
presentación, vamos a ver el método Links

public void Links()


{
string[] links =
{ "http://www.variablenotfound.com",
"http://www.microsoft.com",
"http://www.asp.net",
};
RenderView("Links", links);
}

como podemos ver llamamos a la vista Links de Home y le pasamos


un array de string, ahora vamos a ver el código de la vista

La Vista

public partial class Views_Home_Links : ViewPage<string[]>


{
protected void Page_Load(object sender, EventArgs e)
{
}
}

Antes que nada notemos que para que se una página se comporte
como una vista MVC es necesario que herede de ViewPage, en caso
que necesitemos pasarle datos a la vista para que los renderice se los
pasamos como un tipo genérico como en éste caso ViewPage esto va
a permitir que funcione el intellisense desde el lado de la vista,
veámoslo.

<ul>
<% foreach (string s in ViewData) { %>
<li><a href="<%= s %>"><%= s %></a></li>
<% } %>
</ul>

Como vemos hay una propiedad ViewData de ViewPage que se llena


cuando invocamos a la vista con RenderView("vista", viewData), le
indicamos el tipo cuando hacemos

Pagina: ViewPage<tipodatos>

y listo, tenemos intellisense para ViewData del lado de asp.net.


Para manipular la forma que mostramos los datos podemos usar toda
la potencia de .net, incluso se irán agregando helpers para hacer
cosas como grilla según me han contado.

Bueno, hasta acá la introducción a medida una intro nada más, en


medida que se vayan asentando las cosas imagino que vamos a ver
más, saludos.