ASP.NET Chart Controls y ASP.NET MVC

Hace ya más de un año apareció una nueva librería para la creación de gráficos, tanto para Web Forms como Win Forms, con una enorme cantidad de posibilidades. Hoy en día se nos puede plantear la posibilidad de utilizar estos mismos controles para una aplicación ASP.NET MVC y cómo sería la forma más sencilla de adaptarlo.
Si bien he leído y probado varias opciones, voy a escribir sobre la que me ha parecido más sencilla y más práctica.

INSTALACIÓN DE LIBRERÍAS Y COMPONENTES 

Para poder trabajar con estos controles, es necesario descargar dos ejecutables:

La librería que nos permite la creación de un gráfico se llama System.Web.DataVisualization, la cual está disponible instalando el primero de los paquetes. El segundo de ellos es interesante instalarlo para poder visualizar en el cuadro de herramientas el control de tipo Chart. Existen numerosas combinaciones y propiedades configurables para este tipo de controles, por lo que hay veces que es más práctico crear una aplicación Web Forms de prueba, en modo diseño arrastrar el control y personalizarlo. De esta forma podemos ver el código generado en el aspx y las propiedades utilizadas para ese chart en concreto. Otra de las posibilidades es descargar el proyecto de ejemplos y localizar alguno que ya esté definido y adaptarlo.

CREACIÓN DEL GRÁFICO

Para entender mejor el código, podríamos decir que un chart se compone de 4 partes principalmente: Chart, que es el control principal, Legend, encargado de la leyenda del gráfico, ChartArea, el cual representa el área donde se mostrarán los valores y las Series que son los valores en sí.

El primer paso es agregar una referencia a la librería System.Web.DataVisualization. Una vez añadida, creamos una nueva acción donde se instanciarán los controles necesarios y, finalmente, nos devolverá la imagen generada según las propiedades establecidas.

public ActionResult GetChart()
{
const string legend = "Legend";
const string chartArea = "chartArea";

var chart = ChartFactory.CreateChart("ASP.NET MVC and MSChart by GiS!");


ChartFactory.CreateSerie(chart, "januarySeries", chartArea,
legend, "Emboss", Color.ForestGreen,
ChartValueType.DateTime, ChartValueType.Double,
_repository.GetMonthData(1));

ChartFactory.CreateSerie(chart, "februarySeries", chartArea,
legend, "Cylinder", Color.DodgerBlue,
ChartValueType.DateTime, ChartValueType.Double,
_repository.GetMonthData(1));

ChartFactory.CreateSerie(chart, "marchSeries", chartArea,
legend, "Wedge", Color.DarkViolet,
ChartValueType.DateTime, ChartValueType.Double,
_repository.GetMonthData(3));

var memoryStream = new MemoryStream();
chart.SaveImage(memoryStream);

return File(memoryStream.GetBuffer(), @"image/png");
}

Para intentar refactorizar parte del código necesario para generar el gráfico, he creado una clase llamada ChartFactory en la cual podemos formar tanto el chart, la leyenda, el chartArea y las series que se mostrarán.

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Web.UI.DataVisualization.Charting;
using ChartControlASPNETMVC.Models;

namespace ChartControlASPNETMVC
{
public static class ChartFactory
{
public static Chart CreateChart(string chartTitle)
{
//Chart
var chart = new Chart
{
Height = 296,
Width = 412,
BorderWidth = 2,
ImageType = ChartImageType.Png,
BackColor = ColorTranslator.FromHtml("#F3DFC1"),
BorderlineDashStyle = ChartDashStyle.Solid,
BackGradientStyle = GradientStyle.LeftRight,
BorderColor = Color.FromArgb(181, 64, 1),
BorderSkin = { SkinStyle = BorderSkinStyle.Sunken },
};

//Title
var title = chart.Titles.Add("chartTitle");
title.ShadowColor = Color.FromArgb(32, 0, 0, 0);
title.ShadowOffset = 3;
title.ForeColor = Color.FromArgb(26, 59, 105);
title.Font = new Font("Trebuchet MS", 14, FontStyle.Bold);
title.Text = chartTitle;
title.Alignment = ContentAlignment.TopLeft;

//Legend
var legend = chart.Legends.Add("chartLegend");
legend.LegendStyle = LegendStyle.Row;
legend.Font = new Font("Trebuchet MS", 10, FontStyle.Bold);
legend.Enabled = true;
legend.Name = "Legend";
legend.BackColor = Color.Transparent;
legend.Position.Y = 95;
legend.Position.X = 5;
legend.Position.Height = 20;
legend.Position.Width = 100;

//Chart Area
var chartArea = chart.ChartAreas.Add("chartArea");
chartArea.BorderColor = Color.FromArgb(64, 64, 64, 64);
chartArea.BackSecondaryColor = Color.White;
chartArea.BackColor = Color.OldLace;
chartArea.ShadowColor = Color.Transparent;

//Chart Area 3D Style
chartArea.Area3DStyle.Enable3D = true;
chartArea.Area3DStyle.Rotation = -20;
chartArea.Area3DStyle.Perspective = 8;
chartArea.Area3DStyle.Inclination = 18;
chartArea.Area3DStyle.IsRightAngleAxes = false;
chartArea.Area3DStyle.WallWidth = 0;
chartArea.Area3DStyle.IsClustered = false;
chartArea.Area3DStyle.PointDepth = 50;
chartArea.Area3DStyle.PointGapDepth = 200;

chartArea.AxisY.LineColor = Color.FromArgb(64, 64, 64, 64);
chartArea.AxisY.IsLabelAutoFit = false;
chartArea.AxisY.LabelStyle.Font = new Font("Trebuchet MS", 8, FontStyle.Bold);
chartArea.AxisY.MajorGrid.LineColor = Color.FromArgb(64, 64, 64, 64);

chartArea.AxisX.LineColor = Color.FromArgb(64, 64, 64, 64);
chartArea.AxisX.IsLabelAutoFit = false;
chartArea.AxisX.LabelStyle.Font = new Font("Trebuchet MS", 8, FontStyle.Bold);
chartArea.AxisX.MajorGrid.LineColor = Color.FromArgb(64, 64, 64, 64);

return chart;
}


public static void CreateSerie(Chart chart, string serieName, string chartAreaName, string legendName, string drawingStyle, Color color, ChartValueType xValue, ChartValueType yValue, List<TableSample> monthData)
{
var newSerie = chart.Series.Add(serieName);
newSerie.ChartArea = chartAreaName;
newSerie.XValueType = xValue;
newSerie.YValueType = yValue;
newSerie.Name = serieName;
newSerie.ShadowColor = Color.Transparent;
newSerie.BorderColor = color;
newSerie.Color = color;
newSerie.Legend = legendName;

/**** Drawing Style ****/
/*Cylinder - Data points are drawn as cylinders.
Emboss - Data points are drawn with an embossed effect.
LightToDark - Data points are drawn with a light-to-dark effect.
Wedge - Data points are drawn with a wedge effect.
Default - Data points are drawn as cubes.*/

newSerie["DrawingStyle"] = drawingStyle;
newSerie["PointWidth"] = "0.8";

WriteSeries(newSerie, monthData);
}

private static void WriteSeries(Series serie, IEnumerable<TableSample> list)
{
foreach (TableSample t in list)
{
serie.Points.Add(new DataPoint
{
YValues = new Double[] { t.Amount },
LegendText = t.Date.Day.ToString(),
AxisLabel = t.Date.Day.ToString()
});
}
}
}
}

Seguramente podremos refactorizar aún más y hacer una librería que nos permita mayor flexibilidad, pero el objetivo de este post es mostrar que existe la posibilidad de utilizar este tipo de controles.

La función de este control, a fin de cuentas, es generar una imagen con las propiedades y los datos obtenidos. Para llamar a la acción GetChart desde nuestra vista únicamente debemos asignar la misma al source de una imagen.

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Home Page
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>
<%= Html.Encode(ViewData["Message"]) %></h2>
<div id="container">
<img src="<%=Url.Action("GetChart") %>" alt="Chart Sample" />
</div>
</asp:Content>

 Si arrancamos la aplicación, el resultado sería el siguiente:

Y, lo mejor de todo, el renderizado de la página:



!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
html xmlns="http://www.w3.org/1999/xhtml">
head><title>

Home Page

/title><link href="Content/Site.css" rel="stylesheet" type="text/css" />


/head>
body>
<div class="page">
<div id="header">
<div id="title">
<h1>
My MVC Application</h1>
</div>
<div id="logindisplay">

[ <a href="/Account/LogOn">Log On</a> ]

</div>
<div id="menucontainer">
<ul id="menu">
<li>
<a href="/">Home</a></li>
<li>
<a href="/Home/About">About</a></li>
</ul>
</div>
</div>
<div id="main">

<h2>
Chart Control Sample!</h2>
<div id="container">
<img src="/Home/GetChart" alt="Chart Sample" />
</div>

<div id="footer">
</div>
</div>
</div>
/body>
/html>

Por último, debido a que esta librería es adicional al framework, sería recomendable modificar las propiedades de la misma para tener una copia en el paquete final.

Adjunto el proyecto por si fuera de utilidad.

¡Saludos!

Subir una aplicación ASP.NET MVC a IIS 5.1

Si todavía tenemos que trabajar con Windows XP y estamos utilizando proyectos en ASP.NET MVC es posible que queramos publicar los mismos en el IIS local para realizar las pruebas necesarias. En este caso, vamos a aprovecharnos de un bug de la versión 5.1 de Internet Information Server para hacer funcionar nuestro proyecto:

  1. Accedemos a las propiedades del directorio virtual donde tengamos alojada la aplicación.
  2. Nos aseguramos de que tenemos permisos para ejecutar sólo secuencias de comandos.

  3. Pulsamos sobre el botón Configuración… y, en la pestaña Asignaciones, pulsamos en Agregar.

  4. Rellenamos la ventana con los siguientes datos:
    • En el campo Ejecutable debemos seleccionar la DLL aspnet_isapi.dll, ubicada en la siguiente ruta: C:WINDOWSMicrosoft.NETFrameworkv2.0.50727aspnet_isapi.dll.
    • En el campo Extensión escribimos .*
    • Por último, eliminamos el check en Comprobar si el archivo existe.
  5. Al hacer estos pasos nos daremos cuenta de que el botón de Aceptar aparece deshabilitado debido a que la extensión proporcionada no es válida.
  6. Para poder aceptar los cambios, hacemos click sobre el campo Ejecutable y … ¡magia! 😛

Espero que sea de utilidad.

Fuente

¡Saludos!

Los controles de Telerik para ASP.NET MVC

Si bien es cierto que ASP.NET MVC te da mayor control sobre la vista que genera, puede resultar un retraso en nuestro proyecto el intentar generar controles algo más elaborados si no disponemos de unos conocimientos previos como diseñadores.

Para evitarnos esta búsqueda y aprendizaje, os propongo el uso de los controles de Telerik para ASP.NET MVC. Existen dos tipos de licencia: Una Open Source que está diseñada para el público en general, en la que podemos visualizar y modificar el código de los controles y, por otro lado, existe una licencia comercial para recibir más beneficios y soporte. En este post me centro en la versión Open Source.

Para crear estos controles, disponemos de una serie de Helpers:

  • Grid

    <%= Html.Telerik().Grid(Model)
            .Name("Grid")       
            .Pageable()
    %>
  • PanelBar

    <%= Html.Telerik().PanelBar()
           .Name("PanelBar")
           .Items(items =>
           {
               items.Add().Text("Item 1");
               items.Add().Text("Item 2");
           })
    %>
  • Calendar

    <%= Html.Telerik().Calendar()
           .Name("Calendar")
    %>
  • DatePicker

    <%= Html.Telerik().DatePicker()
            .Name("DatePicker")
    %>
  • Menu 

    <%= Html.Telerik().Menu()
            .Name("Menu")
            .Items(items =>
            {
                items.Add().Text("Item 1");
                items.Add().Text("Item 2");
            })
    %>
  • Numeric Textbox 

    <%= Html.Telerik().NumberTextBox()
                      .Name("NumberTextBox")
                      .Value(12.10)
    %>
  • TabStrip

    <%
         Html.Telerik().TabStrip()
             .Name("TabStrip")
             .Items(items =>
             {
                 items.Add().Text("Item 1")
                      .Content(()=>
                      {%>
                          <p>Content</p>
                      <%});
                 items.Add().Text("Item 2");
             })
             .Render();
     %>
  • TreeView

    <%= Html.Telerik().TreeView()
            .Name("TreeView")
            .Items(items =>
            {           items.Add().Text("Item 1");
                        items.Add().Text("Item 2");
             })
    %>

Todos los controles que requieran una carga de datos, tales como menús o el grid, podemos realizar el bindeo a través de Ajax, del objeto Model del cual hereda nuestra vista, a través de un web service, utilizando el ViewData, utilizando SiteMap o bien personalizar la información de una forma más manual.
Cada uno de ellos dispone de una serie de funcionalidades diferentes. En el caso del Grid podemos paginar, filtrar, agrupar, etcétera de una forma bastante sencilla y clara.

Para utilizarlos, solamente debemos registrarnos en la página y posteriormente bajar el ejecutable. Tiene una documentación lo bastante clara y organizada para no tener problemas a la hora de querer usar cualquiera de los controles. Por otro lado comentar que disponen de una comunidad muy activa que conviene visitar.
Espero que sirvan de utilidad y ayuden a ganar tiempo 😉

¡Saludos!

 

MAD.NUG: Desarrollando software para entregar valor al cliente

El próximo 23 de Marzo tendremos la suerte de poder contar con Hadi Hariri, evangelista tecnológico en JetBrains, que nos hablará de BDD (Behaviour Driven Development) como metodología ágil de desarrollo.
En esta charla tendremos la oportunidad de conocer las ideas detrás de BDD y ver de qué forma nos ayuda a lidiar a los desarrolladores con las especificaciones del cliente.

Como siempre, el evento tendrá lugar en el edificio de Microsoft Ibérica en Madrid. Para más información os facilito el enlace.

¡Saludos!

¿Qué es Sharepoint?

Muchas de las personas que no han tenido aún la oportunidad de pelearse con este producto desconocen qué es Sharepoint o cuál es su finalidad. Sé que en Geeks.ms muchas personas trabajan con ello y han tenido que lidiar con algunas de sus «peculiaridades», pero voy a intentar simplificarlo a mi manera para aquellos que justo ahora comienzan con este mundo.

Antiguamente, cuando las personas de una organización necesitaban compartir ficheros entre ellos, existían varias posibilidades:

  1. Se mandaba un correo con el archivo adjunto y una vez enviado no se sabía nada más o bien podían existir unas idas y venidas de correos con distintas versiones del mismo archivo con el riesgo que aquello suponía.
  2. Se compartía una carpeta en el pc de turno y la gente depositaba los documentos que creían convenientes para el resto de la empresa. Si al menos se tenía en cuenta una serie de permisos sobre esa carpeta, la cosa no terminaba en catástrofe… Si por el contrario existía el libre albedrío esperemos que, al menos, existiera un backup 😉
  3. […]

Obviamente estas alternativas y otras que podemos suponer nos «ayudan» a descentralizar la información, no tener un control real de las versiones de esos documentos, no saber siquiera si tenemos todos los documentos que realmente deberíamos, etcétera.

¿Qué es Sharepoint?

Sharepoint se encarga de aquellos puntos que no conseguíamos de una forma eficaz con otros sistemas:

  • Centralizar la información de la organización.
  • Control de versiones de la documentación.
  • Compartir los recursos con otros miembros.
  • Control de acceso a la información.
  • Buscar personas dentro de la empresa.
  • Etcétera. (Más información aquí)

¿Cómo se consigue?

Gracias a los conceptos Portal y sitios podemos disponer de la información de la empresa a través de la intranet y la extranet utilizando nuestras credenciales.

Este producto consta actualmente de dos partes para sacar el mayor provecho posible:

  • Windows Sharepoint Services (WSS) es la base para la creación de portales y los sitios web dentro de los mismos. Gracias a él podemos almacenar la información, controlar el acceso a la misma, administrar los usuarios, hacer uso del control de versiones, flujo de trabajo y el motor de búsqueda.
  • Microsoft Office Sharepoint Services 2007 (MOSS) se trata de una extensión de WSS, la cual nos aporta mayor funcionalidad en nuestros portales. Gracias a MOSS podemos crear formularios de InfoPath dinámicamente, integración con Reporting Services, BI, podemos hacer uso de bases de datos externas al sistema, utilizar Excel como un servidor cálculo, permitir  a los usuarios generar sitios individuales, etcétera. 

A día de hoy ya se está trabajando en Sharepoint 2010 y está prevista su fecha de lanzamiento para el día 12 de mayo de este año.

A medida que vaya conociendo cada una de las funcionalidades intentaré dedicarle el tiempo que se merezcan 🙂
Como desarrolladora, mi intención es dedicar la mayor parte de mi tiempo a descubrir las posibilidades que ofrece la plataforma para que los desarrolladores podamos extender aún más su funcionalidad.

Herramientas para el desarrollo

El entorno de trabajo es Visual Studio para el cual disponemos un SDK con las plantillas de Sharepoint. Están disponibles desde Visual Studio 2005 en adelante. Para poder descargar la versión oportuna podemos hacerlo a través de este link. En Visual Studio 2010 RC dichas plantillas ya están incluidas.

¿Os acordáis de FrontPage? Para aquellos que pensabais como yo que se había extinguido os comunico que para nada, su nombre actual es Sharepoint Designer y será nuestro aliado a la hora de diseñar 😉

Requisitos mínimos para una instalación stand-alone

  • Procesador: 2.5 GHz
  • RAM: 1 GB
  • Disco duro: 3 GB
  • Software: Windows Server 2003/2003 R2/2008
  • Visual Studio 2005/2008/2010
  • SQL Server 2005 (En la instalación de Sharepoint nos proporciona un SQL Server)

Más información.

Existe una máquina virtual ofrecida por Microsoft en el siguiente enlace. La misma está compuesta de veinte partes y se hace bastante pesada su descarga. Comentaros que yo intenté hacer uso de ella pero, desconozco si fue por un problema puntual, al intentar descomprimir la máquina me avisó de que una de las partes estaba corrupta y no pude continuar 🙁

La instalación es bien sencilla pero debemos tener en cuenta el siguiente orden para no volvernos loc@s. En este caso estamos suponiendo que la instalación es para un entorno de desarrollo:

  1. Una vez que tengamos preparado un Windows Server, debemos añadir el rol de Servidor Web para dejar preparado el IIS.
  2. Iniciamos la instalación de Sharepoint (Dentro de las opciones avanzadas, mantuve la instalación Independiente). Cuando la misma finaliza, podremos configurar Sharepoint en ese momento o ejecutar el asistente más adelante a través del acceso directo Sharepoint Products and Technologies. Por otro lado, para crear y configurar nuevos portales existe otro acceso directo llamado Sharepoint 3.0 Central Administration. Por el momento, para la serie de post que pretendo realizar, he creado un nuevo portal con un sitio de tipo Team Site.
  3. Instalamos Visual Studio y el SDK indicado para su versión.

A partir de este momento, estamos listos para comenzar a trastear con Sharepoint 🙂

¡Comencemos!

MAD.NUG: XRM: Una plataforma para unificarlas a todas

¿Qué es XRM? ¿Cómo puedo sacarle partido como herramienta de negocio? Estas preguntas y muchas más podremos discutir en el evento que se llevará a cabo el día 11 de Marzo en el edificio de Microsoft Ibérica en Madrid.

Gracias a la colaboración de Marco Amoedo, MVP de CRM, en Mad.Nug tendremos la posibilidad de conocer los conceptos básicos de XRM, técnicas de desarrollo, etcétera.

Para más información y acceder al registro tenemos el siguiente enlace.

¡Os esperamos!

Los elementos y eventos en Silverlight

Hace ya algunos días estuve definiendo el primer layout con Silverlight, donde teníamos una primera toma de contacto con XAML. En esta ocasión pretendo dar una visión un poco más amplia acerca de algunos de los elementos que podemos usar en el diseño de la UI y cómo es posible enlazar los eventos a los mismos.

Tenemos tres entornos a nuestra disposición a la hora de diseñar la interfaz de usuario con XAML:

  • Visual Studio 2008: Podemos utilizar la ventana de Herramientas (Toolbox) para arrastrar los elementos pero directamente en el código XAML. En esta versión de Visual Studio no tenemos vista de diseño para XAML.

    Por otro lado, existe la ventana Document Outline para poder visualizar el esquema de la página que estamos creando.

  • Visual Studio 2010: En la nueva versión de VS tenemos una vista previa del código XAML implementado, lo cual facilita bastante su codificación. Actualmente podemos hacer uso de la versión Release Candidate.

  • Expression Blend: Es la herramienta por excelencia para trabajar con las UI de Silverlight y WPF. Si bien para la creación de elementos nos podemos apañar con Visual Studio, en el caso de las animaciones la cosa resulta algo más compleja de realizar codificando.

    Desde Visual Studio podemos seleccionar cualquier archivo XAML y, con el botón derecho sobre él, podemos dar la orden de abrirlo en Expression Blend y poder trabajar de forma paralela con uno y otro (Expression Blend para el diseño y Visual Studio para el desarrollo).

ALGUNAS DIFERENCIAS RESPECTO A ASP.NET

  1. Para asignar un ID a un elemento utilizamos x:Name
  2. Si queremos posicionar un elemento dentro de un contenedor debemos tener en cuenta lo siguiente:
    1. Si estamos utilizando un contenedor de tipo Grid necesitamos establecer en primer lugar la estructura del mismo para poder posicionarlos dentro de él. De lo contrario no visualizaremos los elementos.
    2. Para los contenedores Canvas, podemos ubicarlos a través de Canvas.Top, Canvas.Left y Canvas.ZIndex.
    3. En el caso de los StackPanels, podemos apilar varios y darle una orientación horizontal o vertical al contenedor a través de la propiedad Orientation.
  3. En lugar de utilizar la propiedad Text para algunos controles como en Web Forms, para definir el texto que aparece en los elementos que lo requiera, utilizaremos Content.
  4. En ASP.NET la mayoría de los controles tienen un alto y ancho predeterminado que, en ocasiones, no es necesario alterar. En Silverlight es necesario especificarlo para obtener un tamaño considerable. Si no se especifica, se adaptará al tamaño del texto del Content si lo tiene.

ALGUNOS ELEMENTOS BÁSICOS

Al igual que en ASP.NET disponemos de elementos tales como :

Button

<Button x:Name="myButton" Content="Click me!" 
Canvas
.Left="100" Canvas.Top="120" Width="100" Height="25"></Button>

Textbox

<TextBox x:Name="myTextbox" Text="Write your name here" 
Canvas
.Left="100" Canvas.Top="150" Height="25"/>

Calendar

<controls:Calendar x:Name="myCalendar" Canvas.Left="280" Canvas.Top="120" 
ToolTipService
.ToolTip="Select your birthday" Cursor="Arrow"/>

Combobox

<ComboBox x:Name="myCombobox" Canvas.Left="100" Canvas.Top="195" Width="130"  >
<ComboBoxItem Background="#FF0200FF" Foreground="White" Content="Blue"/>
<ComboBoxItem Background="#FFFF0500" Foreground="White" Content="Red"/>
<ComboBoxItem Background="#FFFF00CA" Foreground="White" Content="Pink" IsSelected="True"/>
</ComboBox>

Listbox

<ListBox Canvas.Left="100" Canvas.Top="250" Width="130" >
<ListBoxItem Background="#FF0200FF" Foreground="White" Content="Blue"/>
<ListBoxItem Background="#FFFF0500" Foreground="White" Content="Red" IsSelected="True"/>
<ListBoxItem Background="#FFFF00CA" Foreground="White" Content="Pink" />
</ListBox>

Label

<dataInput:Label x:Name="myLabel" Content="Common Label" 
Canvas
.Left="100" Canvas.Top="80" Width="130" Height="24"/>

Radiobutton

<StackPanel Orientation="Vertical">
<RadioButton Margin="10,10,0,0" GroupName="Languages" Foreground="Blue" Content="C#"/>
<RadioButton Margin="10,10,0,0" GroupName="Languages" Foreground="Orange" Content="VB.NET"/>
<RadioButton Margin="10,10,0,0" GroupName="Languages" Foreground="Green" Content="Java"/>
<RadioButton Margin="10,10,0,0" GroupName="Languages" Foreground="Purple" Content="PHP"/>
</StackPanel>

Checkbox

<CheckBox x:Name="myCheckBox" Content="I want a million euros" 
Canvas
.Left="100" Canvas.Top="450"></CheckBox>

Datagrid

<data:DataGrid x:Name="myDataGrid" Height="105" 
Canvas.Left="100" Canvas.Top="345" ></data:DataGrid>

Para realizar la carga, en vez de utilizar DataSource sería ItemsSource.

public MainPage()
{
InitializeComponent();

var person = new Person { Name = "Gisela", LastName = "Torres", Location = "Madrid", Web = "http://geeks.ms/blogs/gtorres/" };
var persons = new List<Person> {person};
myDataGrid.ItemsSource = persons;
}

[…]

Existen más controles de los que aquí se indican y, además, podemos hacer uso de Silverlight Toolkit, de forma gratuita, descargándolo desde su sitio en Codeplex para ampliar el repertorio.

LOS EVENTOS EN SILVERLIGHT

Por último, para asociar un evento a un elemento de nuestra interfaz existen distintos procedimientos según el entorno:

Visual Studio 2008

Deberemos seleccionar el evento que necesitemos a través del Intellisense y, una vez añadido al elemento, nos dará la posibilidad de asociar uno existente o crear uno nuevo.

Visual Studio 2010

Si estamos trabajando con la vista previa, podemos hacer doble click sobre el elemento para autogenerar el evento click (De la misma forma que en Web Forms) o bien haciendo doble click sobre el evento que queramos en la ventana propiedades.

Expression Blend

En este último entorno, al igual que en Visual Studio 2010, disponemos de la pestaña Eventos dentro de propiedades del elemento seleccionando el icono que señalo en la imagen.

Hasta aquí la primera toma de contacto con los elementos XAML para Silverlight 🙂

¡Saludos!

Expresiones lambda

Dado que hoy en día lo que se estila es el uso de las expresiones lambda, voy a intentar resumir en un solo post qué son y cómo se utilizan. Sobre todo voy a procurar simplificarlo lo más posible 🙂

Las expresiones lambda se utilizan para crear funciones anónimas las cuales pueden ser asignadas a delegados o a árboles de expresión.

¿Por qué anónimas?

Porque no necesitamos asignarles un nombre para referirnos a ellas.

¿Qué es un delegado?

Es un objeto que hace referencia a uno o más métodos. Más información aquí.

¿Qué es un árbol de expresión?

Un árbol de expresión representa una estructura en forma de árbol de las expresiones lambda en memoria. Generalmente se potencia su uso en LINQ.

¿Cómo se utilizan?

Para saber cómo utilizar y/o leer una expresión lambda debemos tener en cuenta los siguientes puntos:

  • Parte izquierda: Representa los parámetros  que intervienen en la expresión.
  • Parte central: Se trata del operador lambda, necesario en todas las expresiones de este tipo.
  • Parte derecha: Se definen las acciones a realizar.

 

Puntos importantes:

  1. Las expresiones lambda no utiliza la instrucción return, excepto aquellas que utilicen un bloque encerrado entre llaves.
    suma = (a, b) =>
    {
    return a + b;
    };

  2. No es necesario especificar el tipo de los parámetros, ya que siempre van asociados a un delegado que ya contiene esta información.
    delegate string Delegado(int edad);

    [...]

    Delegado edad = e => string.Format("Tu edad es {0}", e);

  3. Se pueden usar tanto por delegados creados por nosotros como por aquellos definidos por el framework.
    <%= Html.TextBoxFor(m => m.Name) %>

LOS DELEGADOS GENÉRICOS: ACTION Y FUNC

Por otro lado, podemos utilizar los siguientes delegados genéricos en lugar de delegate. Con ellos conseguimos una sintaxis algo más refinada y simple.

Action se utiliza para aquellas expresiones lambda que no retornan ningún valor.

Action<string> saludo = s => Console.Write("Hola {0}!", s);
saludo("Gisela");

Func para aquellas expresiones que retornen un valor.

Func<int, int, int> suma = (a, b) => a + b;
int resultado = suma(3, 5);

Tanto en el caso de Func como en Action el número máximo de parámetros permitido es cuatro (Func figurará como cinco ya que el último es considerado el valor de retorno).

Espero que haya servido como una pequeña introducción al respecto 😉

¡Saludos!

¿Qué es ViewEngine en ASP.NET MVC?

Uno de los principales beneficios de crear una aplicación con ASP.NET MVC es que obtenemos mayor control en cuanto al código HTML se refiere. Aún así, es posible que al ver una vista generada para este patrón, resulte complicada la lectura para aquellos acostumbrados a trabajar con WebForms.

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<%
if (Request.IsAuthenticated) {
%>
Welcome <b><%= Html.Encode(Page.User.Identity.Name) %></b>!
[ <%= Html.ActionLink("Log Off", "LogOff", "Account") %> ]
<%
}
else {
%>
[ <%= Html.ActionLink("Log On", "LogOn", "Account") %> ]
<%
}
%>

Si bien este es un pequeño ejemplo del user control del LogOn que viene con la plantilla de ASP.NET MVC, la cosa se puede llegar a complicar bastante y puede dificultar su lectura y comprensión.

¿QUÉ ES VIEW ENGINE?

ASP.NET MVC utiliza un motor de vistas (View Engine) para reemplazar los métodos de renderizado de las aplicaciones por código HTML. Generalmente se está usando el proporcionado por ASP.NET MVC pero es posible utilizar otras alternativas creadas por la comunidad. Para ver un ejemplo de uno de los más conocidos, vamos a modificar una aplicación para utilizar Spark View Engine.

CONFIGURAR SPARK VIEW ENGINE

Nota: Para este ejemplo he utilizado una plantilla de ASP.NET MVC 1.0 ya que la versión actual de Spark no soporta ASP.NET MVC 2 RC 2.

La configuración es bastante simple. Para ello, debemos bajar la última versión del proyecto de CodePlex y adjuntar las siguientes librerías a nuestro proyecto:

Una vez que tenemos las librerías agregadas, necesitamos añadir Spark como motor de vistas a través del archivo Global.asax.

protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
ViewEngines.Engines.Add(new SparkViewFactory());
}

También es necesario generar un archivo donde especificamos las librerías necesarias para el renderizado. Este debe llamarse _global.spark y contedrá los siguientes assemblies (también puede definirse en el web.config).

<use namespace="System" />
<use namespace="System.Web.Mvc.Html" />
<use namespace="System.Collections.Generic" />
<use namespace="System.Linq" />

Esto sería lo mínimo necesario para comenzar a trabajar con Spark View Engine.

LAS VISTAS UTILIZANDO SPARK VIEW ENGINE

Para que el motor de Spark reconozca la vistas como suyas, es necesario que las mismas tengan extensión .spark. Una cosa importante a tener en cuenta es que la master page toma un nombre distinto: Application.spark.  Si modificamos la master page por defecto de la plantilla de ASP.NET MVC quedaría de la siguiente manera:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>
<use content="title">Default title</use>
</title>
<link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="page">
<div id="header">
<div id="title">
<h1>
My MVC Application</h1>
</div>
<div id="logindisplay">
<LogOnUserControl/>
</div>
<div id="menucontainer">
<ul id="menu">
<li>${Html.ActionLink("Home", "Index", "Home")}</li>
<li>${Html.ActionLink("About", "About", "Home")}</li>

</ul>
</div>
</div>
<div id="main">
<use content="view" />
<div id="footer">
</div>
</div>
</div>
</body>
</html>

Como diferencias podemos encontrar:

  1. Para declarar los ContentPlaceHolder utilizamos use content.
    <title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>

    <title>
    <use content="title">Default title</use>
    </title>

  2. Para incluir un control de usuario utilizamos tags con el nombre del mismo, por ejemplo <LogOnUserControl />
    <div id="logindisplay">
    <% Html.RenderPartial("LogOnUserControl"); %>
    </div>

    <div id="logindisplay">
    <LogOnUserControl/>
    </div>

  3. En cuanto al uso de helpers, variables y todo aquello relacionado con el servidor, podemos utilizarlo con la misma sintaxis que hasta ahora, a excepción de <% %>. Con Spark View Engine utilizaremos ${} 
    <ul id="menu">
    <li>${Html.ActionLink("Home", "Index", "Home")}</li>
    <li>${Html.ActionLink("About", "About", "Home")}</li>
    </ul>

Si queremos usar varias master pages en nuestra aplicación, basta con incluir la etiqueta <use master=»»/> en las vistas que lo requiera.

Los controles de usuarios también tienen extensión .spark y el nombre del archivo debe comenzar con guión bajo para ser reconocidos. Además es case sensitive cuando se utiliza el «modo tag»:

<LogOnUserControl />

Si no se tienen en cuenta estas dos indicaciones, no lo reconocerá y tampoco mostrará ningún tipo de error. Si quisieramos «traducir» el user control a lenguaje Spark quedaría de esta forma:

<if condition="Request.IsAuthenticated">
Welcome <b>${Context.User.Identity.Name}</b>!
[ !{Html.ActionLink("Log Off", "LogOff", "Account")} ]
</if>
<else>
[ !{Html.ActionLink("Log On", "LogOn", "Account")} ]
</else>

Podemos crear condiciones a través de tags e intercalar código HTML con código del servidor de una forma, quizás, más clara.

Por último, comentar que para el caso de las vistas no utilizamos un guión bajo  al inicio para el nombre del archivo y que la extensión sigue siendo .spark, al igual que el resto de archivos.

<content name="title">
Index
</content>
<h2>
Index</h2>
<p>
This is the Message in ViewData: ${ViewData["Message"]}</p>
<p>
${Html.ActionLink("About us", "About")}</p>
<p>
The time is ${DateTime.Now}.</p>

Además de Spark View Engine, disponemos de otros motores como pueden ser Brail, NVelocity, NHaml entre otros. A gusto del consumidor 😉

Adjunto el proyecto  por si fuera de utilidad.

¡Saludos!