jueves, 31 de marzo de 2011

Ejercicio. Servicio web que calcula la letra del DNI


Crea un servicio web y una interfaz que lo use en la que, introduciendo el DNI de una persona, obtenemos su letra correspondiente.

NOTA: Puedes consultar el algoritmo necesario y servirte del código de este link

Ejercicio. Consultar información de códigos IANA


Utiliza el siguiente servicio web, http://xmethods.com/ve2/ViewListing.po;jsessionid=eNKpjiPDB3WDG5g4ePRdh4uL?key=467143, para crear una interfaz web en la que dado el dominio primario de internet de un país (código IANA) nos muestre su nombre, latitud y longitud.

Ejercicio. Habilitar acceso por login.


A la aplicación web del último ejemplo posteado ("Consulta de notas de un alumno") vamos a incluirle un control de acceso de manera que sólo el usuario que nosotros registremos pueda utilizarla. Sigue los pasos:

Primero vamos a crear el formulario para loguearnos:
  1. Abre la solución de consulta de notas de un alumno.
  2. En el explorador de soluciones haz clic con el botón derecho del ratón sobre la raíz del árbol de exploración que representa el proyecto y selecciona la opción "Agregar nuevo elemento"
  3. En el cuadro de diálogo selecciona "Web Forms" y ponle como nombre "Login.aspx". Recuerda marcar C# como lenguaje de nuestro nuevo Web Form.
  4. Accede a la vista diseño de Login.aspx e inserta un objeto "Login". Lo encontrarás en el cuadro de herramientas, en el subgrupo "Inicio de sesión"
Ahora, para proteger el conjunto de nuestra aplicación la meteremos en una subcarpeta dentro del sitio:
  1. En el explorador de soluciones haz clic con el botón derecho del ratón sobre la raíz del árbol de exploración que representa el proyecto y selecciona la opción "Nueva carpeta". Ponle de nombre "Aplicacion".
  2. Arrastra los archivos que forman parte de la aplicación a la nueva subcarpeta, esto es, "ConsultarNotas.aspx" y "ResultadoForm.aspx". No obstante, no arrastres el archivo "web.config"
Nos queda crear un usuario y darle los permisos apropiados:

  1. Vuelve a la vista diseño de Login.aspx, selecciona el control Login y haz clic en la fecha de la parte superior derecha para abrir sus opciones. Selecciona "Administrar sitio web"
  2. Se abrirá una ventana de configuración en el navegador.
  3. En la pestaña "Página principal" haz clic en "Seguridad".
  4. Ahora, haz clic en "Utilice el Asistente para la configuración de seguridad para configurar la seguridad paso a paso" y se iniciará un asistente de configuración.
  5. El paso 1 es la bienvenida. Simplemente haz clic en "Siguiente"
  6. En el paso 2, "Seleccionar método de acceso", marca la opción "Desde Internet". Haz clic en "Siguiente"
  7. Ignora los pasos 3 y 4 pulsando en "Siguiente"
  8. En el paso 5, "Agregar nuevos usuarios", te aparecerá un formulario para crear un nuevo usuario. Rellena todos los campos y haz clic en "Siguiente"
  9. El paso 6 te permite añadir reglas de acceso. Tenemos que centrarnos en la subcarpeta que queremos proteger, esto es, la subcarpeta "Aplicacion". Así que selecciónala en el árbol de la izquierda expandiendo primero el nodo principal (clic en el símbolo [+]).
  10. Debes añadir dos reglas: la primera que deniegue el permiso a los usuarios anónimos y la segunda que permita el acceso al usuario que creaste en el paso 5. No olvides pulsar el botón "Agregar esta regla" una vez configuradas las opciones para que quede guardada.
  11. Al hacer clic en "Siguiente" habrás terminado la configuración.
Finalmente, añadimos unos pequeños ajustes al archivo "web.config". En realidad, ahora tendrás dos "web.config". Si haces clic con el botón derecho en la carpeta "Aplicación" en el explorador de soluciones y seleccionas la opción "Actualizar carpeta" verás que el asistente te ha añadido un archivo "web.config" en la subcarpeta. Si lo abres verás las reglas de acceso definidas:

Aclarado esto, vamos a abrir el otro "web.config", el que está en la raíz del sitio web y busca la etiqueta . Como puedes observar, está cerrada, no se ha incluido nada en ella. Simplemente ábrela y añade las siguientes etiquetas para indicar la página de login a la que debe redirigirnos la aplicación en caso de que intentemos acceder a un recurso protegido sin habernos logueado así como la página por defecto a la que se redirigirá el flujo una vez que el login ha tenido éxito.



Ya puedes ejecutar la aplicación y comprobar que funciona. Es importante que limpies las cookies del navegador entre prueba y prueba porque puede suceder que pienses que la aplicación te está dejando acceder directamente a la página protegida sin haber hecho login cuando quizás no haya expirado el tiempo máximo de login de un acceso correcto anterior.

Debes verificar que:

  1. Si escribes la URL de la página "ConsultarNotas.aspx" en el navegador, te redirige a la página de login.
  2. Si ingresas correctamente el usuario y la contraseña te redirige a la aplicación para consultar las notas.
  3. Puedes seguir accediendo a "ConsultarNotas.aspx" aunque cierres la pestaña del navegador y vuelvas a entrar, pero siempre dentro del límite de tiempo establecido en el archivo de configuración.


miércoles, 30 de marzo de 2011

Ejemplo. Consulta de notas de un alumno




En esta aplicación de ejemplo, veremos cómo incorporar accesos a bases de datos desde formularios web usando los controles de Visual Web Developer. Además revisaremos otros aspectos como las cookies y la interacción entre varios formularios web. Consiste en una página de consulta donde un alumno introduciendo su clave o número de control podrá consultar las notas de las distintas materias en las que está matriculado.

Trata de realizar algo similar con esta base de datos de Libros. Simplemente utiliza la tabla BOOKS para realizar consultas por género (campo DETCAT).

martes, 29 de marzo de 2011

Ejemplo de control de usuario personalizado

Examina este ejemplo de control de usuario personalizado. En él se implementa un cuadro de texto que nos avisa de que el dato introducido debe ser numérico en caso de que hayamos introducido caracteres no numéricos.

Puedes seguir el ejemplo paso a paso en este tutorial. La única diferencia es que en él en vez de colocar en el cuadro de texto un aviso simplemente se vacía.

Ejercicio. Conversor de moneda

Crea un sencillo conversor de moneda que sea capaz de pasar valores a Euros, Dólares americanos y Rublos sabiendo que a día de hoy 1 € = 1.4083 USD y 1€= 39.9563 RUB. No obstante, y para poder modificar dichos valores en un futuro, inclúyelos como parámetros en web.config.

Asimismo, utilizando cookies o sesiones, haz que en la etiqueta del resultado siempre se muestre la última conversión aunque se cierre la ventana del navegador y se vuelva a entrar, siempre que no expire el tiempo de la sesión.

Por otra parte, convierte el campo de texto donde se introduce la cantidad en un campo obligatorio utilizando un objeto de validación.

Haz clic aquí para descargar una posible solución

Ejemplo del uso de sesiones en ASP.NET


En este ejemplo se emplea una variable de sesión BackgroundColor para mantener el color de fondo elegido por el usuario en el primer acceso al servidor en solicitudes posteriores, no pudiéndose variar mientras no expire el tiempo máximo de la sesion.

Solución al ejercicio propuesto de Threads "pang-ping-pong-pung"


using System;
using System.Threading;

namespace PangPingPongPung
{


public class Contador
{
const int NUM_HILOS=4;
private int Turno;
private string[] Mensajes={"pang", "ping", "pong", "pung"};

public Contador(int Turno)
{
this.Turno=Turno;
}

public void Incrementar()
{
Turno++;
}

public string ValorActual()
{
return (Turno%NUM_HILOS).ToString();
}

public string MensajeActual()
{
return Mensajes[Turno%NUM_HILOS];
}

}

class Program

{
private Contador c;
const int NUM_HILOS=4;
public Program(int turnoInicial)
{
Thread [] vThreads=new Thread[4];
c=new Contador(turnoInicial);
for (int I=0; I<NUM_HILOS; I++) {
vThreads[I]=new Thread(new ThreadStart(pangpingpongpung));
vThreads[I].Name=I.ToString();
vThreads[I].Start();
if (I<NUM_HILOS-1)
vThreads[I].Join(20);
else
vThreads[I].Join(10000);
}
for (int I=0; I<NUM_HILOS; I++)
vThreads[I].Abort();

Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
}

public static void Main(string[] args)
{
Program p=new Program(0);
}




public void pangpingpongpung()
{
while (true) {
Monitor.Enter(c);
try{
if (Thread.CurrentThread.Name==c.ValorActual()) {
Console.WriteLine(c.MensajeActual());
c.Incrementar();
int esperaAleatoria=new Random(
DateTime.Now.Millisecond).Next()%500;
Thread.Sleep(esperaAleatoria);
}
}
finally {
Monitor.Exit(c);
}
}
}
}
}

lunes, 28 de marzo de 2011

Ejemplo. Visto en clase: Iniciación a ASP .NET

Archivo default.aspx.cs

using System;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections;
using System.Collections.Specialized;


public partial class _Default : System.Web.UI.Page
{

protected void BtnEnviar_Click(object sender, EventArgs e)
{
EtiRespuesta.Visible = true;
EtiRespuesta.Text = "Hola " + TxtNombre.Text;

Response.Write("Estoy escribiendo con el objeto Response
");
Response.Write("Información del objeto Request " +
Request.Browser.Browser+"
);


// Visualizando la colección de parámetros
// del archivo web.config
NameValueCollection Coleccion;

Coleccion=(NameValueCollection)Context.GetConfig("appSettings");
for (int iCtr = 0; iCtr < Coleccion.Count; iCtr++)
{
String s = Coleccion.Keys[iCtr];
Response.Write(s+" "+Coleccion[s]+"
");
}

}
protected void Page_Load(object sender, EventArgs e)
{
if (Request.Cookies["ultimaVisita"] == null)
Response.Write("Es tu primera visita");
else
Response.Write("Tu última visita fue: "+
Request.Cookies["ultimaVisita"].Value);

Response.Cookies["UltimaVisita"].Value=DateTime.Now.ToString();
Response.Cookies["UltimaVisita"].Expires=DateTime.Now.AddMinutes(2);
}
}

Desarrollo de aplicaciones Web con Microsoft ASP.NET utilizando Visual Studio .NET

Si utilizas un navegador distinto a Microsoft Explorer puede que no visualices adecuadamente el curso. Haz clic en la imagen para iniciarlo



Haz clic en la imagen para bajar el contenido del curso en PDF

sábado, 26 de marzo de 2011

Ejercicio. Ping Pong concurrente.

Sincroniza dos threads de manera que uno escriba Ping por pantalla sólo cuando el anterior allá escrito Pong, alternando de forma perfecta las dos escrituras. Emplea los métodos Enter() y Exit() de la clase Monitor.

NOTA: debido al boxing y unboxing (conversión de los tipos primitivos a su respectivo objeto del CTS y viceversa), bloquear tipos primitivos puede hacer que no funcionen los bloqueos. Envuelve dichos tipos en una clase creada por ti para evitarlo.

Haz clic en la imagen para descargar la solución al problema de Ping Pong con monitores.


PROBLEMA PROPUESTO. Realiza el mismo ejercicio pero con cuantro hilos que escriban de forma alterna Pang-Ping-Pong-Pung

Dudas alumnos. Qué diferencia hay entre Monitor.Try() y Monitor.TryEnter()

Con TryEnter si el recurso está libre se bloquea, si no, se espera el tiempo especificado. En caso de que el tiempo expire y el recurso siga bloquedo se devuelve False para poder continuar con otros procesos si es preferible a esperar por conseguir el recurso compartido.


public bool WaitToAddElement(object qValue, int waitTime)
{
if(!Monitor.TryEnter(m_inputQueue,waitTime))
return false;
m_inputQueue.Enqueue(qValue);
Monitor.Exit(m_inputQueue);

return true;
}




En cambio, con Enter, el hilo se bloquearía sin condiciones si el recurso está siendo usado por otro hilo.

public void AddElement(object qValue)

{
Monitor.Enter(m_inputQueue);
m_inputQueue.Enqueue(qValue);
Monitor.Exit(m_inputQueue);
}

Suspend y Resume obsoletos. Cómo resolver el problema

ANTES:

private Thread myThread;

private void WorkerThread()
{
myThread
= Thread.CurrentThread;
while (true)
{
myThread
.Suspend();
//Ejecutar tareas
}
}

public void StartWorking()
{
myThread
.Resume();
}


***************************************

AHORA:



...

private static EventWaitHandle wh;

...

wh = new EventWaitHandle(false,EventResetMode.AutoReset);

...

private
void WorkerThread()
{


while(true)
{
wh.WaitOne();

//Ejecutar tareas
}
}

public void StartWorking()
{
wh.Set();

}

jueves, 24 de marzo de 2011

Ejercicio. Repaso


A partir de los pasos vistos en los ejercicios anteriores de ADO.NET trata de realizar el ejercicio planteado (Haz clic en la imagen para verlo). El único cambio a adoptar es utilizar una base de datos Access en lugar de una base de datos SQL Server. Trata de guiarte por los conocimientos adquiridos más que por las propuestas del ejemplo, en caso de duda.

Ejercicio. Cargar el archivo de Base de Datos .mdb al arrancar la aplicación




Si quisiésemos que la aplicación diese la oportunidad de cargar un archivo de Access específico al abrir el formulario principal, sólo tendríamos que añadir un objeto OpenFileDialog para cargar la ruta del archivo:


public MainForm()
{

OpenFileDialog of = new OpenFileDialog();
of.ShowDialog();
string direccion = of.FileName;

con = new OleDbConnection(

"Provider=Microsoft.Jet.OLEDB.4.0;
Data Source="+direccion+";
Persist Security Info=True");

con.Open();
InitializeComponent();


}

Libros. Para saber más... ADO .NET step by step

[Haz clic en la portada del libro para descargarlo]


  • Conectarse a orígenes de datos externos, incluyendo bases de datos y otras formas de almacenamiento.
  • Uso del framework ADO.NET para interactuar con almacenes de datos subyacentes.
  • Crear modelos de entidad con herramientas de diseño gráfico en Visual Studio 2010
  • Vincular datos directamente a tus formularios Windows y Web para proporcionar información a los usuarios.
  • Manejar datos e información aislada sin estar conectado directamente a una base de datos.

Ejercicio. Habilitar un cuadro de búsqueda


Añade un cuadro de búsqueda simple de tal modo que al introducir el nombre de la persona buscada se marque el registro correspondiente a la misma. En caso contrario, se visualizará una ventana de alerta advirtiéndonos de que el nombre no existe. Para ello, inserta mediante el diseñador de formularios un cuadro de texto (llámale txtBusquedaNombre) y un botón (llámale btnBusqueda) En el método que atienda el evento de clic incluye un código como este adaptándolo a los nombres de objetos de tu proyecto (aquí bs es el objeto BindingSource)

  int elementoEncontrado =
bs.Find("Nombre",textBusquedaNombre.Text );
if (elementoEncontrado>=0)
bs.Position = elementoEncontrado;
else MessageBox.Show("Nombre no encontrado");

Ejercicio. Insertar controles de navegación


Partiendo de tu proyecto del ejercicio anterior o de este proyecto ya resuelto, añade una barra de navegación que permita moverse por los registros de la tabla. Para ello, inserta utilizando el IDE de Sharp Develop un control de tipo BindingNavigator. Para mayor claridad del código, llámale Navegador. El navegador ya implementa toda la funcionalidad necesaria; lo único que tienes que hacer es asociarlo al objeto BindingSource vinculado a los datos. Es decir añade el código marcado en rojo:


ds=new DataSet();
OleDbCommand cmd = new OleDbCommand(
"Select Id, Nombre, Edad from Persona",con);
da=new OleDbDataAdapter(cmd);
cb = new OleDbCommandBuilder(da);
da.Fill(ds);
bs=new BindingSource();
bs.DataSource=ds.Tables[0];
dgPersona.DataSource=bs;
Navegador.BindingSource=bs;


Si haces clic sobre el objeto BindingNavigator en el diseñador de formularios aparecerá una flecha negra en la esquina superior derecha del control desde la que puedes acceder a la opción Dock (anclar). Selecciona Button para colocar el navegador en la parte inferior de la ventana tal y como se muestra en la figura, de manera que no se solape con los controles ya dispuestos sobre el formulario principal.

*************************************


Ahora imagina que no dispusieses del objeto BindingNavigator y tuvieses que conseguir la misma funcionalidad de desplazamiento con botones y una etiqueta que muestre en qué registro nos encontramos del total. Descarga el siguiente proyecto de codeproject.com en el que se implementa este aspecto para una base de datos SQL Server. Aunque no lo podrás ejecutar directamente sí se representa en el diseñador de formularios, lo que te permitirá rastrear los métodos asociados a los eventos de clic de cada botón. En realidad, el proceso resulta tan simple como invocar a los métodos moveFirst(), moveLast(), moveNext() y movePrevious() del objeto BindingSource con alguna lógica adicional. Haz lo mismo sobre tu proyecto.

miércoles, 23 de marzo de 2011

Ejercicio. Vincular campos de texto a un BindingSource.


Sobre el proyecto del ejercicio anterior, vamos a hacer que cada vez que haga clic en un registro del DataGridView, automáticamente se visualice el nombre y la edad de la persona seleccionada en los cuadros de texto correspondientes. Para ello modifica el método que trata la carga del formulario de la siguiente manera:


void MainFormLoad(object sender, EventArgs e)
{
this.ActualizarGrid();
this.txtNombre.DataBindings.Add(
new Binding("Text",bs,"Nombre",true));
this.mstxtEdad.DataBindings.Add(
new Binding("Text",bs,"Edad",true));
}

Aquí, this.txtNombre y this.mstxtEdad son los campos de texto del Nombre y la Edad de la persona respectivamente; bs es nuestro objeto BindingSource y "Nombre" y "Edad" son los campos de la tabla Persona en la base de datos. Text es la propiedad de los controles en la que almacenamos los valores y el valor booleano true me indica que dejo habilitado el formateo de datos.

Ejercicio. Guardar cambios de un DataGridView en la Base de Datos


Partiendo de este proyecto, similar al que ya usamos para agregar personas a una tabla pero usando un DataSet en lugar de un DataReader, trata de incluir un objeto BindingSource que permita guardar las modificaciones o eliminaciones que hagamos sobre el DataGridView. Para ello, añade a la interfaz un botón para guardar los cambios y ten en cuenta los pasos necesarios que se indican a continuación. Añade los que no están implementados para dotar a la aplicación de la nueva funcionalidad.

// necesitamos una cadena de conexión que variará según el tipo de base de datos a la que nos conectemos.

string connString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\miBaseDeDatos.mdb";

La cadena de conexión está formada por dos partes: un proveedor y un origen de datos. El proveedor es el motor de base de datos que estamos usando, en este caso un motor Jet de Microsoft. El origen de datos para una base de datos Access es simplemente la trayectoria del fichero .mdb

Ahora usaremos la cadena de conexión para conectarnos y conseguir los datos que queremos.

//crear la conexion
string conn = new OleDbConnection(connString);

//crear la consulta a la base de datos
string query = "SELECT * FROM MiTabla";

//crear un adaptador para ejecutar la consulta
OleDbDataAdapter dAdapter = new OleDbDataAdapter(query, conn);

//crear un constructor de sentencias
OleDbCommandBuilder cBuilder = new OleDbCommandBuilder(dAdapter);

//crear un DataTable que almacene el resultado de la consulta
DataSet dSet = new DataSet();

//rellenar el DataSet con la información que le pasa el adaptador
dAdapter.Fill(dSet);

*******

Ahora veremos como se sincroniza el DataSet con la información de la base de datos a traves del DataGridView:

//creamos el DataGridView
DataGridView dgView = new DataGridView();

//creamos un BindingSource para sincronizar la información del DataSet y la del DataGridView
BindingSource bSource = new BindingSource();

//el origen de datos del BindingSource es la única tabla de datos que contiene el DataSet,
// la primera de la colección Table
bSource.DataSource = dSet.Table[0];

//y el origen de datos del DataGridView es el BindingSource
dgView.DataSource = bSource;

*********


Finalmente, podemos habilitar un botón que al hacer clic sobre él actualice los cambios del DataGridView pasándolos al DataSet y finalmente a la base de datos. Para ello en el método que trate el evento de clic sólo hay que añadir:


dAdapter.Update(dSet);


*********

NOTA: la solución a este probrema sería prácticamente idéntica si en lugar de un DataSet, utilizamos un DataTable, con la única diferencia de que cuando se le asigna el origen de datos al DataBinding éste sería directamente el DataTable.

Solución...al problema planteado de listar los tipos de películas en un ComboBox.


  1. Incluir en el formulario un ComboBox. Le llamaremos, por ejemplo, ComboTipo. También una etiqueta que identifique el campo tipo de película.
  2. Al método que trata el evento de clic de dicho ComboBox le añadimos el siguiente código:

    String sql = "SELECT typeID, Type FROM movietype";
    Conexion.Open();
    OleDbDataAdapter da = new OleDbDataAdapter(sql, Conexion);
    DataTable dt = new DataTable("TiposPeliculas");
    da.Fill(dt);

    this.ComboTipo.DataSource = dt;
    this.ComboTipo.DisplayMember = "Type";
    this.ComboTipo.ValueMember = "typeID";
    Conexion.Close();

    Observa que aprovechamos el objeto "Conexion" que ya teníamos. En cambio, necesitamos modificar la consulta del adaptador. Lo mejor es crear un adaptador nuevo, como se indica aquí. Con esto, aparecerá la lista desplegable de tipos de películas cada vez que hagamos clic en el cuadro combinado. No obstante, el valor que nos interesa recoger es el identificador del tipo de película. Ya solo queda pasar dicho valor a la sentencia de inserción.
  3. En el método que atiende el evento de clic del botón Insertar, modificamos la sentencia de inserción. A los dos campos de prueba que ya introducíamos (en este ejemplo: título de la película y distribuidora) le añadimos el valor del cuadro Combinado referido al tipo de la película.

    void BtnInsertarClick(object sender, System.EventArgs e)
    {
    string strTitulo = "";
    string strDistribuidor = "";

    strTitulo = TextTitulo.Text;
    strDistribuidor = TextDistribuidor.Text;
    OleDbConnection con = new OleDbConnection
    ("Provider=Microsoft.Jet.OLEDB.4.0;
    Data Source=moviedb.mdb");
    con.Open();
    OleDbCommand Comando2 = new OleDbCommand(
    "Insert into movie (Title, Publisher, typeID)
    Values ('" + strTitulo + "', '" + strDistribuidor
    + "',"+ComboTipo.SelectedValue.ToString()+")",con);
    Comando2.ExecuteNonQuery();
    con.Close();
    mostrarDatos();
    }

  4. Ahora, cada vez que incluyes una nueva película, aparecerá correctamente insertado su tipo.

martes, 22 de marzo de 2011

Ejemplo. Enlazar un DataTable con un ComboBox

En este caso, queremos mostrar el nombre de los bancos en la lista desplegable y almacenar como valor del ComboBox su ID.


Puedes enlazar un control ComboBox con un objeto DataTable:

using System.Data.SqlClient;

try
{
// Construimos la consulta SQL de selección
String sql = "SELECT IdBanco, Nombre FROM Bancos";

// Creamos un adaptador de datos

OleDbDataAdapter da = new OleDbDataAdapter(sql, cnn);

// Creamos un nuevo objeto DataTable

DataTable dt = new DataTable("Bancos");

// Rellenamos el objeto DataTable

da.Fill(dt);

// Configuramos el control ComboBox

this.comboBox1.DataSource = dt;
this.comboBox1.DisplayMember = "Nombre";
this.comboBox1.ValueMember = "IdBanco";
}

catch (Exception ex) {
MessageBox.Show (ex.Message);
}
}

Ejemplos ADO.NET - Familiarizarse con objetos de acceso a bases de datos y herramientas del IDE

1.- Crea una nueva aplicación Windows en Sharp Develop.
2.- Añade en el panel de Herramientas del diseñador de interfaz (pestaña Data) los objetos OleDb para poder conectarnos a una Base de Datos Access.
3.- Descarga esta base de datos Access de ejemplo y guárdala en la subcarpeta bin/debug de la carpeta del proyecto para que sea directamente accesible desde la aplicación.
4.- Inserta los siguientes objetos OleDb:

  • un objeto OleDbConnection (llámale Conexion) y en la propiedad ConnectionString introduce la cadena "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=moviedb.mdb"
  • un objeto OleDbCommand (llámale Comando) con la propiedad CommandText "SELECT movieID, Title, Publisher, Previewed, MovieYear, Type FROM movie, movieType WHERE movietype.typeID = movie.typeID", en la propiedad Connection selecciona el objeto Conexion.
  • un objeto OleDbDataAdapter (llámale Adaptador) ; en el apartado de SelectCommand selecciona Comando y asegúrate de que la propiedad Connection del subgrupo toma el valor del objeto Conexion.
5.- Inserta un objeto de tipo DataGridView en el formulario y llámale Cuadricula.

6.- Añade el siguiente método a la clase MainForm en el archivo MainForm.Designer.cs e invócalo desde el constructor de MainForm en MainForm.cs después de la inicialización de componentes.

public void mostrarDatos()
{
Conexion.Open();
Cuadricula.Columns.Clear();
DataTable TablaDatos=new DataTable();
Adaptador.Fill(TablaDatos);
Cuadricula.DataSource=TablaDatos;

Conexion.Close();
}
7.- Ejecuta el proyecto y deberás ver un listado con todas las películas que incluye la base de datos, incluyendo el género.


8.- Descarga este otro proyecto con una base de datos Access. Hazlo funcionar y fíjate en las diferencias que supone emplear un objeto OleDbDataReader. Descarga aquí la base de datos en formato mdb

9.- Aquí tienes un ejemplo más completo de empleo de bases de datos en C# que hace uso de la misma base de datos que el ejemplo inicial. Escudríñalo e intenta agregar alguna de sus características al ejemplo inicial (borrado o edición de datos, por ejemplo)

10. Puedes consultar este tutorial de manejo de los objetos ADO .NET

lunes, 21 de marzo de 2011

Ejercicio. Cálculo del interesés y capital acumulado


Crea una aplicación sencilla que dado el capital y la tasa de interés calcule el interés conseguido y el capital final. La fórmula para el cálculo del interés es I=(C*t)/100 siendo C el capital inicial y r la tasa de interés nominal anual en tanto por ciento. El capital acumulado será el capital inicial más el interés.


La lógica principal de acuerdo a esta fórmula sería la siguiente:


Decimal cap, tp, res;
String formato = "{0:#,###,###,##0.00}";
try
{
cap = Convert.ToDecimal(Capital.Text);
tp = Convert.ToDecimal(TpInterés.Text);
}
catch (FormatException exc)
{
cap = 0; tp = 0;
}

// Cálculos de los resultados
res = Convert.ToDecimal(cap * tp / 100);
InterésPro.Text = String.Format(formato, res);
res += cap;
CapitalAc.Text = String.Format(formato, res);

Ejercicio. Diseñar el juego Pong


Crea una nueva aplicación de Windows en Sharp Develop, agrega los controles necesarios para conformar la interfaz y que resulte similar a la que se muestra en la figura y sustituye el código del MainForm por el que se muestra a continuación. En concreto, la pelota se simula con un RadioButton y las palas con dos Buttons sin texto. Habrá un menú sencillo (ToolStrip) desde el que se puede iniciar una nueva partida, mostrar una pequeña ventana de ayuda con las teclas que permiten deslizar las palas y una opción de salida (ToolStripLabels). Asimismo se reproducirá un sonido WAV cada vez que la pelota toque las palas. No olvides vincular cada delegado con el método del código que atenderá cada evento. Por otra parte, se necesita un componente Timer para generar el movimiento de la pelota. NOTA: Para mejorar la corrección y legibilidad del código sustituye la codificación
   1 -> Derecha      -1 -> Izquierda
1 -> Abajo        -1 -> Arriba
'u' (up) -> arriba     'd' (down) -> abajo
por enumerados.
DESCARGA EL CÓDIGO AQUÍ
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace Pong
{
public  partial class MainForm : Form
{
//  1 -> Derecha      -1 -> Izquierda
//  1 -> Abajo        -1 -> Arriba
private int dx = -1, dy = 1;

// Variables q contiene la ultima tecla pulsada por cierta pala
// para q el rebote se efectue en una o otra direcion
// 'u' (up) -> arriba     'd' (down) -> abajo
private char d1, d2;


public MainForm()
{
InitializeComponent();
}

void reproducirSonido()
{
System.Media.SoundPlayer player = new System.Media.SoundPlayer();
player.SoundLocation = @"C:\WINDOWS\Media\ding.wav";
player.Play();
}

void Timer1Tick(object sender, EventArgs e)
{
// Movemos la "pelota"
pelota.Left += dx;
pelota.Top  += dy;

// Para el movimiento de la pelota

//dx = pelota.Location.X >= this.ClientSize.Width ? -1 : dx;
//dx = pelota.Location.X  == 0 ? 1 : dx;

if (pelota.Location.X + 18 >= this.ClientSize.Width)
{
Timer1.Enabled = false;
MessageBox.Show("Gana el jugador 1", "Felicidades");
}
if (pelota.Location.X == 0)
{
Timer1.Enabled = false;
MessageBox.Show("Gana el jugador 2", "Felicidades");
}

// Si choca contra la parte inferior o el menú
dy = pelota.Location.Y + 50  >= this.ClientSize.Width ? -1 : dy;
dy = pelota.Location.Y  == 25 ? 1 : dy;

// Si choca contra la pala1

if (pelota.Left == pala1.Left + pala1.Width)
{
reproducirSonido();
if (pelota.Top > pala1.Top && pelota.Top < dx =" 1;" dy =" d1" left ="="> pala2.Top && pelota.Top < dx =" -1;" dy =" d2" a =" arriba," z =" abajo" k =" arriba," m =" abajo" top =" 25;" d1 =" 'u';">= this.ClientSize.Height)
             pala1.Top = this.ClientSize.Height - pala1.Height;
           d1 = 'd';
           break;

case 'K':
         //La pala2
         pala2.Top -= 10;
         if (pala2.Top  < top =" 25;" d2 =" 'u';">= this.ClientSize.Height)
           pala2.Top = this.ClientSize.Height - pala2.Height;
        d2 = 'd';
        break;
}
}


// Las opciones del menú
void NuevoToolStripMenuItemClick(object sender, EventArgs e)
{
Timer1.Enabled = true;
pelota.Left = 154;
pelota.Top  = 134;
}

void ControlesToolStripMenuItemClick(object sender, EventArgs e)
{

MessageBox.Show ("Pulsar las teclas A y K para subir y las
    teclas Z y M para bajar las respectivas paletas de los
    jugadores 1 y 2", "Controles");
}

void SalirToolStripMenuItemClick(object sender, EventArgs e)
{
Application.Exit();
}
}
}

Ejercicio. Diseña la interfaz gráfica de una calculadora


Crea un nuevo proyecto de aplicación Windows en Sharp Develop con el nombre de Calculadora y sustituye la plantilla del MainForm por este código que implementa la lógica de una sencilla calculadora capaz de sumar, restar, multiplicar y dividir. Construye la interfaz gráfica para que tenga un aspecto similar al de la figura y declara convenientemente los métodos que tratan los eventos de clic ante los delegados.

BAJA EL CÓDIGO AQUÍ

namespace Calculadora
{
enum Operacion {suma, resta, multiplicacion, division} ;

public partial class MainForm : Form
{

Operacion oper;
float primero;


public MainForm()
{
InitializeComponent();
}

void Numero7Click(object sender, EventArgs e)
{
txtnum.Text = txtnum.Text + 7;
}

void Numero8Click(object sender, EventArgs e)
{
txtnum.Text = txtnum.Text + 8;
}

void Numero9Click(object sender, EventArgs e)
{
txtnum.Text = txtnum.Text + 9;
}

void Numero4Click(object sender, EventArgs e)
{
txtnum.Text = txtnum.Text + 4;
}

void Numero5Click(object sender, EventArgs e)
{
txtnum.Text = txtnum.Text + 5;
}

void Numero6Click(object sender, EventArgs e)
{
txtnum.Text = txtnum.Text + 6;
}

void Numero1Click(object sender, EventArgs e)
{
txtnum.Text = txtnum.Text + 1;
}

void Numero2Click(object sender, EventArgs e)
{
txtnum.Text = txtnum.Text + 2;
}

void Numero3Click(object sender, EventArgs e)
{
txtnum.Text = txtnum.Text + 3;
}

void Numero0Click(object sender, EventArgs e)
{
txtnum.Text = txtnum.Text + 0;
}

void CClick(object sender, EventArgs e)
{
txtnum.Text = "";
}

void DivClick(object sender, EventArgs e)
{
oper = Operacion.division;
primero = float.Parse (txtnum.Text);
txtnum.Text = "";
}

void MulClick(object sender, EventArgs e)
{
oper = Operacion.multiplicacion;
primero = float.Parse (txtnum.Text);
txtnum.Text = "";
}

void ResClick(object sender, EventArgs e)
{
oper = Operacion.resta;
primero = float.Parse (txtnum.Text);
txtnum.Text = "";
}

void SumClick(object sender, EventArgs e)
{
oper = Operacion.suma;
primero = float.Parse (txtnum.Text);
txtnum.Text = "";
}

void SolClick(object sender, EventArgs e)
{
float segundo = int.Parse (txtnum.Text);
float resultado;

switch (oper)
{
case Operacion.suma:
resultado = primero + segundo;
txtnum.Text = resultado.ToString();
break;
case Operacion.resta:
resultado = primero - segundo;
txtnum.Text = resultado.ToString();
break;
case Operacion.multiplicacion:
resultado = primero * segundo;
txtnum.Text = resultado.ToString();
break;
case Operacion.division:
resultado = primero / segundo;
txtnum.Text = resultado.ToString();
break;
}
}
}
}

Ejemplo de Eventos y Delegados

La clase Empleado declara un evento "NombreCambiado" que se lanza cada vez que se cambia el atributo correspondiente al nombre del empleado. El evento tiene un manejador o delegado asociado (tipo del evento) "ActualizacionEventHandler" que declara una signatura para los métodos que pueden ser llamados para tratar el evento. En este caso, los métodos permitidos no devuelven nada (void) y deben tener un argumento de tipo string donde se pasará un mensaje a visualizar. En el método Main(), con la instrucción
MiEmpleado.NombreCambiado +=
new EjemploDelegados.ActualizacionEventHandler(NotificarCambioNombre);
se le indica al delegado que cuando se produzca el evento NombreCambiado se invoque al método "NotificarCambioNombre", método que respeta la firma declarada por el propio manejador de eventos.


*****************************************************************************

Program.cs


using System;

namespace EjemploDelegados
{
class Program
{
public static void NotificarCambioNombre(string msg)
{
//imprimos mensaje aviso.
Console.WriteLine("¡El nombre del empleado a cambiado!");
Console.WriteLine(msg);
}

public static void Main(string[] args)
{
Empleado MiEmpleado = new Empleado("Ramiro");
MiEmpleado.NombreCambiado +=
new EjemploDelegados.ActualizacionEventHandler(NotificarCambioNombre);
Console.Write("Nombre empleado: ");
MiEmpleado.setNombre(Console.ReadLine());

Console.Write("Pulsa cualquier tecla para continuar . . . ");
Console.ReadKey(true);
}

}
}


Empleado.cs


using System;

namespace EjemploDelegados
{
public delegate void ActualizacionEventHandler(string msg);

public class Empleado
{
//atributo
private string Nombre;

//... resto de atributos..

//declaración del evento
public event ActualizacionEventHandler NombreCambiado;

public Empleado(String Nombre)
{
this.Nombre=Nombre;
}

public void setNombre(string s)
{
//actualizar el atributo
string anteriorNombre=this.Nombre;
this.Nombre = s;

//lanzar el evento
this.NombreCambiado("Era "+anteriorNombre+"
y ahora es "+this.Nombre);
}

}
}

domingo, 20 de marzo de 2011

Diseñador de Formularios Windows en Sharp Develop

En C# podemos crear con una cierta facilidad programas en entornos gráficos, con menús botones, listas desplegables, etc.

La forma más cómoda de conseguirlo es usando herramientas que incluyan un editor visual, como Visual Studio o SharpDevelop.

A pesar de que existen versiones gratuitas de Visual Studio, vamos a ver el caso de SharpDevelop, que necesita un ordenador menos potente y tiene un manejo muy similar.

Cuando entramos a SharpDevelop, diríamos que queremos crear una "nueva solución", y en el menú escogeríamos "Aplicación Windows":

Nos aparecerá un esqueleto de aplicación:

Debajo de la ventana de código hay una pestaña llamada "Diseño", que nos permite acceder al diseñador visual:

Para poder incluir botones y otros elementos visuales, debemos escoger la ventana de "Herramientas" en la parte inferior de la pantalla, y luego el panel "Windows Forms" en esta ventana:

Para incluir un botón, podemos hacer clic en el elemento "Button" del panel izquierdo, y luego hacer un clic en la parte de la ventana en la que queremos que aparezca. De igual modo, podríamos añadir otros elementos.

Por ejemplo, vamos a añadir un botón (Button) y una etiqueta de texto (Label), para hacer un primer programa que cambien el texto de la etiqueta cuando pulsemos el botón.

Las propiedades de cada uno de estos elementos aparecen en la parte derecha, en una nueva ventana. Estas propiedades las podremos cambiar directamente en ese panel, o bien desde código. Algunas de esas propiedades son:

  • Name, el nombre con el que se accederá desde el código.
  • Text, el texto que muestra un elemento.
  • ForeColor, el color con el que se muestra.
  • TextAlign, para indicar la alineación del texto (y poder centrarlo, por ejemplo).
  • Enabled, para poder activar o desactivar un elemento.
  • Location, la posición en que se encuentra (que podemos ajustar inicialmente con el ratón).
  • Size, el tamaño (ancho y alto, que también se puede ajustar inicialmente con el ratón).

Si queremos que al pulsar el botón cambie el texto, tendremos que modificar el código que corresponde al "evento" de pulsación del botón. Lo conseguimos simplemente haciendo doble clic en el botón, y aparece este texto:

void Button1Click(object sender, EventArgs e)
{

}

Dentro de ese método escribiremos lo que queremos que ocurra al hacer clic en el botón. Por ejemplo, para que el texto de la etiqueta "label1" pase a ser "Hola", haríamos:

void Button1Click(object sender, EventArgs e)
{
label1.Text = "Hola";
}

Ejercicios propuestos:

  • Un programa que muestre una ventana con 3 recuadros de texto (TextBox) y un botón "Calcular suma". Cuando se pulse el botón, en el tercer recuadro deberá aparecer la suma de los números introducidos en los dos primeros recuadros.
  • Un programa que muestre una ventana con un recuadro de texto y 3 etiquetas. En el recuadro de texto se escribirá un número decimal. Cada vez que en el recuadro de texto se pulse una tecla, se mostrará en las 3 etiquetas de texto el equivalente de ese número en binario, octal y hexadecimal. Pista: en la ventana de propiedades, se deberá escoger "Eventos", para ver las posibles acciones relacionadas con el TextBox.

lunes, 14 de marzo de 2011

Dudas alumnos. Cómo saber si dos referencias apuntan al mismo objeto.

A diferencia de otros lenguajes similares, como Java, en C# es posible comparar dos cadenas utilizando el operador de igualdad == sin miedo a que en vez de comparar el contenido al que apuntan las referencias esté comparando las referencias mismas. Es decir, que para la siguiente declaración de cadenas,

string str1 = "abc", str2="abc";

en la que se crean dos instancia diferentes de la misma cadena, la expresión str1.Equals(str2) y la expresión str1==str2 devolverían True en ambos casos. Si quisiéramos comprobar si se trata de dos instancias diferentes tendríamos que usar el método ReferenceEquals de la clase Object. Así, y para el caso anterior, System.Object.ReferenceEquals(str1, str2) devolvería False ya que cada referencia apunta a instancias distintas. Para hacer que dos referencias de cadenas apunten a la misma instancia hay que emplear la instrucción de asignación, sin más,

string str1="abc", str2;
str2 = str1;

Para este ejemplo, System.Object.ReferenceEquals(str1, str2) devolvería True. Otra forma equivalente de hacer que str2 tome la referencia del objeto referenciado por str1 sería utilizar el método ToString de la superclase Object:

string str1="abc", str2;
str2 = str1.ToString();


Teoría. Arreglos y enumeraciones en C#


Diapositivas. Herencia


Diapositivas. Creación y Destrucción de objetos


Diapositivas. Variables de tipo referencia


Diapositivas. Fundamentos de POO


Diapositivas. Tablas


Diapositivas. Métodos y parámetros


Diapositivas. Estructuras de control y excepciones


Diapositivas. Variables de tipo valor.


Teoría. Libro de C# didáctico


Puedes descargar el libro aquí

miércoles, 9 de marzo de 2011

Temario del curso

MCTS Windows.Net Framework 3.5 con C# .Net


Contenido del curso:

  1. Conceptos Fundamentales del Framework
  2. input/Output (Entrada/Salida)
  3. Buscar, Modificar y Codificar texto
  4. Colecciones y colecciones genéricas
  5. Serialización
  6. La clase Graphics
  7. La clase Threading
  8. Dominios de aplicación y servicios
  9. Instalación y confuguración de aplicaciones
  10. Logging y gestión de sistemas
  11. Seguridad de datos y de usuarios
  12. Interoperatibilidad con componentes COM
  13. La clase Reflection
  14. Mail
  15. Globalización