martes, 12 de agosto de 2014

El Libro del Día: Learning Responsive Web Design

El Libro del Día: 2014-08-12

Titulo: Learning Responsive Web Design
Autor: Clarissa Peterson
Editorial: O'Reilly
Nro Paginas: 412

Capítulos:
Part I FOUNDAT IONS OF RESPONSIVE DESIGN
Chapter 1 What Is Responsive Design?
Chapter 2 Responsive Content
Part II CREAT ING RESPONSIVE WEBSITES
Chapter 3 HTML for Responsive Sites
Chapter 4 CSS for Responsive Sites
Chapter 5 Media Queries
Chapter 6 Images
Part III WORKING RESPONSIVELY
Chapter 7 Responsive Workflow
Chapter 8 Mobile and Beyond
Part IV DESIGNING RESPONSIVE WEBSITES
Chapter 9 Typography
Chapter 10 Navigation and Header Layout
Chapter 11 Performance

Descarga:
Learning_Responsive_Web_Design

lunes, 11 de agosto de 2014

El Libro del Día: HTML5 and CSS3 Responsive Web Design Cookbook

El Libro del Día: 2014-08-11

Titulo: HTML5 and CSS3 Responsive Web Design Cookbook
Autor: Benjamin LaGrone
Editorial: Packt
Nro Paginas: 204

Capítulos:
Chapter 1: Responsive Elements and Media
Chapter 2: Responsive Typography
Chapter 3: Responsive Layout
Chapter 4: Using Responsive Frameworks
Chapter 5: Making Mobile-first Web Applications
Chapter 6: Optimizing Responsive Content
Chapter 7: Unobtrusive JavaScript

Descarga:
HTML5_CSS3_Responsive_Web_Design_Cookbook

domingo, 10 de agosto de 2014

El Libro del Día: Jump Start Responsive Web Design

El Libro del Día: 2014-08-10

Titulo: Jump Start Responsive Web Design
Autor: Craig Sharkie, Andrew Fisher
Editorial: SitePoint
Nro Paginas: 161

Capítulos:
Chapter 1 Becoming Responsive
Chapter 2 Fluid Grids
Chapter 3 Adaptive Images
Chapter 4 Understanding Media Queries
Chapter 5 Responsive Content
Chapter 6 Responsive Boilerplate

Descarga:
JumpStart_Responsive_Web_Design

sábado, 9 de agosto de 2014

El Libro del Día: Professional Visual Studio 2013

El Libro del Día: 2014-08-09

Titulo: Professional Visual Studio 2013
Autor: Bruce Johnson
Editorial: Wrox
Nro Paginas: 1102

Capítulos:
Part I - Integrated Development Environment
Chapter 1 A Quick Tour
Chapter 2 The Solution Explorer, Toolbox, and Properties
Chapter 3 Options and Customizations
Chapter 4 The Visual Studio Workspace
Chapter 5 Find and Replace and Help
Part II - Getting Started
Chapter 6 Solutions, Projects, and Items
Chapter 7 IntelliSense and Bookmarks
Chapter 8 Code Snippets and Refactoring
Chapter 9 Server Explorer
Chapter 10 Modeling with the Class Designer
Part III - Digging Deeper
Chapter 11 Unit Testing
Chapter 12 Documentation with XML Comments
Chapter 13 Code Consistency Tools
Chapter 14 Code Generation with T4
Chapter 15 Project and Item Templates
Chapter 16 Language-Specific Features
Part IV - Rich Client Applications
Chapter 17 Windows Forms Applications
Chapter 18 Windows Presentation Foundation (WPF)
Chapter 19 Office Business Applications
Chapter 20 Windows Store Applications
Part V - Web Applications
Chapter 21 ASP.NET Web Forms
Chapter 22 ASP.NET MVC
Chapter 23 Silverlight
Chapter 24 Dynamic Data
Chapter 25 SharePoint
Chapter 26 Windows Azure
Part VI - Data
Chapter 27 Visual Database Tools
Chapter 28 DataSets and DataBinding
Chapter 29 Language Integrated Queries (LINQ)
Chapter 30 The ADO.NET Entity Framework
Chapter 31 Reporting
Part VII - Application Services
Chapter 32 Windows Communication Foundation (WCF)
Chapter 33 Windows Workflow Foundation (WF)
Chapter 34 Client Application Services
Chapter 35 Synchronization Services
Chapter 36 WCF RIA Services
Part VIII Configuration and Resources
Chapter 37 Configuration Files
Chapter 38 Connection Strings
Chapter 39 Resource Files
Part IX - Debugging
Chapter 40 Using the Debugging Windows
Chapter 41 Debugging with Breakpoints
Chapter 42 DataTips, Debug Proxies, and Visualizers
Chapter 43 Debugging Web Applications
Chapter 44 Advanced Debugging Techniques
Part X - Build and Deployment
Chapter 45 Upgrading with Visual Studio 2013
Chapter 46 Build Customization
Chapter 47 Assembly Versioning and Signing
Chapter 48 Obfuscation, Application Monitoring, and Management
Chapter 49 Packaging and Deployment
Chapter 50 Web Application Deployment
Part XI - Customizing and Extending Visual Studio
Chapter 51 The Automation Model
Chapter 52 Add-Ins
Chapter 53 Managed Extensibility Framework (MEF)
Part XII - Visual Studio Ultimate
Chapter 54 Visual Studio Ultimate for Architects
Chapter 55 Visual Studio Ultimate for Developers
Chapter 56 Visual Studio Ultimate for Testers
Chapter 57 Team Foundation Server

Descarga:
Professional_VisualStudio_2013

viernes, 8 de agosto de 2014

El Libro del Día: Pro ASP.NET 4.5 in VB

El Libro del Día: 2014-08-08

Titulo: Pro ASP.NET 4.5 in VB (5th Edition)
Autor: Dan Mabbutt, Adam Freeman, Matthew MacDonald
Editorial: Apress
Nro Paginas: 1192

Capítulos:
Part 1: Getting Started
Chapter 1: Your First ASP.NET Application
Chapter 2: Putting ASP.NET in Context
Chapter 3: Essential VB Language Features
Chapter 4: Using jQuery
Chapter 5: Essential Development Tools
Chapter 6: SportsStore: A Real Application
Chapter 7: SportsStore: Navigation and Cart
Chapter 8: SportsStore: Completing the Cart
Chapter 9: SportsStore: Administration
Chapter 10: SportsStore: Deployment
Chapter 11: Testable Web Apps
Part 2: The Core ASP.NET Platform
Chapter 12: Working with Web Forms
Chapter 13: Lifecycles and Context
Chapter 14: Modules
Chapter 15: Handlers
Chapter 16: Page and Control Lifecycle Events
Chapter 17: Managing Request Execution
Chapter 18: Managing State Data
Chapter 19: Caching
Chapter 20: Caching Output
Chapter 21: Handling Errors
Chapter 22: Managing Paths
Chapter 23: URL Routing
Chapter 24: Advanced URL Routing
Chapter 25: Authentication and Authorization
Chapter 26: Membership and OpenAuth
Chapter 27: ASP.NET Configuration
Chapter 28: Asynchronous Request Handling
Part 3: Forms and Controls
Chapter 29: Working with Controls
Chapter 30: Forms and Request Validation
Chapter 31: Creating Custom Controls
Chapter 32: Stateful Controls
Chapter 33: Server-Side HTML Elements
Chapter 34: Model Binding
Chapter 35: Data Binding
Chapter 36: Basic Data Controls
Chapter 37: Complex Data Controls
Chapter 38: Other ASP.NET Controls
Part 4: Client-Side Development
Chapter 39: Managing Scripts and Styles
Chapter 40: Ajax and Web Services
Chapter 41: Client-Side Validation

Descarga:
Pro_ASPNET_4.5_VB

jueves, 7 de agosto de 2014

El Libro del Día: Windows Phone 8 Development Internals

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

Titulo: Windows Phone 8 Development Internals
Autor: Andrew Whitechapel, Sean McKenna
Editorial: Microsoft
Nro Paginas: 1046

Capítulos:
Part I CORE FEATURES
Chapter 1 Vision and architecture
Chapter 2 App model and navigation
Chapter 3 UI visuals and touch
Chapter 4 Data binding and MVVM
Chapter 5 Phone and media services
Chapter 6 Sensors
Chapter 7 Web connectivity
Chapter 8 Web services and the cloud
Chapter 9 Background agents
Chapter 10 Local storage and databases
Part II WINDOWS PHONE 7 TO WINDOWS PHONE 8
Chapter 11 App publication
Chapter 12 Profiling and diagnostics
Chapter 13 Porting to Windows Phone 8 and multitargeting
Chapter 14 Tiles and notifications
Chapter 15 Contacts and calendar
Chapter 16 Camera and photos
Chapter 17 Networking and proximity
Chapter 18 Location and maps
Part III NEW WINDOWS PHONE 8 FEATURES
Chapter 19 Speech
Chapter 20 The Wallet
Chapter 21 Monetizing your app
Chapter 22 Enterprise apps
Part IV NATIVE DEVELOPMENT AND WINDOWS PHONE 8
CONVERGENCE
Chapter 23 Native development
Chapter 24 Windows 8 convergence
Chapter 25 Games and Direct3D

Descarga:
WindowsPhone_8_Development_Internals

miércoles, 6 de agosto de 2014

El Demo del Día: Paginar, Ordenar y Filtrar en el Control Web DataList

Paginar, Ordenar y Filtrar 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.
- Las fichas deben tener fondo gris claro, pero al pasar el mouse el estilo de la ficha cambiara a fondo amarillo.
- La información debe estar paginada (por defecto mostrar 6 registros de empleados), mediante botones de desplazamiento y enlaces con números de paginas.
- Se debe permitir ordenar los registros por cualquier campo en forma ascendente y descendente.
- Se debe permitir filtrar los registros por cualquier campo ingresando el dato buscado.

Solución

Usaremos el control DataList con Plantilla de Datos para poder presentar en forma de ficha la información del empleado y mostrarla en varias columnas. Ademas agregaremos botones y enlaces para paginar, combos para seleccionar los criterios de ordenación y filtro de registros.

Nota: En este caso si podemos deshabilitar el ViewState del DataList ya que no hay ningun control dentro de la plantilla que haga PostBack, es decir enviaremos el minimo HTML al navegador 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 "Demo14" 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;
}
.MarcarTabla {
    background-color: lightgray;
    cursor:default;
    border:solid;
    border-color:lightgray;
}
.MarcarTabla:hover {
    background-color: yellow;
    cursor:pointer;
    border:solid;
    border-color:black;
}

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" colspan="5">Paginar, Ordenar y Filtrar en el DataList</td>
            </tr>
            <tr>
                <td class="Subtitulo" colspan="5">Lista de Empleados</td>
            </tr>
            <tr>
                <td style="width:10%">Ordenar Por: </td>
                <td style="width:20%">
                    <asp:DropDownList ID="ddlCampo" runat="server" />
                </td>
                <td style="width:10%">Tipo Orden: </td>
                <td style="width:20%">
                    <asp:DropDownList ID="ddlOrden" runat="server">
                        <asp:ListItem Value="0">Ascendente</asp:ListItem>
                        <asp:ListItem Value="1">Descendente</asp:ListItem>
                    </asp:DropDownList>
                </td>
                <td style="width:40%">
                    <asp:Button ID="btnOrdenar" Text="Ordenar" 
                      OnClick="ordenarCampo" runat="server"/>
                </td>
            </tr>
            <tr>
                <td style="width:10%">Filtrar Por: </td>
                <td style="width:20%">
                    <asp:DropDownList ID="ddlCriterio" runat="server" AutoPostBack="True" 
                      OnSelectedIndexChanged="cambiarControlBusqueda" />
                </td>
                <td style="width:10%">Dato Filtrar: </td>
                <td style="width:20%">
                    <asp:TextBox ID="txtDato" Width="130" runat="server" />
                </td>
                <td style="width:40%">
                    <asp:Button ID="btnFiltrar" Text="Filtrar" OnClick="filtrarCriterio" runat="server"/>
                </td>
            </tr>
            <tr>
                <td colspan="5" class="Subtitulo">Registros encontrados: 
                    <asp:Label ID="lblRegistros" Text="0" runat="server"/>
                </td>
            </tr>
            <tr>
                <td colspan="5">
                    <asp:DataList ID="dlsEmpleado" runat="server" EnableViewState="False" 
                        RepeatColumns="3" CellPadding="15" CellSpacing="15"
                        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>
            <tr>
                <td id="celdaBotones" style="text-align:center" colspan="5" runat="server">
                    <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" colspan="5" 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
using System.Reflection; //PropertyInfo

public partial class Paginas_ListaEmpleados : System.Web.UI.Page
{
    private List<beEmpleado> lbeEmpleado;
    private int registrosPagina = 6;
    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();
            Session["Empleados"] = lbeEmpleado;
            Session["Todo"] = lbeEmpleado;
            calcularPaginacion();
            enlazarDataList();
            cargarListaCampos();
        }
        else
        {
            indicePaginaActual = (int)ViewState["indicePaginaActual"];
            indiceUltimaPagina = (int)ViewState["indiceUltimaPagina"];
        }
        crearEnlacesPaginas();
    }

    private void calcularPaginacion()
    {
        indiceUltimaPagina = (lbeEmpleado.Count / registrosPagina);
        if (lbeEmpleado.Count % registrosPagina == 0)
            indiceUltimaPagina--;
        ViewState["indicePaginaActual"] = indicePaginaActual;
        ViewState["indiceUltimaPagina"] = indiceUltimaPagina;
    }

    private void cargarListaCampos()
    {
        ddlCriterio.Items.Add(new ListItem("Todo", ""));
        PropertyInfo[] propiedades = lbeEmpleado[0].
            GetType().GetProperties();
        foreach (PropertyInfo propiedad in propiedades)
        {
            ddlCampo.Items.Add(new ListItem
                (propiedad.Name, propiedad.Name));
            ddlCriterio.Items.Add(new ListItem
                (propiedad.Name, propiedad.Name));
        }
    }

    private void crearEnlacesPaginas()
    {
        celdaPaginas.Controls.Clear();
        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;
        enlazarDataList();
    }

    private void enlazarDataList()
    {
        indicePaginaActual = (int)ViewState["indicePaginaActual"];
        indiceUltimaPagina = (int)ViewState["indiceUltimaPagina"];

        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;
        }
        dlsEmpleado.DataSource = lbeFiltro;
        dlsEmpleado.DataBind();
        lblRegistros.Text = lbeEmpleado.Count.ToString();
        txtPosicion.Text = String.Format("{0} de {1}", indicePaginaActual + 1,
            indiceUltimaPagina + 1);
    }

    protected void ordenarCampo(object sender, EventArgs e)
    {
        string campo = ddlCampo.SelectedValue;
        int orden = int.Parse(ddlOrden.SelectedValue);
        lbeEmpleado = (List<beEmpleado>)Session["Empleados"];
        if (orden.Equals(0)) 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;
        enlazarDataList();
    }

    protected void filtrarCriterio(object sender, EventArgs e)
    {
        string campo = ddlCriterio.SelectedValue;
        lbeEmpleado = (List<beEmpleado>)Session["Todo"];
        if (!campo.Equals(""))
        {
            string tipo = lbeEmpleado[0].GetType().GetProperty(campo).
                PropertyType.ToString().ToLower();
            if (tipo.Contains("datetime"))
            {
                string[] fechaNac = txtDato.Text.Split('-');
                txtDato.Text = fechaNac[2] + "/" + fechaNac[1] + "/" + fechaNac[0];
            }
            lbeEmpleado = lbeEmpleado.FindAll(x => x.GetType().GetProperty(campo).
               GetValue(x, null).ToString().ToLower().Contains(txtDato.Text.ToLower()));
        }
        celdaBotones.Visible = (lbeEmpleado.Count > 0);
        Session["Empleados"] = lbeEmpleado;
        indicePaginaActual = 0;
        ViewState["indicePaginaActual"] = indicePaginaActual;
        calcularPaginacion();
        enlazarDataList();
        crearEnlacesPaginas();
    }

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

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

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

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

    protected void cambiarControlBusqueda(object sender, EventArgs e)
    {
        string campo = ddlCriterio.SelectedValue;
        txtDato.Text = "";
        if (campo.Equals("")) txtDato.TextMode = TextBoxMode.SingleLine;
        else
        {
            lbeEmpleado = (List<beEmpleado>)Session["Empleados"];
            string tipo = lbeEmpleado[0].GetType().GetProperty(campo).
                PropertyType.ToString().ToLower();
            if (tipo.Contains("int")) txtDato.TextMode = TextBoxMode.Number;
            else
            {
                if (tipo.Contains("datetime")) txtDato.TextMode = TextBoxMode.Date;
                else txtDato.TextMode = TextBoxMode.SingleLine;
            }
        }
        enlazarDataList();
    }
}

Nota: Por defecto los registrosPorPagina está configurado a 6 y usamos Reflection para cargar dinamicamente los combos con los nombres de las propiedades del objeto empleado.

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.

Seleccionar un criterio del combo "Ordenar Por", luego seleccionar el "Tipo de Orden" (ascendente o descendente) y clic al botón "Ordenar", ver como los registros se ordenan por el campo seleccionado.

Seleccionar un criterio del combo "Filtrar Por", luego ingresar un dato en "Dato Filtrar" y clic al botón "Filtrar", ver como solo aparecen los registros que cumplen con el criterio, se muestra la cantidad de registros encontrados y como varia los números de paginas.

Comentario Final

En esta demostración hemos visto como podemos paginar, ordenar y filtrar usando el control DataList y sin usar ViewState para dicho control para minimizar el HTML enviado al navegador. Mas bien hemos usado el ViewState (y no Session) para almacenar y recuperar el "indicePaginaActual" y el "indiceUltimaPagina" ya que al hacer PostBack se pierden los valores de las variables.

Descarga:
Demo14_Paginar_Ordenar_Filtrar_DataList