[WP8] Silverlight para Windows Phone 8 (Parte I)

Silverlight es una poderosa plataforma de desarrollo para crear aplicaciones web y mobil que sean capaces de brindar una gran experiencia de usuario. En este vídeo veremos todo lo que nos ofrece Silverlight para el desarrollo de aplicaciones en Windows Phone 8 con ayuda de varios ejemplos.

Source Code: Xaml Development Codeplex

[Expression] ¿Como agregar fuentes a Expression Design?

Expression Design es una gran herramienta (al menos para las cosas que hago), pero como cualquier otra herramienta de diseño, no cuenta con todas las fuentes habidas y por haber del mundo, sin embargo es muy fácil poder modificar las fuentes que tiene. Y aquello lo logramos con los siguientes pasos:

Paso 1

Descargamos los archivos .otf o .ttf de la fuente que queremos. Por ejemplo aqui estoy descargando los correspondientes a Oswald desde Font Squirrel.

Paso 2

Simplemente hacemos doble click sobre el archivo deseado e instalamos.

Paso 3

Ubicamos la fuente ya sea en C:WindowsFonts ó Control PanelAppearance and PersonalizationFonts y anotamos los nombres que aparecen.

Paso 4

Finalmente nos vamos hacia donde esta instalado el Expression Design, especificamente a la carpeta PSI C:Program Files (x86)Microsoft ExpressionDesign 4PSI y modificamos (con persmisos administrativos en caso sea necesario) el archivo fonts.dat.

Paso 5

[WPF] Texblock versus Label

Si bien son elementos visuales muy similares (debido a que la mayoria de veces lo usan para lo mismo) estos en verdad difieren bastante. El Textblock aunque reside en el espacio de nombres System.Windows.Controls no hereda de ContentControl como sí lo hace el Label.
Si se nos ocurre explorar un poco más nos daremos cuenta que el Textblock no tiene la propiedad Template, por lo mismo que no hereda de Control, en cambio el Label si tiene:

            <Style TargetType="{x:Type Label}">
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Padding" Value="5"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Label}">
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="True">
<ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Entonces luego de saber esto podemos concluir algunas cosas:

  • Usando Label podemos mostrar más información que solo cadenas.
  • Se puede personalizar la plantilla del Label.
  • Podemos usar TemplateBinding usando Label.
  • Label es un control mucho mas pesado que el TextBlock.
  • No debemos usar Label a menos que realmente necesitos las funcionalidades que nos da.

[WP8] Fundamentos de Windows Phone 8

Windows Phone 8 llego un Octubre del 2012, y no ha dejado de ser una tecnología poderosa y en constante evolución. Es hora de poner manos a la obra, aprender y explotar todo lo que nos trae.

Con este video se abren las puertas a un curso para el Desarrollo de Apliaciones en Windows Phone 8 que constara aproximadamente de 8 modulos y que además cubrira el examen 70-599 Pro: Designing and Developing Windows Phone Applications.
En este modulo se mencionaran las mejoras o los cambios que nos trae Windows Phone 8 respecto a Windows Phone 7, ademas de señalar brevemente algunas de las nuevas capacidades y caracteristicas que seran de gran interes para los desarrolladores.

Source Code: Xaml Development Codeplex

[.NET] Enterprise Library Data Access Application Block

Enterprise Library Data Access Application Block es una API desarrollada por Microsoft, la cual facilita en muchas maneras el trabajo que tiene que realizar un programador para implementar una capa de Acceso a Datos.
En el siguiente video se explicaran sus fundamentos y se hará una demostración de como configurar las versiones 5 y 6 de esta API,además de realizar una demostración de como usarla.

Config v5:

Config v6:

Links:

[C#] Manejadores Globales de Excepciones

Los Manejadores Globales de Excepciones son eventos de System.Windows.Application (Windows.UI.Xaml.Application para Windows 8) que se disparan cada vez que se lanza un Exception y este no ha sido controlado por el código que se ejecuta en el hilo de ejecución principal, esto significa que si se produce alguna Excepcion en un subproceso no sera tomado en cuenta para este evento, para mayor información sobre subprocesos vease Modelo de subprocesos.


Tengamos en cuenta que para los distintos proyectos los encontramos de las siguientes maneras:

Windows Phone y Silverlight:

public event EventHandler<applicationunhandledexceptioneventargs> UnhandledException;

Windows Presentation Foundation:
public event DispatcherUnhandledExceptionEventHandler DispatcherUnhandledException;

Windows 8:
public event UnhandledExceptionEventHandler UnhandledException;

Para Windows Phone y Silverlight este evento ya viene manejado, sin embargo para WPF y Windows 8 hay que hacerlo por nuestra cuenta. Aca un ejemplo de donde se ubica en Windows Phone:

Implementando DispatcherUnhandledExceptionEventHandler

Cuando creamos nuestro proyecto WPF desde la plantilla WPF Application, nuestro App.xaml.cs se encuentra completamente vacio por asi decirlo, encontes lo que tenemos que hacer es simplemente dejarlo de la siguiente manera:

Y ahora hagamos algo simple como colocar int.Parse(“No olviden suscribirse a xamldevelopment.blogspot.com!”); en el constructor del MainWindow y se daran cuenta que la aplicación no se cae, en su lugar sale el mensaje de error. Ahora comenten el e.Handled = true; del App_DispatcherUnhandledException y ya entenderan como es que funciona esto.

[WP] Drag & Drop con MouseDragElementBehavior

Probablemente el Drag & Drop es una de las cosas mas divertidas y sencillas que se puede hacer con Silverlight, asi que en la presente entrada explicare como implementarlo.

Referencias

Empezamos agregando 2 referencias a nuestro proyecto: System.Windows.Interactivity y Microsoft.Expression.Interactions. Asegurense que ambas apunten a la misma versión.

XAML

Una vez que hemos hecho las referencias a las librerias previamente mencionadas, debemos agregarlas a nuestro XAML de la siguiente manera y adjuntar el comportamiento correspondiente que en este caso es MouseDragElementBehavior.

Pero para efectos practicos construyamos el XAML de la siguiente manera:


<Grid x:Name="LayoutRoot" Background="Transparent">
<Ellipse Width="180" Height="180" Fill="Azure">
<i:Interaction.Behaviors>
<ia:MouseDragElementBehavior DragFinished="MouseDragElementBehavior_DragFinished"/>
</i:Interaction.Behaviors>
</Ellipse>

<Rectangle x:Name="AnotherShape" Height="80" Width="80"
HorizontalAlignment="Left" VerticalAlignment="Bottom"
Fill="RoyalBlue" Margin="22" ></Rectangle>
<StackPanel VerticalAlignment="Bottom" HorizontalAlignment="Left" Margin="108,0,0,22">
<TextBlock Text="Relative to Rectangle"/>
<TextBlock>
<Run Text="Position X: "/>
<Run x:Name="txtRecPositionX"/>
</TextBlock>
<TextBlock>
<Run Text="Position Y: "/>
<Run x:Name="txtRecPositionY"/>
</TextBlock>
</StackPanel>

<StackPanel VerticalAlignment="Top" HorizontalAlignment="Left" Margin="22">
<TextBlock Text="Relative to Grid"/>
<TextBlock>
<Run Text="Position X: "/>
<Run x:Name="txtGridPositionX"/>
</TextBlock>
<TextBlock>
<Run Text="Position Y: "/>
<Run x:Name="txtGridPositionY"/>
</TextBlock>
</StackPanel>
</Grid>

C#

Ahora manejamos el evento e imprimimos la información más relevante la cual es su posición, demonos cuenta también que su posición es relativa a otro elemento, en este caso estamos imprimiendo su posición con respecto a 2 elementos: la grilla que contiene nuestra ellipse y un rectangulo que se encuentra dentro de la grilla también.


public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
}

private void MouseDragElementBehavior_DragFinished(object sender, MouseEventArgs e)
{
Point position = new Point();

//Relative to Grid
position = e.GetPosition(this.LayoutRoot);
this.txtGridPositionX.Text = position.X.ToString();
this.txtGridPositionY.Text = position.Y.ToString();

//Relative to Rectangle
position = e.GetPosition(this.AnotherShape);
this.txtRecPositionX.Text = position.X.ToString();
this.txtRecPositionY.Text = position.Y.ToString();
}
}

Solo C#

Si deseas hacer toda su implemetación usando solo C# lo logras de la siguiente manera:


using System.Windows;
using System.Windows.Input;
using Microsoft.Phone.Controls;
using Microsoft.Expression.Interactivity.Layout;

namespace PhoneApp3
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
Loaded += MainPage_Loaded;
}

private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
var mouseDragElement = new MouseDragElementBehavior();
mouseDragElement.DragFinished += MouseDragElementBehavior_DragFinished;
mouseDragElement.Attach(this.ellipse);
}

private void MouseDragElementBehavior_DragFinished(object sender, MouseEventArgs e)
{
Point position = new Point();

//Relative to Grid
position = e.GetPosition(this.LayoutRoot);
this.txtGridPositionX.Text = position.X.ToString();
this.txtGridPositionY.Text = position.Y.ToString();

//Relative to Rectangle
position = e.GetPosition(this.AnotherShape);
this.txtRecPositionX.Text = position.X.ToString();
this.txtRecPositionY.Text = position.Y.ToString();
}
}
}

Cabe indicar que aunque no se esta colocando using System.Windows.Interactivity, sí es importante referenciarla desde nuestro proyecto por que sin esta libreria no podriamos adjuntar ni usar ninguna clase que extienda de Behavior(en este caso MouseDragElementBehavior) ya que precisamente esta es la libreria que trae trae consigo la clase System.Windows.Interactivity.Behavior.

Valido para:

  • Silverlight 4.0, 5.0
  • Windows Phone 7.1, Windows 8.0
  • Windows Presentation Foundation

Otros enlaces:

[.NET] Enviar correos con System.Net.Mail

Aveces nos es necesario enviar correos desde alguna de nuestras aplicaciones, esto se puede lograr de muchas maneras, una de ellas por ejemplo seria usar el Database Mail del SQL Server, pero en esta ocasión se hara usando 2 clases que se encuentran en el namespace System.Net.Mail que son SmtpClient y MailMessage. Es una demo sencilla, basta entender la idea y se pueden hacer muchísimas cosas.

    class Program
{
static void Main(string[] args)
{
EnviarCorreo();
}

private static void EnviarCorreo()
{
//Configurando el cliente SMTP
SmtpClient client = new SmtpClient();
client.Host = "smtp.gmail.com";
client.Port = 587;
client.EnableSsl = true;
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.UseDefaultCredentials = false;
client.Credentials = new NetworkCredential("correoOrigen@gmail.com", "clavecorreoOrigen");
//Preparando archivo adjunto
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes("Contenido de un documento de texto muy interesante."));

//Enviando correo
MailMessage mail = new MailMessage();
mail.From = new MailAddress("correoOrigen@gmail.com");
mail.To.Add(new MailAddress("correoDestinatario@gmail.com"));
mail.Subject = "Correo simple de HTML con documento adjunto.";
mail.IsBodyHtml = true;
mail.Body = "<h2>Hola!</h2><br/><br/>Visiten: <a href='http://xamldevelopment.blogspot.com'>XAML Development</>";
mail.Attachments.Add(new Attachment(ms,"Documento.txt"));
client.Send(mail);
}
}

Actualización: 14 Abril 2014

Otra forma de configurar uno o más SmtpClient es usando el App.config o Web.config.

¿Cómo configurar un SmtpClient desde el .config?

Simplemente agregamos el siguiente código XML al nodo principal <configuration>:

App.config o Web.config

  <system.net>
<mailSettings>
<smtp deliveryMethod="Network" from="correoOrigen@gmail.com">
<network enableSsl="true" defaultCredentials="false" clientDomain="www.gmail.com" host="smtp.gmail.com" port="587" userName="correoOrigen@gmail.com" password="clavecorreoOrigen" />
</smtp>
</mailSettings>
</system.net>

CSharp

SmtpClient client = new SmtpClient();

Bastaría hacer lo anterior en C# y apreciar que los valores por defecto son los mismos que hemos establecido en el .config.

¿Cómo configurar más de un SmtpClient desde el .config?

En este caso debemos definir un section con su type por cada SmtpClient que queramos usar (en el ejemplo pondre 3), agruparlos en un sectionGroup (el cual llamaré mailingConfiguration, puede tener cualquier otro nombre) y luego establecer correctamente los valores (no es necesario que todos tengan el mismo clientDomain). Entonces, agreguemos el siguiente código XML al nodo principal <configuration> sin olvidar que configSections debe ser el primer elemento del nodo configuration sino no funcionaria:

App.config o Web.config

<configSections>
<sectionGroup name="mailingConfiguration">
<section name="cliente1" type="System.Net.Configuration.SmtpSection"/>
<section name="cliente2" type="System.Net.Configuration.SmtpSection"/>
<section name="cliente3" type="System.Net.Configuration.SmtpSection"/>
</sectionGroup>
</configSections>

<mailingConfiguration>
<cliente1 deliveryMethod="Network" from="correoOrigen1@gmail.com">
<network enableSsl="true" defaultCredentials="false" clientDomain="www.gmail.com" host="smtp.gmail.com" port="587" userName="correoOrigen1@gmail.com" password="clavecorreoOrigen1" />
</cliente1>
<cliente2 deliveryMethod="Network" from="correoOrigen2@gmail.com">
<network enableSsl="true" defaultCredentials="false" clientDomain="www.gmail.com" host="smtp.gmail.com" port="587" userName="correoOrigen2@gmail.com" password="clavecorreoOrigen2" />
</cliente2>
<cliente3 deliveryMethod="Network" from="correoOrigen3@gmail.com">
<network enableSsl="true" defaultCredentials="false" clientDomain="www.gmail.com" host="smtp.gmail.com" port="587" userName="correoOrigen3@gmail.com" password="clavecorreoOrigen3" />
</cliente3>
</mailingConfiguration>

CSharp

SmtpSection smtpSection = (SmtpSection)ConfigurationManager.GetSection("mailingConfiguration/cliente1");
SmtpClient smtpClient = new SmtpClient();
smtpClient.Host = smtpSection.Network.Host;
smtpClient.Port = smtpSection.Network.Port;
smtpClient.EnableSsl = smtpSection.Network.EnableSsl;
smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
smtpClient.UseDefaultCredentials = smtpSection.Network.DefaultCredentials;
smtpClient.Credentials = new NetworkCredential(smtpSection.Network.UserName, smtpSection.Network.Password);

Si bien estamos mapeando propiedad por propiedad desde el smtpSection la ventaja es que ahora lo tenemos todo centralizado desde el .config, no olviden agregar la referencia a System.Configuration.

Eso es todo amigos :)!

[Data Platform] Conectando Servicio de Base de Datos Azure

Ahora un simple paso a paso para conectarnos a nuestro servicio de datos en la nube de Microsoft, si aun no tienes una cuenta en Windows Azure puedes conseguir mayor información aqui http://www.windowsazure.com/en-us/

Entonces, luego de crear nuestro servicio de datos en Azure, por ejemplo:

Nos dirigimos a explorarlo y seguidamente seleccionamos 2 opciones:

Con la primera opción “Configurar reglas del firewall de Windows Azure para esta dirección IP” estamos indicando que nuestro servicio de datos puede ser accesible desde esta IP. Tambien se podria hacer desde el tab Panel con la opción “Administrar direcciones IP permitidas”:

Y con la segunda obtenemos las cadenas de conexión necesarias para conectarnos a nuestra base de datos en la nube. yyyyyyyyyy es el nombre de nuestro server, lo puse así para resaltar que es variable solo que menos obvia que el User ID. Ahora nos concentramos en la cadena de conexión para ADO.NET.

Seguido abrimos el Visual Studio y en el Explorador de Servidores (si no esta visible podemos activarlo en la barra de menu: View -> Server Explorer) en donde dice “Data Connections” o “Conexiones a Datos” hacemos click derecho y agregamos una conexión Microsoft SQL Server:

Ahora de acuerdo a nuestra cadena de conexión para ADO.NET (Server=tcp:yyyyyyyyyy.database.windows.net,1433;Database=MyAzureDatabase;User ID=s@a@yyyyyyyyyy; …) llenamos los datos como deben de ser y deberia aparecer nuestra base de datos en el combo:

Y listo una vez que lo reconoce significa que ya podemos consumir la información de nuestra bd de la forma que queramos usando aquella cadena de conexión.