jueves, 31 de julio de 2014

El Libro del Día: Beginning Windows 8 Application Development

El Libro del Día: 2014-07-31

Titulo: Beginning Windows 8 Application Development
Autor: István Novák, György Balássy, Zoltán Arvai, Dávid Fülöp
Editorial: Wrox
Nro Paginas: 626

Capítulos:
Part I: INTRODUCTION TO WINDOWS 8 APPLICATION DEVELOPMENT
Chapter 1: A BRIEF HISTORY OF WINDOWS APPLICATION DEVELOPMENT
Chapter 2: USING WINDOWS 8
Chapter 3: WINDOWS 8 ARCHITECTURE FROM A DEVELOPER’S POINT OF VIEW
Chapter 4: GETTING TO KNOW YOUR DEVELOPMENT ENVIRONMENT
Part II: CREATING WINDOWS 8 APPLICATIONS
Chapter 5: PRINCIPLES OF MODERN WINDOWS APPLICATION DEVELOPMENT
Chapter 6: CREATING WINDOWS 8 STYLE APPLICATIONS WITH HTML5, CSS, AND JAVASCRIPT
Chapter 7: USING XAML TO CREATE WINDOWS 8 STYLE USER INTERFACES
Chapter 8: WORKING WITH XAML CONTROLS
Chapter 9: BUILDING WINDOWS 8 STYLE APPLICATIONS
Chapter 10: CREATING MULTI-PAGE APPLICATIONS
Chapter 11: BUILDING CONNECTED APPLICATIONS
Chapter 12: LEVERAGING TABLET FEATURES
Part III: ADVANCING TO PROFESSIONAL WINDOWS 8 DEVELOPMENT
Chapter 13: CREATING WINDOWS 8 STYLE APPLICATIONS WITH C++
Chapter 14: ADVANCED PROGRAMMING CONCEPTS
Chapter 15: TESTING AND DEBUGGING WINDOWS 8 APPLICATIONS
Chapter 16: INTRODUCING THE WINDOWS STORE
Part IV: APPENDICES
Appendix A: ANSWERS TO EXERCISES
Appendix B: USEFUL LINKS

Descarga:
Beginning_Windows8_Application_Development

miércoles, 30 de julio de 2014

El Demo del Día: Paginar y Ordenar en el Control Web Repeater

Paginar y Ordenar en el Control Web Repeater

Requerimiento

Se desea crear una Aplicación Web que permita listar los datos de los empleados que cumpla con lo siguiente:
- Presente en columnas la información del código, apellido, nombre, fecha de nacimiento y foto del empleado.
- La cabecera de la grilla debe estar combinada de tal forma que muestre un titulo que diga Nombre Completo que agrupe al Apellido y al nombre del empleado.
- Las filas de datos deben tener un estilo con fondo blanco y color de letra azul, pero al pasar el mouse el estilo de la fila debe tener fondo amarillo y color de letra rojo.
- Lo principal es que muestre solo unos cuantos registros (por ejemplo 4), de tal forma que ocupe menos de una pagina.
- También debe permitir ordenar la información ascendente o descendente por cualquiera de las columnas creadas, mostrando un símbolo de ordenación en el ultimo campo ordenado.

Solución

Usaremos el Control Web Repeater y crearemos 2 tipos de paginación: con botones (primero, anterior, siguiente y último) y con Enlaces (Links con los números de paginas, al estilo GridView). Además usando plantillas agregaremos controles LinkButton para cada columna de tal forma que permita ordenar y mostraremos el símbolo de ordenación del último campo ordenado.

Nota: Para este caso, No podremos deshabilitar el ViewState debido ha que el Repeater tendrá LinkButtons que ejecutan código en el servidor y se perderían si deshabilitamos el ViewState. Pero como el control está paginado, no es mucho HTML el que se guarda en el cliente.

Crear el Procedimiento Almacenado en la Base de Datos de SQL Server

Usaremos la tabla Empleados (Employees) de Northwind:

Create Procedure [dbo].[uspEmployeesListar]
As
Select EmployeeID,LastName,FirstName,
IsNull(BirthDate,'1/1/1900') As BirthDate
From Employees Order By 1

Crear una Librería de Clases con las Entidades del Negocio

Crear un proyecto de tipo Librería de Clases en C# llamado: "Northwind.Librerias.EntidadesNegocio" y modificar el código de la clase como sigue:

using System;
namespace Northwind.Librerias.EntidadesNegocio
{
    public class beEmpleado
    {
        public int IdEmpleado { get; set; }
        public string Apellido { get; set; }
        public string Nombre { get; set; }
        public string NombreCompleto
        {
            get
            {
                return (String.Format("{0} {1}",Nombre,Apellido));
            }
        }
        public DateTime FechaNacimiento { get; set; }
    }
}

Crear una Librería de Acceso a Datos

Crear un proyecto de tipo Librería de Clases en C# llamado: "Northwind.Librerias.AccesoDatos" y modificar el código de la clase como sigue:

using System;
using System.Data; //CommandType
using System.Data.SqlClient; //SqlConnection, SqlCommand, SqlDataReader
using System.Collections.Generic; //List
using Northwind.Librerias.EntidadesNegocio; //beEmpleado
namespace Northwind.Librerias.AccesoDatos
{
    public class daEmpleado
    {
        public List<beEmpleado> listar(SqlConnection con)
        {
            List<beEmpleado> lbeEmpleado = null;
            SqlCommand cmd = new SqlCommand("uspEmployeesListar", con);
            cmd.CommandType = CommandType.StoredProcedure;
            SqlDataReader drd = cmd.ExecuteReader(CommandBehavior.SingleResult);
            if (drd != null)
            {
                lbeEmpleado = new List<beEmpleado>();
                int posIdEmpleado = drd.GetOrdinal("EmployeeID");
                int posApellido = drd.GetOrdinal("LastName");
                int posNombre = drd.GetOrdinal("FirstName");
                int posFechaNacimiento = drd.GetOrdinal("BirthDate");
                beEmpleado obeEmpleado;
                while (drd.Read())
                {
                    obeEmpleado = new beEmpleado();
                    obeEmpleado.IdEmpleado = drd.GetInt32(posIdEmpleado);
                    obeEmpleado.Apellido = drd.GetString(posApellido);
                    obeEmpleado.Nombre = drd.GetString(posNombre);
                    obeEmpleado.FechaNacimiento = drd.GetDateTime(posFechaNacimiento);
                    lbeEmpleado.Add(obeEmpleado);
                }
                drd.Close();
            }
            return (lbeEmpleado);
        }
    }
}

Nota: Hay que hacer una referencia a la Librería de Entidades del Negocio.

Crear una Librería de Reglas del Negocio

Crear un proyecto de tipo Librería de Clases en C# llamado: "Northwind.Librerias.ReglasNegocio" y modificar el código de la clase como sigue:

using System;
using System.Configuration; //ConfigurationManager
namespace Northwind.Librerias.ReglasNegocio
{
    public class brGeneral
    {
        //Propiedad
        public string Conexion { get; set; }

        //Constructor
        public brGeneral()
        {
            Conexion = ConfigurationManager.ConnectionStrings["conNW"].ConnectionString;
        }
    }
}

Nota: Hay que hacer una referencia a la Librería de Entidades del Negocio, a la Librería de Acceso a Datos y a System.Configuration.

Agregar otra clase llamada: "brEmpleado" y escribir el siguiente código:

using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using Northwind.Librerias.EntidadesNegocio;
using Northwind.Librerias.AccesoDatos;

namespace Northwind.Librerias.ReglasNegocio
{
    public class brEmpleado:brGeneral //Herencia
    {
        public List<beEmpleado> listar()
        {
            List<beEmpleado> lbeEmpleado = null;
            using (SqlConnection con = new SqlConnection(Conexion))
            {
                try
                {
                    con.Open();
                    daEmpleado odaEmpleado = new daEmpleado();
                    lbeEmpleado = odaEmpleado.listar(con);
                }
                catch (SqlException ex)
                {
                    //Capturar el error y grabar un Log
                }
            } //con.Close(); con.Dispose(); con = null;
            return (lbeEmpleado);
        }
    }
}

Nota: La clase "brEmpleado" hereda de la clase "brGeneral" la cadena de conexión para no pasarla como parámetro en cada método de la clase o en el constructor de cada clase se hace una sola vez.

Crear una Librería de Código de Usuario para Web

Crear un proyecto de tipo Librería de Clases en C# llamado: "General.Librerias.CodigoUsuarioWeb" y modificar el código de la clase como sigue:

using System;
using System.Collections.Generic;
using System.IO; //File
using System.Web; //HttpContext

namespace General.Librerias.CodigoUsuarioWeb
{
    public class Imagen
    {
        public static string obtenerUrl(int id, string carpeta)
        {
            string archivo = HttpContext.Current.Server.MapPath
            (String.Format("../Imagenes/{0}/{1}.jpg", carpeta, id));
            string url = String.Format("../Imagenes/{0}/{1}.jpg", carpeta, id);
            if (!File.Exists(archivo)) url = String.Format("../Imagenes/{0}/No.jpg", carpeta);
            return (url);
        }
    }
}

Nota: Como esta librería va a ser usada por paginas web hay que hacer referencia a: "System.Web"

Crear la Aplicación Web en ASP .NET Web Form

Crear un "Nuevo Sitio web vacío de ASP .NET" en C# llamado "Demo13" y crear las siguientes carpetas:
- Estilos: Para el archivo de hoja de estilo (CSS).
- Imagenes. Dentro crear otra carpeta llamada "Empleados" y adjuntar los archivos con las fotos de los empleados: 1.jpg, 2.jpg, 3.jpg, ... y No.jpg.
- Paginas: Para contener la pagina de lista de empleados.

Crear el Archivo de Hoja de Estilo (CSS)

Seleccionar la carpeta "Estilos" y agregar un archivo de hoja de estilos con el nombre de: "ACME.css" y modificar el código como sigue:

body {
    background-color:aqua;
}
.Titulo {
    background-color:black;
    color:white;
    text-transform:uppercase;
    font-size:xx-large;
    font-weight:bold;
}
.Subtitulo {
    background-color:white;
    color:blue;
    text-transform:capitalize;
    font-size:x-large;
    font-weight:bold;
}
.MarcarFila tr {
    background-color: white;
    color: blue;
    cursor:default;
    font-weight:normal;
}
.MarcarFila tr:hover {
    background-color: yellow;
    color: red;
    cursor:pointer;
    font-weight:bold;
}

Crear la Pagina ASP .NET como un Formulario Web Form

Seleccionar la carpeta "Paginas" y agregar un Formulario Web Form llamado: "ListaEmpleados.aspx", para empezar a diseñar la pagina hay que hacer referencia a las Librerías de Negocio (que copia todas sus dependencias) y la Librería de Código de Usuario Web.

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ListaEmpleados.aspx.cs" Inherits="Paginas_ListaEmpleados" %>
<%@ Import Namespace="Northwind.Librerias.EntidadesNegocio" %>
<%@ Import Namespace="General.Librerias.CodigoUsuarioWeb" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <link href="../Estilos/ACME.css" rel="stylesheet" type="text/css" />
    <style type="text/css">
        .auto-style1 {
            width: 100%;
        }
    </style>
</head>
<body class="Cuadro">
    <form id="form1" runat="server">
    <div>
        <table class="auto-style1">
            <tr>
                <td class="Titulo">Paginar y Ordenar en el Control Repeater</td>
            </tr>
            <tr>
                <td class="Subtitulo">Lista de Empleados</td>
            </tr>
            <tr>
                <td>
                    <asp:Repeater ID="rpEmpleado" runat="server">
                        <HeaderTemplate>
                            <table class="MarcarFila">
                                <tr style="text-align:center;background-color:lightgray;color:black">
                                    <td rowspan="2" style="width:100px">
                                        <%#obtenerSimbolo("IdEmpleado")%>
                                        <asp:LinkButton ID="lbnCodigo" Text="Código"
                                          OnClick="ordenarCampo"
                                          CommandArgument="IdEmpleado" runat="server" />
                                    </td>
                                    <td colspan="2" style="width:300px">Nombre Completo</td>
                                    <td rowspan="2" style="width:100px">
                                        <%#obtenerSimbolo("FechaNacimiento")%>
                                        <asp:LinkButton ID="lbnFechaNac" Text="Fecha Nac"
                                          OnClick="ordenarCampo"
                                          CommandArgument="FechaNacimiento" runat="server" />
                                    </td>
                                    <td rowspan="2" style="width:150px">Foto</td>
                                </tr>
                                <tr style="text-align:center;background-color:lightgray;color:black">
                                    <td style="width:150px">
                                        <%#obtenerSimbolo("Apellido")%>
                                        <asp:LinkButton ID="lbnApellido" Text="Apellido"
                                          OnClick="ordenarCampo"
                                          CommandArgument="Apellido" runat="server" />
                                    </td>
                                    <td style="width:150px">
                                        <%#obtenerSimbolo("Nombre")%>
                                        <asp:LinkButton ID="lbnNombre" Text="Nombre"
                                          OnClick="ordenarCampo"
                                          CommandArgument="Nombre"  runat="server" />
                                    </td>
                                </tr>
                        </HeaderTemplate>
                        <ItemTemplate>
                            <tr>
                                <td>
                                    <%#((beEmpleado)Container.DataItem).IdEmpleado%>
                                </td>
                                <td>
                                    <%#((beEmpleado)Container.DataItem).Apellido%>
                                </td>
                                <td>
                                    <%#((beEmpleado)Container.DataItem).Nombre%>
                                </td>
                                <td>
                                    <%#((beEmpleado)Container.DataItem).FechaNacimiento.
                                            ToShortDateString()%>
                                </td>
                                <td>
                                    <img src='<%#Imagen.obtenerUrl(((beEmpleado)Container.DataItem).
                                      IdEmpleado,"Empleados")%>' width="120" height="80" alt="Foto"
                                      title="<%#((beEmpleado)Container.DataItem).NombreCompleto%>"/>
                                </td>
                            </tr>
                        </ItemTemplate>
                        <FooterTemplate>
                            </table>
                        </FooterTemplate>
                    </asp:Repeater>
                </td>
            </tr>
            <tr>
                <td style="text-align:center">
                    <asp:Button ID="btnPrimero" Text="<<" Width="50"
                      runat="server" OnClick="btnPrimero_Click" />
                    <asp:Button ID="btnAnterior" Text="<" Width="50"
                      runat="server" OnClick="btnAnterior_Click" />
                    <asp:TextBox ID="txtPosicion" Width="100" ReadOnly="true" runat="server" />
                    <asp:Button ID="btnSiguiente" Text=">" Width="50"
                      runat="server" OnClick="btnSiguiente_Click" />
                    <asp:Button ID="btnUltimo" Text=">>" Width="50"
                      runat="server" OnClick="btnUltimo_Click" />
                </td>
            </tr>
            <tr>
                <td id="celdaPaginas" style="text-align:center" runat="server">
                </td>
            </tr>
        </table>
    </div>
    </form>
</body>
</html>

El diseño de la pagina se mostrará como en la siguiente figura:


Escribir el siguiente código C# en la página:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Northwind.Librerias.EntidadesNegocio; //beEmpleado
using Northwind.Librerias.ReglasNegocio; //brEmpleado

public partial class Paginas_ListaEmpleados : System.Web.UI.Page
{
    private List<beEmpleado> lbeEmpleado;
    private string simbolo;
    private int registrosPagina = 4;
    private int indicePaginaActual;
    private int indiceUltimaPagina;

    protected void Page_Load(object sender, EventArgs e)
    {
        txtPosicion.Attributes.Add("style", "text-align:center");
        if (!Page.IsPostBack)
        {
            brEmpleado obrEmpleado = new brEmpleado();
            lbeEmpleado = obrEmpleado.listar();
            indiceUltimaPagina = (lbeEmpleado.Count / registrosPagina);
            if (lbeEmpleado.Count % registrosPagina == 0) indiceUltimaPagina--;
            ViewState["indicePaginaActual"] = indicePaginaActual;
            ViewState["indiceUltimaPagina"] = indiceUltimaPagina;
            Session["Empleados"] = lbeEmpleado;
            ViewState["campo"] = "";
            enlazarRepeater();
        }
        else
        {
            indiceUltimaPagina = (int)ViewState["indiceUltimaPagina"];
        }
        crearEnlacesPaginas();
    }

    private void crearEnlacesPaginas()
    {
        LinkButton lbn;
        for (int i = 0; i <= indiceUltimaPagina; i++)
        {
            lbn = new LinkButton();
            lbn.Text = (i + 1).ToString();
            lbn.Click += new EventHandler(paginar);
            celdaPaginas.Controls.Add(lbn);
            celdaPaginas.Controls.Add(new LiteralControl("  "));
        }
    }

    private void paginar(object sender, EventArgs e)
    {
        LinkButton lbn = (LinkButton)sender;
        indicePaginaActual = int.Parse(lbn.Text) - 1;
        ViewState["indicePaginaActual"] = indicePaginaActual;
        enlazarRepeater();
    }

    private void enlazarRepeater()
    {
        lbeEmpleado = (List<beEmpleado>)Session["Empleados"];
        List<beEmpleado> lbeFiltro = new List<beEmpleado>();
        int inicio = indicePaginaActual * registrosPagina;
        int fin = (indicePaginaActual * registrosPagina)+registrosPagina;
        for (int i = inicio; i < fin; i++)
        {
            if (i < lbeEmpleado.Count) lbeFiltro.Add(lbeEmpleado[i]);
            else break;
        }
        rpEmpleado.DataSource = lbeFiltro;
        rpEmpleado.DataBind();

        indicePaginaActual = (int)ViewState["indicePaginaActual"];
        indiceUltimaPagina = (int)ViewState["indiceUltimaPagina"];
        txtPosicion.Text = String.Format("{0} de {1}", indicePaginaActual + 1, indiceUltimaPagina + 1);
    }

    protected void ordenarCampo(object sender, EventArgs e)
    {
        LinkButton lbn = (LinkButton)sender;
        string campo = lbn.CommandArgument;
        ViewState["campo"] = campo;
        if (ViewState["simbolo"] == null) simbolo = "▲";
        else
        {
            if (ViewState["simbolo"].Equals("▲")) simbolo = "▼";
            else simbolo = "▲";
        }
        ViewState["simbolo"] = simbolo;
        lbeEmpleado = (List<beEmpleado>)Session["Empleados"];
        if(simbolo.Equals("▲")) lbeEmpleado = lbeEmpleado.OrderBy
            (x => x.GetType().GetProperty(campo).GetValue(x, null)).ToList<beEmpleado>();
        else lbeEmpleado = lbeEmpleado.OrderByDescending
            (x => x.GetType().GetProperty(campo).GetValue(x, null)).ToList<beEmpleado>();
        Session["Empleados"] = lbeEmpleado;
        enlazarRepeater();
    }

    protected string obtenerSimbolo(string campo)
    {
        if (ViewState["campo"].Equals(campo)) return (simbolo);
        else return ("");
    }

    protected void btnPrimero_Click(object sender, EventArgs e)
    {
        indicePaginaActual = 0;
        ViewState["indicePaginaActual"] = indicePaginaActual;
        enlazarRepeater();
    }

    protected void btnAnterior_Click(object sender, EventArgs e)
    {
        indicePaginaActual=(int)ViewState["indicePaginaActual"];
        if (indicePaginaActual > 0)
        {
            indicePaginaActual--;
            ViewState["indicePaginaActual"] = indicePaginaActual;
            enlazarRepeater();
        }
    }

    protected void btnSiguiente_Click(object sender, EventArgs e)
    {
        indicePaginaActual = (int)ViewState["indicePaginaActual"];
        indiceUltimaPagina = (int)ViewState["indiceUltimaPagina"];
        if (indicePaginaActual < indiceUltimaPagina)
        {
            indicePaginaActual++;
            ViewState["indicePaginaActual"] = indicePaginaActual;
            enlazarRepeater();
        }
    }

    protected void btnUltimo_Click(object sender, EventArgs e)
    {
        indiceUltimaPagina = (int)ViewState["indiceUltimaPagina"];
        indicePaginaActual = indiceUltimaPagina;
        ViewState["indicePaginaActual"] = indicePaginaActual;
        enlazarRepeater();
    }
}

Nota: Por defecto los registrosPorPagina está configurado a 4, pero se puede cambiar para probar, además el símbolo de ordenación ascendente es el caracter ASCII 30 y el descendente 31.

Modificar el Archivo Web.Config para especificar la cadena de conexión a Northwind

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <connectionStrings>
    <add name="conNW" providerName="SQLServer" connectionString="uid=UsuarioNW;pwd=123456;
      data source=DSOFT\Sqlexpress; database=Northwind"/>
  </connectionStrings>
    <system.web>
      <compilation debug="true" targetFramework="4.5" />
      <httpRuntime targetFramework="4.5" />
    </system.web>
</configuration>

Probar la Pagina Web

Guardar el Sitio Web, clic derecho a la Pagina "ListaEmpleados.aspx" y seleccionar "Ver en el explorador".


Probar ir a cualquier pagina usando los Links con los números de paginas o con los botones, por ejemplo si estamos en la ultima ya no podemos avanzar a la siguiente o si estamos en la primera ya no podemos retroceder.

También ordenar los registros usando los Links de las cabeceras y ver el símbolo de ordenación que aparece, ya sea ascendente o descendente.

Comentario Final

En esta demostración hemos visto como podemos paginar sobre el control Repeater y como ordenar los registros mostrando el símbolo de ordenación. En el siguiente post, veremos como hacerlo en el control DataList.

Descarga:
Demo13_Paginar_Ordenar_Repeater

El Libro del Día: Beginning HTML5 & CSS3 For Dummies

El Libro del Día: 2014-07-30

Titulo: Beginning HTML5 & CSS3 For Dummies
Autor: Ed Tittel, Chris Minnick
Editorial: Wiley
Nro Paginas: 387

Capítulos:
Part I: Getting Started with HTML and CSS on the Web
Chapter 1: An Overview of HTML and CSS on the Web
Chapter 2: Meeting the Structure and Components of HTML
Part II: Getting the Structure and Text Right
Chapter 4: HTML Documents Need Good Structure
Chapter 5: Text and Lists
Chapter 6: Tip-Top Tables in HTML
Chapter 7: Working with Forms in HTML
Part III: Adding Links, Images, and Other Media
Chapter 8: Getting Hyper with Links in HTML
Chapter 9: Working with Images in HTML
Chapter 10: Managing Media and More in HTML
Part IV: Adopting CSS Style
Chapter 11: Advantages of Style Sheets
Chapter 12: CSS Structure and Syntax
Chapter 13: Using Different Kinds of Style Sheets
Part V: Enhancing Your Pages’ Look and Feel
Chapter 14: Managing Layout and Positioning
Chapter 15: Building with Boxes, Borders, and Buttons
Chapter 16: Using Colors and Backgrounds
Chapter 17: Web Typography
Chapter 18: CSS Text and Shadow Effects
Chapter 19: Multimedia and Animation with CSS
Part VI: The Part of Tens
Chapter 20: Ten Keys to Mobile Web Design
Chapter 21: Ten HTML Do’s and Don’ts
Chapter 22: Ten Ways to Kill Web Bugs Dead
Chapter 23: Ten Cool HTML Tools and Technologies
Part VII: Appendixes
Appendix A: Twitterati
Appendix B: About the Dummies HTML Site

Descarga:
Beginning_HTML5_CSS3_ForDummies

martes, 29 de julio de 2014

El Libro del Día: HTML5 Canvas For Dummies

El Libro del Día: 2014-07-29

Titulo: HTML5 Canvas For Dummies
Autor: Don Cowan
Editorial: Wiley
Nro Paginas: 387

Capítulos:
Part I: Looking at Canvas
Chapter 1: A Quick Glimpse Behind the Canvas
Chapter 2: Setting Up Your Canvas Platform
Part II: Drawing on Canvas
Chapter 3: Creating Objects
Chapter 4: Enhancing Objects
Chapter 5: Transforming Objects
Chapter 6: Moving Objects
Part III: Breathing Life into Your Canvas
Chapter 7: Mastering the Art of Canvas
Chapter 8: Introducing User Interaction
Chapter 9: Creating Engaging Imagery and Motion
Chapter 10: Sounding Off with Audio
Part IV: Developing More Complex Applications
Chapter 11: Grabbing Attention with Video
Chapter 12: Enhancing Canvas Applications
Part V: The Part of Tens
Chapter 13: Ten Great Canvas Applications
Chapter 14: Ten Great Tools

Descarga:
HTML5_Canvas_ForDummies

lunes, 28 de julio de 2014

El Libro del Día: Pro Windows Phone App Development

El Libro del Día: 2014-07-28

Titulo: Pro Windows Phone App Development
Autor: Falafel Software
Editorial: Apress
Nro Paginas: 551

Capítulos:
Chapter 1: Introduction
Chapter 2: Getting Started
Chapter 3: Building the UI with XAML
Chapter 4: Phone Controls
Chapter 5: Navigation
Chapter 6: Application Lifecycle
Chapter 7: Gestures
Chapter 8: Device Capabilities
Chapter 9: Mapping
Chapter 10: Live Tiles and Notifications
Chapter 11: Data Sources
Chapter 12: Using Data in the Cloud
Chapter 13: Designing In Blend
Chapter 14: Taking Your App to Market

Descarga:
Pro_WindowsPhone_AppDevelopment

domingo, 27 de julio de 2014

El Libro del Día: HTML5 in Action

El Libro del Día: 2014-07-27

Titulo: HTML5 in Action
Autor: Rob Crowther, Joe Lennon, Ash Blue, Greg Wanish
Editorial: Manning
Nro Paginas: 466

Capítulos:
PART 1 INTRODUCTION
1 HTML5: from documents to applications
PART 2 BROWSER-BASED APPS
2 Form creation: input widgets, data binding, and data validation
3 File editing and management: rich formatting, file storage, drag and drop
4 Messaging: communicating to and from scripts in HTML5
5 Mobile applications: client storage and offline execution
PART 3 INTERACTIVE GRAPHICS, MEDIA, AND GAMING
6 2D Canvas: low-level, 2D graphics rendering
7 SVG: responsive in-browser graphics
8 Video and audio: playing media in the browser
9 WebGL: 3D application development

Descarga:
HTML5_InAction

sábado, 26 de julio de 2014

El Demo del Día: Plantilla de Datos en el Control Web DataList

Requerimientos

Se desea crear una Aplicación Web que permita listar los datos de los empleados que cumpla con lo siguiente:
- Presente en forma de ficha la información del código, apellido, nombre y fecha de nacimiento del empleado.
- Muestre en la ficha la foto del empleado la cual se encuentra en un carpeta "Empleados" donde el nombre del archivo esta compuesto por el código del empleado y la extensión jpg. Para los archivos que no se encuentren se usará el archivo No.jpg.
- La información debe aparecer solo en una pagina en forma de cuadro con borde distribuida en columnas.
- Las fichas deben tener fondo gris claro, pero al pasar el mouse el estilo de la ficha cambiara a fondo amarillo.

Nota: El principal requerimiento es que la pagina sea rápida y que arroje la menor cantidad de HTML en el cliente. Además el Usuario No quiere Paginado ya que no son demasiados los registros a mostrar.

Solución

Usaremos el control DataList y le quitaremos el ViewState (EnableViewState=false) para reducir el HTML arrojado al cliente y para mejorar la apariencia de la pagina usaremos estilos para las fichas de datos.
Ademas usando Plantilla de Datos en el Control DataList podemos presentar en forma de ficha la información del empleado y mostrarla en varias columnas.

Crear el Procedimiento Almacenado en la Base de Datos de SQL Server

Usaremos la tabla Empleados (Employees) de Northwind:

Create Procedure [dbo].[uspEmployeesListar]
As
Select EmployeeID,LastName,FirstName,
IsNull(BirthDate,'1/1/1900') As BirthDate
From Employees Order By 1

Crear una Librería de Clases con las Entidades del Negocio

Crear un proyecto de tipo Librería de Clases en C# llamado: "Northwind.Librerias.EntidadesNegocio" y modificar el código de la clase como sigue:

using System;
namespace Northwind.Librerias.EntidadesNegocio
{
    public class beEmpleado
    {
        public int IdEmpleado { get; set; }
        public string Apellido { get; set; }
        public string Nombre { get; set; }
        public string NombreCompleto
        {
            get
            {
                return (String.Format("{0} {1}",Nombre,Apellido));
            }
        }
        public DateTime FechaNacimiento { get; set; }
    }
}

Crear una Librería de Acceso a Datos

Crear un proyecto de tipo Librería de Clases en C# llamado: "Northwind.Librerias.AccesoDatos" y modificar el código de la clase como sigue:

using System;
using System.Data; //CommandType
using System.Data.SqlClient; //SqlConnection, SqlCommand, SqlDataReader
using System.Collections.Generic; //List
using Northwind.Librerias.EntidadesNegocio; //beEmpleado
namespace Northwind.Librerias.AccesoDatos
{
    public class daEmpleado
    {
        public List<beEmpleado> listar(SqlConnection con)
        {
            List<beEmpleado> lbeEmpleado = null;
            SqlCommand cmd = new SqlCommand("uspEmployeesListar", con);
            cmd.CommandType = CommandType.StoredProcedure;
            SqlDataReader drd = cmd.ExecuteReader(CommandBehavior.SingleResult);
            if (drd != null)
            {
                lbeEmpleado = new List<beEmpleado>();
                int posIdEmpleado = drd.GetOrdinal("EmployeeID");
                int posApellido = drd.GetOrdinal("LastName");
                int posNombre = drd.GetOrdinal("FirstName");
                int posFechaNacimiento = drd.GetOrdinal("BirthDate");
                beEmpleado obeEmpleado;
                while (drd.Read())
                {
                    obeEmpleado = new beEmpleado();
                    obeEmpleado.IdEmpleado = drd.GetInt32(posIdEmpleado);
                    obeEmpleado.Apellido = drd.GetString(posApellido);
                    obeEmpleado.Nombre = drd.GetString(posNombre);
                    obeEmpleado.FechaNacimiento = drd.GetDateTime(posFechaNacimiento);
                    lbeEmpleado.Add(obeEmpleado);
                }
                drd.Close();
            }
            return (lbeEmpleado);
        }
    }
}

Nota: Hay que hacer una referencia a la Librería de Entidades del Negocio.

Crear una Librería de Reglas del Negocio

Crear un proyecto de tipo Librería de Clases en C# llamado: "Northwind.Librerias.ReglasNegocio" y modificar el código de la clase como sigue:

using System;
using System.Configuration; //ConfigurationManager
namespace Northwind.Librerias.ReglasNegocio
{
    public class brGeneral
    {
        //Propiedad
        public string Conexion { get; set; }

        //Constructor
        public brGeneral()
        {
            Conexion = ConfigurationManager.ConnectionStrings["conNW"].ConnectionString;
        }
    }
}

Nota: Hay que hacer una referencia a la Librería de Entidades del Negocio, a la Librería de Acceso a Datos y a System.Configuration.

Agregar otra clase llamada: "brEmpleado" y escribir el siguiente código:

using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using Northwind.Librerias.EntidadesNegocio;
using Northwind.Librerias.AccesoDatos;

namespace Northwind.Librerias.ReglasNegocio
{
    public class brEmpleado:brGeneral //Herencia
    {
        public List<beEmpleado> listar()
        {
            List<beEmpleado> lbeEmpleado = null;
            using (SqlConnection con = new SqlConnection(Conexion))
            {
                try
                {
                    con.Open();
                    daEmpleado odaEmpleado = new daEmpleado();
                    lbeEmpleado = odaEmpleado.listar(con);
                }
                catch (SqlException ex)
                {
                    //Capturar el error y grabar un Log
                }
            } //con.Close(); con.Dispose(); con = null;
            return (lbeEmpleado);
        }
    }
}

Nota: La clase "brEmpleado" hereda de la clase "brGeneral" la cadena de conexión para no pasarla como parámetro en cada método de la clase o en el constructor de cada clase se hace una sola vez.

Crear una Librería de Código de Usuario para Web

Crear un proyecto de tipo Librería de Clases en C# llamado: "General.Librerias.CodigoUsuarioWeb" y modificar el código de la clase como sigue:

using System;
using System.Collections.Generic;
using System.IO; //File
using System.Web; //HttpContext

namespace General.Librerias.CodigoUsuarioWeb
{
    public class Imagen
    {
        public static string obtenerUrl(int id, string carpeta)
        {
            string archivo = HttpContext.Current.Server.MapPath
            (String.Format("../Imagenes/{0}/{1}.jpg", carpeta, id));
            string url = String.Format("../Imagenes/{0}/{1}.jpg", carpeta, id);
            if (!File.Exists(archivo)) url = String.Format("../Imagenes/{0}/No.jpg", carpeta);
            return (url);
        }
    }
}

Nota: Como esta librería va a ser usada por paginas web hay que hacer referencia a: "System.Web"

Crear la Aplicación Web en ASP .NET Web Form

Crear un "Nuevo Sitio web vacío de ASP .NET" en C# llamado "Demo12" y crear las siguientes carpetas:
- Estilos: Para el archivo de hoja de estilo (CSS).
- Imagenes. Dentro crear otra carpeta llamada "Empleados" y adjuntar los archivos con las fotos de los empleados: 1.jpg, 2.jpg, 3.jpg, ... y No.jpg.
- Paginas: Para contener la pagina de lista de empleados.

Crear el Archivo de Hoja de Estilo (CSS)

Seleccionar la carpeta "Estilos" y agregar un archivo de hoja de estilos con el nombre de: "ACME.css" y modificar el código como sigue:

.Cuadro {
    position:absolute;
    left:2%;
    top:4%;
    width:96%;
    height:92%;
    background-color: gray;
    border:solid;
    border-color:black;
    border-radius:10px;
    overflow:scroll;
}
.Titulo {
    background-color:black;
    color:white;
    text-transform:uppercase;
    font-size:xx-large;
    font-weight:bold;
}
.Subtitulo {
    background-color:white;
    color:blue;
    text-transform:capitalize;
    font-size:x-large;
    font-weight:bold;
}
.MarcarTabla {
    background-color: lightgray;
    cursor:default;
    border:solid;
    border-color:lightgray;
}
.MarcarTabla:hover {
    background-color: yellow;
    cursor:pointer;
    border:solid;
    border-color:black;
}

Nota: El estilo "Cuadro" será aplicado al div principal de la pagina y el estilo "MarcarTabla" será aplicado a la tabla que muestra la ficha de cada empleado dentro del DataList.

Crear la Pagina ASP .NET como un Formulario Web Form

Seleccionar la carpeta "Paginas" y agregar un Formulario Web Form llamado: "ListaEmpleados.aspx", para empezar a diseñar la pagina hay que hacer referencia a las Librerías de Negocio (que copia todas sus dependencias) y la Librería de Código de Usuario Web.

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ListaEmpleados.aspx.cs" Inherits="Paginas_ListaEmpleados" %>
<%@ Import Namespace="Northwind.Librerias.EntidadesNegocio" %>
<%@ Import Namespace="General.Librerias.CodigoUsuarioWeb" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <link href="../Estilos/ACME.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <form id="form1" runat="server">
    <div class="Cuadro">
        <table style="width: 100%">
            <tr>
                <td class="Titulo">Plantilla y Estilos en el Control DataList</td>
            </tr>
            <tr>
                <td class="Subtitulo">Lista de Empleados</td>
            </tr>
            <tr>
                <td>
                    <asp:DataList ID="dlsEmpleado" runat="server" EnableViewState="False" 
                        RepeatColumns="3" CellPadding="20" CellSpacing="20"
                        RepeatDirection="Horizontal">
                        <ItemTemplate>
                            <table class="MarcarTabla">
                                <tr>
                                    <td>
                                        <table>
                                            <tr>
                                                <td style="width:80px">Código :</td>
                                                <td style="width:100px">
                                                    <%#((beEmpleado)Container.DataItem).IdEmpleado%>
                                                </td>
                                            </tr>
                                            <tr>
                                                <td style="width:80px">Apellido :</td>
                                                <td style="width:100px">
                                                    <%#((beEmpleado)Container.DataItem).Apellido%>
                                                </td>
                                            </tr>
                                            <tr>
                                                <td style="width:80px">Nombre :</td>
                                                <td style="width:100px">
                                                    <%#((beEmpleado)Container.DataItem).Nombre%>
                                                </td>
                                            </tr>
                                            <tr>
                                                <td style="width:80px">Fecha Nac :</td>
                                                <td style="width:100px">
                                                    <%#((beEmpleado)Container.DataItem).FechaNacimiento.
                                                           ToShortDateString()%>
                                                </td>
                                            </tr>
                                        </table>
                                    </td>
                                    <td>
                                        <img src='<%#Imagen.obtenerUrl(((beEmpleado)Container.DataItem).
                                           IdEmpleado,"Empleados")%>' width="120" height="80" alt="Foto" 
                                           title="<%#((beEmpleado)Container.DataItem).
                                           NombreCompleto%>"/>
                                    </td>
                                </tr>
                            </table>
                        </ItemTemplate>
                   </asp:DataList>
                </td>
            </tr>
        </table>
    </div>
    </form>
</body>
</html>

Nota: Se ha configurado las propiedad "RepeatColumns" del Control DataList para distribuir en 3 columnas los datos de los empleados, además la propiedad "RepeatDirection" está en Horizontal y No en Vertical para mostrar la dirección de los registros en filas y no en columnas, de izquierda a derecha y no de arriba hacia abajo. Finalmente, las propiedades CellPadding y CellSpacing permiten dar espaciado a los datos.

El diseño de la pagina se mostrará como en la siguiente figura:


Escribir el siguiente código C# en la página:

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Northwind.Librerias.EntidadesNegocio; //beEmpleado
using Northwind.Librerias.ReglasNegocio; //brEmpleado

public partial class Paginas_ListaEmpleados : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            brEmpleado obrEmpleado = new brEmpleado();
            List<beEmpleado> lbeEmpleado = obrEmpleado.listar();
            dlsEmpleado.DataSource = lbeEmpleado;
            dlsEmpleado.DataBind();
        }
    }
}

Modificar el Archivo Web.Config para especificar la cadena de conexión a Northwind

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <connectionStrings>
    <add name="conNW" providerName="SQLServer" connectionString="uid=UsuarioNW;pwd=123456;
      data source=DSOFT\Sqlexpress; database=Northwind"/>
  </connectionStrings>
    <system.web>
      <compilation debug="true" targetFramework="4.5" />
      <httpRuntime targetFramework="4.5" />
    </system.web>
</configuration>

Probar la Pagina Web

Guardar el Sitio Web, clic derecho a la Pagina "ListaEmpleados.aspx" y seleccionar "Ver en el explorador".


Observar que el contenido aparece sobre un cuadro con borde negro con esquinas redondeadas y los registros de empleados aparecen en pequeñas fichas distribuidas en 3 columnas. El cuadro tiene una barra de desplazamiento (scroll) para ver los demás registros.

Pasar el mouse por cada ficha de empleado y notar como cambia el estilo de la ficha seleccionada debido al estilo "MarcarTabla" aplicado a la tabla que esta dentro del control DataList.

Clic derecho a la página y seleccionar "Ver código fuente de la pagina", notar que el HTML generado desde el servidor es mínimo ya que se le quito el ViewState al control DataList y se uso Hojas de Estilo para reducir el formato en cada tabla.

Comentario Final

En esta demostración usamos el Control DataList para presentar la información en columnas y usando Estilos lo presentamos en una sola pagina en forma de cuadro con una barra de desplazamiento, esta técnica es útil si no son muchas páginas, de lo contrario es mejor Paginar para No enviar demasiado HTML al cliente, lo cual veremos en un siguiente post.

Descarga:

El Libro del Día: Programming Windows Store Apps with C#

El Libro del Día: 2014-07-26

Titulo: Programming Windows Store Apps with C#
Autor: Matt Baxter-Reynolds, Iris Classon
Editorial: O'Reilly
Nro Paginas: 508

Capítulos:
1. Making the Transition from .NET (Part 1)
2. Making the Transition from .NET (Part 2)
3. Local Persistent Data
4. The App Bar
5. Notifications
6. Working with Files
7. Sharing
8. Searching
9. Settings
10. Location
11. Using the Camera
12. Responsive Design
13. Resources and Localization
14. Background Tasks and App Lifetime
15. Sideloading and Distribution
A. Cryptography and Hashing
B. Unit Testing Basics for Windows Store Apps

Descarga:
Programming_WindowsStore_AppsC#

viernes, 25 de julio de 2014

El Libro del Día: Microsoft SharePoint 2013 Administration Inside Out

El Libro del Día: 2014-07-25

Titulo: Microsoft SharePoint 2013 Administration Inside Out
Autor: Randy Williams, CA Callahan, Chris Givens, John Milan Gross, 
          Brian Alderman, Javier Barrera
Editorial: Microsoft
Nro Paginas: 954

Capítulos:
Chapter 1: What’s new in SharePoint 2013
Chapter 2: Planning and preparing for SharePoint 2013 installation
Chapter 3: Upgrading to SharePoint 2013
Chapter 4: Installing SharePoint 2013
Chapter 5: Managing farms, web applications, and content databases
Chapter 6: Creating and managing service applications
Chapter 7: Creating and managing site collections
Chapter 8: Creating and configuring Search service applications
Chapter 9: Customizing search results and the Search Center site
Chapter 10: Configuring Metadata Management Services
Chapter 11: Configuring User Profile Services
Chapter 12: Understanding and configuring social capabilities
Chapter 13: Configuring Business Connectivity Services
Chapter 14: Configuring records management and eDiscovery
Chapter 15: Understanding and managing SharePoint 2013 apps
Chapter 16: Managing farm and sandboxed solutions
Chapter 17: Installing and configuring business intelligence components
Chapter 18: Monitoring and troubleshooting SharePoint 2013
Chapter 19: Understanding and configuring security
Chapter 20: Scaling and optimizing farms
Chapter 21: Installing and configuring Office Web Apps 2013
Chapter 22: Understanding SharePoint Online, Azure, and hybrid scenarios
Chapter 23: Performing content and disaster recovery

Descarga:
Microsoft_SharePoint2013_Administration_InsideOut

jueves, 24 de julio de 2014

El Libro del Día: Windows Phone 8 In Action

El Libro del Día: 2014-07-24

Titulo: Windows Phone 8 In Action
Autor: Timothy Binkley-Jones, Adam Benoit, Massimo Perga, Michael Sync
Editorial: Manning
Nro Paginas: 497

Capítulos:
PART 1 INTRODUCING WINDOWS PHONE
1 A new phone, a new operating system
2 Creating your first Windows Phone application
PART 2 CORE WINDOWS PHONE
3 Fast application switching and resume
4 Scheduled actions
5 Launching tasks and choosers
6 Contacts and calendars
7 Storing data
8 Working with the camera
9 Integrating with the Photos and Music + Videos Hubs
10 Using sensors
11 Network communication with push notifications
12 Using the Speech API
PART 3 XAML FOR WINDOWS PHONE
13 ApplicationBar and context menus
14 Panorama and pivot controls
15 Building a media player
16 Using Maps 369
17 Building HTML applications
18 Releasing and monetizing apps

Descarga:
WindowsPhone_8_InAction

miércoles, 23 de julio de 2014

El Libro del Día: Exam Ref 70-484

El Libro del Día: 2014-07-23

Titulo: Exam Ref 70-484 Essentials of Developing Windows Store Apps Using C#
Autor: Indrajit Chakrabarty
Editorial: Microsoft
Nro Paginas: 446

Capítulos:
Chapter 1 Design Windows Store apps
Chapter 2 Develop Windows Store apps
Chapter 3 Create the user interface
Chapter 4 Program the user interaction
Chapter 5 Manage security and data

Descarga:
ExamRef_70484_Essentials_Developing_WindowsStore_C#

martes, 22 de julio de 2014

El Libro del Día: Microsoft SQL Server 2012 Internals

El Libro del Día: 2014-07-22

Titulo: Microsoft SQL Server 2012 Internals
Autor: Kalen Delaney, Bob Beauchemin, Conor Cunningham, 
          Jonathan Kehayias, Benjamin Nevarez, Paul S. Randal
Editorial: Microsoft
Nro Paginas: 983

Capítulos:
Chapter 1 SQL Server 2012 architecture and configuration
Chapter 2 The SQLOS
Chapter 3 Databases and database files
Chapter 4 Special databases
Chapter 5 Logging and recovery
Chapter 6 Table storage
Chapter 7 Indexes: internals and management
Chapter 8 Special storage
Chapter 9 Special indexes
Chapter 10 Query execution
Chapter 11 The Query Optimizer
Chapter 12 Plan caching and recompilation
Chapter 13 Transactions and concurrency
Chapter 14 DBCC internals

Descarga:
Microsoft_SQL_Server_2012_Internals

lunes, 21 de julio de 2014

El Libro del Día: Start Here Build Windows 8 Apps with HTML5 and JavaScript

El Libro del Día: 2014-07-21

Titulo: Start Here Build Windows 8 Apps with HTML5 and JavaScript
Autor: Dino Esposito, Francesco Esposito
Editorial: Microsoft
Nro Paginas: 388

Capítulos:
Chapter 1 Using Visual Studio 2012 Express edition for Windows 8
Chapter 2 Making sense of HTML5
Chapter 3 Making sense of CSS
Chapter 4 Making sense of JavaScript
Chapter 5 First steps with Windows 8 development
Chapter 6 The user interface of Windows Store applications
Chapter 7 Navigating through multimedia content
Chapter 8 States of a Windows 8 application
Chapter 9 Integrating with the Windows 8 environment
Chapter 10 Adding persistent data to applications
Chapter 11 Working with remote data
Chapter 12 Accessing devices and sensors
Chapter 13 Adding Live tiles
Chapter 14 Publishing an application

Descarga:
StartHere_Build_Windows8_Apps_HTML5_JavaScript

sábado, 19 de julio de 2014

El Libro del Día: Essential SharePoint 2013

El Libro del Día: 2014-07-19

Titulo: Essential SharePoint 2013 (3rd Edition)
Autor: Scott Jamison, Susan Hanley, Chris Bortlik
Editorial: Addison Wesley
Nro Paginas: 778

Capítulos:
Chapter 1 Your Reading Journey
Part I Planning
Chapter 2 Planning Your Solution Strategy
Chapter 3 Introducing the SharePoint 2013 Platform
Chapter 4 Planning for Business Governance
Chapter 5 Planning for Operational Governance
Chapter 6 Planning Your Information Architecture
Chapter 7 Planning Your Adoption Strategy
Chapter 8 Developing a Value Measurement Strategy
Chapter 9 Understanding Architecture Fundamentals
Chapter 10 Planning Your Upgrade
Chapter 11 Taking SharePoint to the Cloud
Chapter 12 Planning Security
Part II Optimizing
Chapter 13 Managing Enterprise Content
Chapter 14 Managing Web Content
Chapter 15 Planning for Social Computing
Chapter 16 Planning Enterprise Search
Chapter 17 Planning Business Solutions
Chapter 18 Planning for Business Intelligence
Chapter 19 Planning for Mobility
Chapter 20 Integrating Office Applications
Appendix Content You Can Reuse

Descarga:
Essential_SharePoint_2013

viernes, 18 de julio de 2014

El Libro del Día: MCPD Exam Ref 70-518

El Libro del Día: 2014-07-18

Titulo: MCPD Exam Ref 70-518 Windows Application NET Framework 4
Autor: Tony Northrup, Matthew A. Stoecker
Editorial: Microsoft
Nro Paginas: 337

Capítulos:
Chapter 1 Designing the Layers of a Solution
Chapter 2 Designing the Presentation Layer
Chapter 3 Designing the Data Access Layer
Chapter 4 Planning a Solution Deployment
Chapter 5 Designing for Stability and Maintenance

Descarga:
MCPD_Exam70518_WindowsApplication_NetFramework4

jueves, 17 de julio de 2014

El Demo del Día: Plantilla de Datos (Data Template) en el Control Web Repeater

Plantilla de Datos (Data Template) en el Control Web Repeater

Este es el primer Demo que estoy publicando sobre ASP .NET y trataremos de como crear Plantillas de Datos (Data Template) usando el Control Web Repeater.

Requerimientos

Se desea crear una Aplicación Web que permita listar los datos de los empleados que cumpla con lo siguiente:
- Presente en columnas la información del código, apellido, nombre y fecha de nacimiento.
- Muestre una columna con la foto del empleado la cual se encuentra en un carpeta "Empleados" donde el nombre del archivo esta compuesto por el código del empleado y la extensión jpg. Para los archivos que no se encuentren se usará el archivo No.jpg.
- La cabecera de la grilla debe estar combinada de tal forma que muestre un titulo que diga Nombre Completo que agrupe al Apellido y al nombre del empleado.
- Las filas de datos deben tener un estilo con fondo blanco y color de letra azul, pero al pasar el mouse el estilo de la fila debe tener fondo amarillo y color de letra rojo.

Nota: El principal requerimiento es que la pagina sea rápida y que arroje la menor cantidad de HTML en el cliente.

Solución

Usaremos el control Repeater y le quitaremos el ViewState (EnableViewState=false) y usaremos estilos para las filas de datos con lo cual logramos disminuir el HTML arrojado al cliente (Browser).
Ademas usando Plantilla de Datos podemos dar la apariencia que deseemos a la consulta, en este caso para combinar celdas en la cabecera.

Nota: La mayoría de programadores de ASP .NET solo consideran como alternativa usar el GridView y programar en el evento RowDataBound la combinación de las celdas y otras funcionalidades.

Crear el Procedimiento Almacenado en la Base de Datos de SQL Server

Usaremos la tabla Empleados (Employees) de Northwind:

Create Procedure [dbo].[uspEmployeesListar]
As
Select EmployeeID,LastName,FirstName,
IsNull(BirthDate,'1/1/1900') As BirthDate
From Employees Order By 1

Crear una Librería de Clases con las Entidades del Negocio

Crear un proyecto de tipo Librería de Clases en C# llamado: "Northwind.Librerias.EntidadesNegocio" y modificar el código de la clase como sigue:

using System;
namespace Northwind.Librerias.EntidadesNegocio
{
    public class beEmpleado
    {
        public int IdEmpleado { get; set; }
        public string Apellido { get; set; }
        public string Nombre { get; set; }
        public string NombreCompleto
        {
            get
            {
                return (String.Format("{0} {1}",Nombre,Apellido));
            }
        }
        public DateTime FechaNacimiento { get; set; }
    }
}

Crear una Librería de Acceso a Datos

Crear un proyecto de tipo Librería de Clases en C# llamado: "Northwind.Librerias.AccesoDatos" y modificar el código de la clase como sigue:

using System;
using System.Data; //CommandType
using System.Data.SqlClient; //SqlConnection, SqlCommand, SqlDataReader
using System.Collections.Generic; //List
using Northwind.Librerias.EntidadesNegocio; //beEmpleado
namespace Northwind.Librerias.AccesoDatos
{
    public class daEmpleado
    {
        public List<beEmpleado> listar(SqlConnection con)
        {
            List<beEmpleado> lbeEmpleado = null;
            SqlCommand cmd = new SqlCommand("uspEmployeesListar", con);
            cmd.CommandType = CommandType.StoredProcedure;
            SqlDataReader drd = cmd.ExecuteReader(CommandBehavior.SingleResult);
            if (drd != null)
            {
                lbeEmpleado = new List<beEmpleado>();
                int posIdEmpleado = drd.GetOrdinal("EmployeeID");
                int posApellido = drd.GetOrdinal("LastName");
                int posNombre = drd.GetOrdinal("FirstName");
                int posFechaNacimiento = drd.GetOrdinal("BirthDate");
                beEmpleado obeEmpleado;
                while (drd.Read())
                {
                    obeEmpleado = new beEmpleado();
                    obeEmpleado.IdEmpleado = drd.GetInt32(posIdEmpleado);
                    obeEmpleado.Apellido = drd.GetString(posApellido);
                    obeEmpleado.Nombre = drd.GetString(posNombre);
                    obeEmpleado.FechaNacimiento = drd.GetDateTime(posFechaNacimiento);
                    lbeEmpleado.Add(obeEmpleado);
                }
                drd.Close();
            }
            return (lbeEmpleado);
        }
    }
}

Nota: Hay que hacer una referencia a la Librería de Entidades del Negocio.

Crear una Librería de Reglas del Negocio

Crear un proyecto de tipo Librería de Clases en C# llamado: "Northwind.Librerias.ReglasNegocio" y modificar el código de la clase como sigue:

using System;
using System.Configuration; //ConfigurationManager
namespace Northwind.Librerias.ReglasNegocio
{
    public class brGeneral
    {
        //Propiedad
        public string Conexion { get; set; }

        //Constructor
        public brGeneral()
        {
            Conexion = ConfigurationManager.ConnectionStrings["conNW"].ConnectionString;
        }
    }
}

Nota: Hay que hacer una referencia a la Librería de Entidades del Negocio, a la Librería de Acceso a Datos y a System.Configuration.

Agregar otra clase llamada: "brEmpleado" y escribir el siguiente código:

using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using Northwind.Librerias.EntidadesNegocio;
using Northwind.Librerias.AccesoDatos;

namespace Northwind.Librerias.ReglasNegocio
{
    public class brEmpleado:brGeneral //Herencia
    {
        public List<beEmpleado> listar()
        {
            List<beEmpleado> lbeEmpleado = null;
            using (SqlConnection con = new SqlConnection(Conexion))
            {
                try
                {
                    con.Open();
                    daEmpleado odaEmpleado = new daEmpleado();
                    lbeEmpleado = odaEmpleado.listar(con);
                }
                catch (SqlException ex)
                {
                    //Capturar el error y grabar un Log
                }
            } //con.Close(); con.Dispose(); con = null;
            return (lbeEmpleado);
        }
    }
}

Nota: La clase "brEmpleado" hereda de la clase "brGeneral" la cadena de conexión para no pasarla como parámetro en cada método de la clase o en el constructor de cada clase se hace una sola vez.

Crear una Librería de Código de Usuario para Web

Crear un proyecto de tipo Librería de Clases en C# llamado: "General.Librerias.CodigoUsuarioWeb" y modificar el código de la clase como sigue:

using System;
using System.Collections.Generic;
using System.IO; //File
using System.Web; //HttpContext

namespace General.Librerias.CodigoUsuarioWeb
{
    public class Imagen
    {
        public static string obtenerUrl(int id, string carpeta)
        {
            string archivo = HttpContext.Current.Server.MapPath
            (String.Format("../Imagenes/{0}/{1}.jpg", carpeta, id));
            string url = String.Format("../Imagenes/{0}/{1}.jpg", carpeta, id);
            if (!File.Exists(archivo)) url = String.Format("../Imagenes/{0}/No.jpg", carpeta);
            return (url);
        }
    }
}

Nota: Como esta librería va a ser usada por paginas web hay que hacer referencia a: "System.Web"

Crear la Aplicación Web en ASP .NET Web Form

Crear un "Nuevo Sitio web vacío de ASP .NET" en C# llamado "Demo11" y crear las siguientes carpetas:
- Estilos: Para el archivo de hoja de estilo (CSS).
- Imagenes. Dentro crear otra carpeta llamada "Empleados" y adjuntar los archivos con las fotos de los empleados: 1.jpg, 2.jpg, 3.jpg, ... y No.jpg.
- Paginas: Para contener la pagina de lista de empleados.

Crear el Archivo de Hoja de Estilo (CSS)

Seleccionar la carpeta "Estilos" y agregar un archivo de hoja de estilos con el nombre de: "ACME.css" y modificar el código como sigue:

body {
    background-color:aqua;
}
.Titulo {
    background-color:black;
    color:white;
    text-transform:uppercase;
    font-size:xx-large;
    font-weight:bold;
}
.Subtitulo {
    background-color:white;
    color:blue;
    text-transform:capitalize;
    font-size:x-large;
    font-weight:bold;
}
.MarcarFila tr {
    background-color: white;
    color: blue;
    cursor:default;
    font-weight:normal;
}
.MarcarFila tr:hover {
    background-color: yellow;
    color: red;
    cursor:pointer;
    font-weight:bold;
}

Crear la Pagina ASP .NET como un Formulario Web Form

Seleccionar la carpeta "Paginas" y agregar un Formulario Web Form llamado: "ListaEmpleados.aspx", para empezar a diseñar la pagina hay que hacer referencia a las Librerías de Negocio (que copia todas sus dependencias) y la Librería de Código de Usuario Web.

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ListaEmpleados.aspx.cs" Inherits="Paginas_ListaEmpleados" %>
<%@ Import Namespace="Northwind.Librerias.EntidadesNegocio" %>
<%@ Import Namespace="General.Librerias.CodigoUsuarioWeb" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <link href="../Estilos/ACME.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <table style="width:100%">
            <tr>
                <td class="Titulo">Plantilla y estilos en el Control Repeater</td>
            </tr>
            <tr>
                <td class="Subtitulo">Lista de Empleados</td>
            </tr>
            <tr>
                <td>
                    <asp:Repeater ID="rpEmpleado" runat="server" EnableViewState="False">
                        <HeaderTemplate>
                            <table class="MarcarFila">
                                <tr style="text-align:center;background-color:blue;color:white">
                                    <td rowspan="2" style="width:100px">Código</td>
                                    <td colspan="2" style="width:300px">Nombre Completo</td>
                                    <td rowspan="2" style="width:100px">Fecha Nac</td>
                                    <td rowspan="2" style="width:150px">Foto</td>
                                </tr>
                                <tr style="text-align:center;background-color:blue;color:white">
                                    <td style="width:150px">Apellido</td>
                                    <td style="width:150px">Nombre</td>
                                </tr>
                        </HeaderTemplate>
                        <ItemTemplate>
                            <tr>
                                <td>
                                    <%#((beEmpleado)Container.DataItem).IdEmpleado%>
                                </td>
                                <td>
                                    <%#((beEmpleado)Container.DataItem).Apellido%>
                                </td>
                                <td>
                                    <%#((beEmpleado)Container.DataItem).Nombre%>
                                </td>
                                <td>
                                    <%#((beEmpleado)Container.DataItem).FechaNacimiento.
                                       ToShortDateString()%>
                                </td>
                                <td>
                                    <img src='<%#Imagen.obtenerUrl(((beEmpleado)Container.DataItem)
                                      .IdEmpleado,"Empleados")%>' width="120" height="80" alt="Foto"
                                       title="<%#((beEmpleado)Container.DataItem).NombreCompleto%>"/>
                                </td>
                            </tr>
                        </ItemTemplate>
                        <FooterTemplate>
                            </table>
                        </FooterTemplate>
                    </asp:Repeater>
                </td>
            </tr>
        </table>
    </div>
    </form>
</body>
</html>

Nota: El código que se encuentre entre los marcadores: "<%%>" se ejecuta en el servidor, si tiene un # indica que es enlace de datos (solo se usa dentro de un control enlazado a datos). La instrucción Container.DataItem obtiene una fila enlazada a datos, en este caso un Empleado ya que el Repeater estará enlazado a una Lista de Objetos Empleados.

El diseño de la pagina se mostrará como en la siguiente figura:


Escribir el siguiente código C# en la página:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Northwind.Librerias.EntidadesNegocio; //beEmpleado
using Northwind.Librerias.ReglasNegocio; //brEmpleado

public partial class Paginas_ListaEmpleados : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            brEmpleado obrEmpleado = new brEmpleado();
            List<beEmpleado> lbeEmpleado = obrEmpleado.listar();
            rpEmpleado.DataSource = lbeEmpleado;
            rpEmpleado.DataBind();
        }
    }
}

Modificar el Archivo Web.Config para especificar la cadena de conexión a Northwind

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <connectionStrings>
    <add name="conNW" providerName="SQLServer" connectionString="uid=UsuarioNW;pwd=123456;
      data source=DSOFT\Sqlexpress; database=Northwind"/>
  </connectionStrings>
    <system.web>
      <compilation debug="true" targetFramework="4.5" />
      <httpRuntime targetFramework="4.5" />
    </system.web>
</configuration>

Probar la Pagina Web

Guardar el Sitio Web, clic derecho a la Pagina "ListaEmpleados.aspx" y seleccionar "Ver en el explorador".


Pasar el mouse por cada fila y notar como cambia el estilo de la fila seleccionada debido al estilo "MarcarFila" aplicado a la tabla que esta dentro del control Repeater.

Clic derecho a la página y seleccionar "Ver código fuente de la pagina", notar que el HTML generado desde el servidor es mínimo ya que se le quito el ViewState al control Repeater y se uso Hojas de Estilo para reducir el formato en cada fila.

Comentario Final

Es muy útil el uso de Plantillas de Datos para personalizar la apariencia de los controles Web en ASP .NET, además es necesario entender que debemos enviar la menor cantidad de HTML al navegador para que se cargue mas rápido la página, en este caso lo logramos configurando el ViewState y usando CSS.

En los siguientes demos, estaremos viendo mas el tema de Plantillas de Datos, Hojas de Estilos y Controles Enlazados a Datos en ASP .NET.

Descarga:
Demo11_Plantilla_Repeater