[MATERIALES] Desarrollo en Windows Phone 7 con Silverlight

pc_logo_white

artaldelogowp7

Hola a todos!

Ayer día 14 tuvimos la charla sobre desarrollo en Windows Phone 7 con Silverlight donde vimos una pequeña introducción a la arquitectura interna de Windows Phone 7, como usar los sensores (acelerómetro, radio) acceder al almacenamiento local, realizar animaciones y compartir código entre Windows Phone 7, Silverlight y WPF.

Os dejo los materiales (demos y presentación) para que podáis revisarlos y jugar un poco con ellos.

Un saludo y Happy coding!

[EVENTO] Desarrollo en Windows Phone 7 con Silverlight

pc_logo_white

artaldelogowp7

Hola a todos!

El 14 de este mes voy a dar una charla en la universidad de Deusto sobre desarrollo Silverlight en Windows Phone 7.

Hablaremos un poco de la arquitectura del S.O., formas de acceder a recursos locales (hardware, almacenamiento) y algunas cosas más.

Aquí tenéis el link para registraros en el evento:

https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032472578&Culture=es-ES

Espero veros por allí, y que esta sea la primera de muchas otras!

Un saludo, Agur!

[WPF] Plantillas de datos dinámicas.

En muchas ocasiones podemos mostrar en una misma lista datos con diferentes significados o propiedades y podemos querer que sea fácil para el usuario distinguir entre los distintos tipos.

Por ejemplo, a la hora de mostrar una lista de los empleados de una empresa, tenemos diferentes puestos y habilidades, sería ideal que de un simple vistazo pudiésemos localizar los empleados que cumplen con lo que necesitamos para poder abrir su ficha y asignarles un trabajo.

En WPF podemos realizar esto de una forma bastante sencilla usando el interface IValueConverter y las clases DataTemplate y DataTemplateSelector.

IValueConverter

En muchas ocasiones el tipo de dato guardado en nuestra base de datos no es exactamente el mismo que deseamos presentar al cliente. Por ejemplo guardamos un código de país en nuestros datos pero queremos mostrar la bandera del país, no su código. También puede darse el caso de que queramos presentar sutiles diferencias entre diferentes valores de un campo, por ejemplo cambiando el color de letra o resaltando en negrita ante ciertos valores.

Esto, que se podría decir es una lógica de presentación propia de nuestros datos, podemos realizarlo de forma automática y muy sencilla con el interface IValueConverter, en tres pasos: Crear una clase que implemente el interface IValueConverter , referenciar esta clase como un recurso en nuestro XAML y usar la opción Converter en el binding de nuestro dato:

1º Crear una clase que implemente IValueConverter, debemos crear dos métodos Convert y ConvertBack:

class BoolToColorConverter : System.Windows.Data.IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, 
                            System.Globalization.CultureInfo culture)
    {
        bool Valor = (bool)value;

        if (Valor == true)
        {
            return new System.Windows.Media.SolidColorBrush(System.Windows.Media.Colors.Green);
        }
        else
        {
            return new System.Windows.Media.SolidColorBrush(System.Windows.Media.Colors.Red);
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, 
                                System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

 

En este ejemplo podemos ver un conversor que pasa un valor boolean a una interpretación en color (verde para verdadero, rojo para falso) con lo que conseguimos una interpretación visual más sencilla para el usuario. En la estructura de la clase que implementa el interface IValueConverter, los parámetros de ambos métodos son los mismos aunque su significado varía:

  • Convert:
    • Value: es un objeto con el valor de la propiedad original que queremos convertir.
    • targetType: es el tipo de la propiedad que queremos devolver.
    • parameter: un parámetro adicional que podemos enviar al método para la conversión.
    • culture: la cultura actual de la aplicación, para conversiones que puedan depender de ella.
  • ConvertBack:
    • Value: es un objeto con el valor de la propiedad que hemos convertido.
    • targetType: es el tipo de nuestra propiedad original.
    • parameter: un parámetro adicional que podemos enviar al método para la conversión.
    • culture: la cultura actual de la aplicación, para conversiones que puedan depender de ella.

2º Referenciar esta clase como un recurso en nuestro XAML:

Una vez creada nuestra clase deberemos referenciarla en XAML como un recurso para poder utilizarla.

Si no lo hemos hecho ya, primero deberemos referenciar nuestro namespace en el XAML:

xmlns:converters="clr-namespace:DynamicTemplates"

A continuación creamos un recurso con nuestro conversor:

<Window.Resources>
    <converters:BoolToColorConverter x:Key="ColorConverter"></converters:BoolToColorConverter>
</Window.Resources>  

Le asignamos una Key como a cualquier otro recurso para poder acceder más tarde a él.

3º Usamos nuestro conversor en la propiedad que queramos afectar.

Por ejemplo el Foreground de un TextBlock enlazado a una propiedad Disponible de nuestras clases de datos:

<TextBlock Name="txtDisponibilidad" 
            Foreground="{Binding Path=Disponibilidad,
                                Converter={StaticResource ColorConverter}}" 
            Text="{Binding Path=UserName}" Margin="0,0,192,285">
</TextBlock>

Con esto, cuando la propiedad Disponibilidad tenga el valor True, el Foreground será verde, mientras que cuando tenga el valor False será rojo:

imageimage

DataTemplate

Ahora que ya sabemos como modificar valores para presentarlos de formas diferentes a como se representarían de forma normal, vamos a ver como modificar el aspecto general de nuestros datos en un control de lista, por ejemplo, un ListBox o un ComboBox, creando una plantilla visual específica que muestre nuestros datos al usuario de forma más atractiva y más sencilla para su entendimiento.

Esta operación se realiza en dos pasos: Definir nuestro DataTemplate y asignarlo al control que queramos que lo use.

1º Definir nuestro DataTemplate

En XAML debemos especificar un DataTemplate como recurso, y dentro de este, crear el árbol visual que compondrá a los Items de nuestra lista. De esta forma una vez que especifiquemos al control de lista el DataTemplate que queremos que use, se encargará de formatear nuestros datos visualmente como le hayamos indicado. Vamos a Crear una plantilla sencilla, que muestre los datos de un empleado usando un estilo de tarjeta de visita:

<DataTemplate x:Key="MiTemplate">
    <Grid Height="74" Width="250" HorizontalAlignment="Stretch" Margin="5">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="64"></ColumnDefinition>
            <ColumnDefinition Width="*"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height=".3*"></RowDefinition>
            <RowDefinition Height=".3*"></RowDefinition>
            <RowDefinition Height=".3*"></RowDefinition>
        </Grid.RowDefinitions>
        <Border Grid.ColumnSpan="2" Grid.RowSpan="3" BorderBrush="Black" BorderThickness="2" CornerRadius="5">
            <Border.Background>
                <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                    <GradientStop Offset="0" Color="White"></GradientStop>
                    <GradientStop Offset="1" Color="LightGray"></GradientStop>
                </LinearGradientBrush>
            </Border.Background>
        </Border>
        <Image Name="imgUserPhoto" Grid.Column="0" Grid.RowSpan="3" Margin="10" Source="{Binding Path=UserPhotoFile}"></Image>
            
        <TextBlock Name="tblUserName" Grid.Column="1" Grid.Row="0" 
                    FontSize="14" FontWeight="Bold"
                    HorizontalAlignment="Left" VerticalAlignment="Center"
                    Text="{Binding Path=UserName}">
        </TextBlock>
        <TextBlock Name="tblUserFullName" Grid.Column="1" Grid.Row="1" 
                    HorizontalAlignment="Left" VerticalAlignment="Center"
                    Text="{Binding Path=UserFullName}">
        </TextBlock>
        <TextBlock Name="tblUserArea" Grid.Column="1" Grid.Row="2" 
                    HorizontalAlignment="Left" VerticalAlignment="Center"
                    Text="{Binding Path=UserArea}">
        </TextBlock>
    </Grid>
</DataTemplate>

Dentro de la propia DataTemplate hemos incluido los Bindings a las propiedades para cada control, al insertar la plantilla en cada Item, el DataContext que usará será el de la ventana que lo contenga.

2º Asignarlo al control

Una vez que hemos creado nuestra DataTemplate y le hemos asignado un nombre (x:Key) simplemente tenemos que especificar la propiedad ItemTemplate en el control que queremos que use nuestra plantilla, apuntando hacia el nombre de la misma:

<ListBox Name="lstUsers" Margin="0,10,0,10" 
            HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
            ItemTemplate="{StaticResource MiTemplate}"
</ListBox>  

Como puedes ver simplemente hemos definido un Layout de elementos, usando una grid, un Border, un Image y varios Textblocks para mostrar los datos, en vez de uno al lado del otro como se hacia tradicionalmente, en forma de ficha o tarjeta, y después hemos indicado a nuestro ListBox que use este Layout, por medio de la propiedad ItemTemplate. El resultado al enlazar con datos sería este:

image

Como puedes ver, es mucho más atractivo que simplemente mostrar la información del usuario en una línea solo con texto.

DataTemplateSelector

Bien, ya hemos visto como usar el interface IValueConverter para cambiar la apariencia visual de nuestros datos y como usar la clase DataTemplate para personalizar el árbol visual de nuestros controles de listas.

Pero, que pasa si, siguiendo el ejemplo anterior de la lista de empleados, tenemos diferentes perfiles de empleados, con diferentes habilidades y queremos que sea más sencillo distinguir entre tipos de empleados y entre habilidades de los mismos? Bueno podríamos usar clases con el interface IValueConverter para mostrar, ocultar datos o modificar colores… Pero eso nos exigiría tener varias clases para poder personalizar la plantilla. ¿Que tal si pudiésemos tener varias DataTemplate independientes y la lista fuese capaz, en base a los datos de cada Item, elegir cual es la que debe aplicar? Eso podemos realizarlo con la clase DataTemplateSelector en tres sencillos pasos: crear las plantillas que queramos usar, crear una clase que herede de DataTemplateSelector y establecer la propiedad ItemTemplateSelector de nuestro control de lista.

1º Crear las plantillas que queramos usar

En nuestro ejemplo anterior hemos creado una plantilla para mostrar datos de usuarios, ahora vamos a crear dos más, una específica para desarrolladores y otra para diseñadores, dejando la que hemos creado anteriormente para directores.

<DataTemplate x:Key="TemplateDevelopers">
    <Grid Height="74" Width="250" HorizontalAlignment="Stretch" Margin="5">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="64"></ColumnDefinition>
            <ColumnDefinition Width="*"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height=".25*"></RowDefinition>
            <RowDefinition Height=".25*"></RowDefinition>
            <RowDefinition Height=".25*"></RowDefinition>
            <RowDefinition Height=".25*"></RowDefinition>                
        </Grid.RowDefinitions>
        <Border Grid.ColumnSpan="2" Grid.RowSpan="4" BorderBrush="DarkBlue" BorderThickness="2"  CornerRadius="5">
            <Border.Background>
                <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                    <GradientStop Offset="0" Color="Azure"></GradientStop>
                    <GradientStop Offset="1" Color="LightBlue"></GradientStop>
                </LinearGradientBrush>
            </Border.Background>
        </Border>
        <Image Name="imgUserPhoto" Grid.Column="0" Grid.RowSpan="4" Margin="10" Source="{Binding Path=UserPhotoFile}"></Image>

        <TextBlock Name="tblUserName" Grid.Column="1" Grid.Row="0" 
                    FontSize="14" FontWeight="Bold"
                    HorizontalAlignment="Left" VerticalAlignment="Center"
                    Text="{Binding Path=UserName}">
        </TextBlock>
        <TextBlock Name="tblUserFullName" Grid.Column="1" Grid.Row="1" 
                    HorizontalAlignment="Left" VerticalAlignment="Center"
                    Text="{Binding Path=UserFullName}">
        </TextBlock>
        <TextBlock Name="tblUserArea" Grid.Column="1" Grid.Row="2" 
                    HorizontalAlignment="Left" VerticalAlignment="Center"
                    Text="{Binding Path=UserArea}">
        </TextBlock>
        <TextBlock Name="tblDevLanguaje" Grid.Column="1" Grid.Row="3" 
                    HorizontalAlignment="Left" VerticalAlignment="Center"
                    Text="{Binding Path=DevLang}" FontWeight="Bold"
                    Foreground="{Binding Path=DevLang,Converter={StaticResource DevConv}}">
        </TextBlock>
    </Grid>
</DataTemplate>

<DataTemplate x:Key="TemplateDesigners">
    <Grid Height="74" Width="250" HorizontalAlignment="Stretch" Margin="5">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="64"></ColumnDefinition>
            <ColumnDefinition Width="*"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height=".25*"></RowDefinition>
            <RowDefinition Height=".25*"></RowDefinition>
            <RowDefinition Height=".25*"></RowDefinition>
            <RowDefinition Height=".25*"></RowDefinition>
        </Grid.RowDefinitions>
        <Border Grid.ColumnSpan="2" Grid.RowSpan="4" BorderBrush="LimeGreen" BorderThickness="2"  CornerRadius="5">
            <Border.Background>
                <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                    <GradientStop Offset="0" Color="LightYellow"></GradientStop>
                    <GradientStop Offset="1" Color="LightGreen"></GradientStop>
                </LinearGradientBrush>
            </Border.Background>
        </Border>
        <Image Name="imgUserPhoto" Grid.Column="0" Grid.RowSpan="4" Margin="10" Source="{Binding Path=UserPhotoFile}"></Image>

        <TextBlock Name="tblUserName" Grid.Column="1" Grid.Row="0" 
                    FontSize="14" FontWeight="Bold"
                    HorizontalAlignment="Left" VerticalAlignment="Center"
                    Text="{Binding Path=UserName}">
        </TextBlock>
        <TextBlock Name="tblUserFullName" Grid.Column="1" Grid.Row="1" 
                    HorizontalAlignment="Left" VerticalAlignment="Center"
                    Text="{Binding Path=UserFullName}">
        </TextBlock>
        <TextBlock Name="tblUserArea" Grid.Column="1" Grid.Row="2" 
                    HorizontalAlignment="Left" VerticalAlignment="Center"
                    Text="{Binding Path=UserArea}">
        </TextBlock>
        <TextBlock Name="tblDesignEnvironment" Grid.Column="1" Grid.Row="3" 
                    HorizontalAlignment="Left" VerticalAlignment="Center"
                    Text="{Binding Path=DesEnv}" FontWeight="Bold"
                    Foreground="{Binding Path=DesEnv,Converter={StaticResource DesConv}}">
        </TextBlock>
    </Grid>
</DataTemplate>

Estas plantillas son muy parecidas a la primera, hemos añadido una fila más de información con el lenguaje de desarrollo o software de diseño que mejor usa el empleado y en este texto hemos usado un converter para modificar el color del texto dependiendo del texto en cuestión.

2º Crear una clase que herede de DataTemplateSelector

La clase DataTemplateSelector se encuentra en el namespace System.Windows.Controls, tenemos que sobreescribir el método SelectTemplate, que toma dos parámetros item (el item actual de la lista) y container (el objeto en cuestión que contiene nuestro item), debemos devolver el DataTemplate a aplicar en este item en concreto:

class UsersTemplateSelector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        if (item != null && item is UserClass)
        {
            UserClass Usuario = item as UserClass;
            switch (Usuario.UserArea)
            {
                case "director":
                    {
                        return App.Current.Resources["TemplateDirectors"] as DataTemplate;
                    }
                case "developer":
                    {
                        return App.Current.Resources["TemplateDevelopers"] as DataTemplate;
                    }
                case "designer":
                    {
                        return App.Current.Resources["TemplateDesigners"] as DataTemplate;
                    }
                default:
                    {
                        return App.Current.Resources["TemplateDirectors"] as DataTemplate;
                    }
            }
        }

        return null;
    }

}

Es muy sencillo, simplemente convertimos el item a una instancia de nuestra clase UserClass que es la que está enlazada a la lista y usamos el campo UserArea para saber que plantilla debemos devolver, luego como nuestras plantillas están definidas en un ResourceDictionary añadido a nuestro app.xaml simplemente buscamos el recurso y lo convertimos a un DataTemplate para devolverlo.

3º Establecer la propiedad ItemTemplateSelector de nuestro control de lista

Una vez que tenemos nuestra clase creada, debemos referenciarla como un recurso de XAML, añadiendo primero el namespace donde se encuentra a la ventana o usercontrol:

xmlns:cls="clr-namespace:DynamicTemplates"

Y creando después un recurso con nuestra clase de selección de plantillas:

<Window.Resources>
    <cls:UsersTemplateSelector x:Key="TempSelector"></cls:UsersTemplateSelector>
</Window.Resources>

Una vez hecho esto, debemos eliminar la propiedad ItemTemplate de nuestro control de listas y sustituirla por la propiedad ItemTemplateSelector apuntando a nuestro nuevo recurso de selección de plantillas:

<ListBox Name="lstUsers" Margin="0,10,0,10" 
            HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
            ItemTemplateSelector="{StaticResource TempSelector}">
</ListBox>

Una vez terminado todo, si añadimos distintos tipos de usuarios a la colección y ejecutamos tendremos un resultado parecido a este:

image

Como podemos ver cada tipo de usuario ha usado una plantilla diferente y además usando las clases que implementan IValueConverter hemos cambiado el color del texto de algunas opciones dependiendo del valor del texto.

De esta manera es muy fácil saber cuantos diseñadores tenemos disponibles o ver que hay menos directores disponibles que el resto de tipos de empleados, sin tener que leer o buscar de forma más complicada y , por supuesto, nuestro interface de usuario es mucho más agradable que una simple lista de texto en líneas.

Conclusión

Espero que os haya parecido instructivo este pequeño artículo y que podáis dotar de mayor dinamismo a vuestras aplicaciones WPF a la hora de mostrar datos al usuario, la era de las listas de texto en filas interminables ha terminado, tenemos el poder de cambiar la forma en la que los usuarios consumen datos, y podemos hacer que sea más sencillo y agradable.

Os dejo el proyecto para descarga y como siempre, estoy a vuestra entera disposición para cualquier cosa que necesitéis, duda, crítica, sugerencia o simplemente tomar un café y conocernos!

Un saludo a todos, gracias por leerme y HAPPY CODING!

Compartiendo Código: Móvil + Web + Escritorio (2/2)

Hola a todos, por fin he encontrado un momento para poder acabar mi entrada sobre MVVM y compartir código.

Antes que nada, os dejo el enlace a la 1º parte por si no lo habéis visto, para poneros en situación:

Compartiendo Código: Móvil + Web + Escritorio (1/2)

Vamos al toro, empecemos por ver que son los comandos en WPF/Silverlight

Comandos

Los comandos son mecanismos de ejecución de nuestro código que reemplazan a los tradicionales eventos para conseguir algo fundamental en MVVM: Separar la lógica de visualización de la visualización en si misma.

Para crear un nuevo comando, solo debemos crear una nueva clase que implemente la interface ICommand (System.Windows.Input):

class HelloCommand : ICommand
{
    public event EventHandler CanExecuteChanged;

    public bool CanExecute(object parameter)
    {
        CanExecuteChanged(this, EventArgs.Empty);
        return true;
    }
    public void Execute(object parameter)
    {
        MessageBox.Show("Hola");
    }
}

Una vez hecho esto, referenciamos esta nueva clase en xaml y la añadimos como un recurso:

xmlns:comando="clr-namespace:WpfApplication1"
<Window.Resources>
    <comando:HelloCommand x:Key="Hello"></comando:HelloCommand>
</Window.Resources>

Si añadimos un nuevo botón a nuestra ventana veremos que una de sus propiedades se llama Command, simplemente debemos añadir un Binding estático a nuestra clase:

<Button Content="Button" Height="23" HorizontalAlignment="Left" 
        Margin="119,63,0,0" Name="button1" VerticalAlignment="Top" 
        Width="75" Command="{Binding Source={StaticResource Hello}}" />

Al ejecutar nuestra aplicación veremos que presionando el botón aparece el cuadro de mensajes que hemos definido en nuestro comando.

El método CanExecute controla si nuestro comando se puede ejecutar, si devuelve False, el control asociado al evento se desactivará automáticamente.

De todas formas, crear una clase para cada acción que queramos realizar en nuestra aplicación puede ser largo y complicado de mantener, para evitar esto podemos crear una clase que centralice la infraestructura del comando y, ya en cada clase de nuestro ViewModel crear variables públicas de tipo ICommand que usarán esa infraestructura y métodos que serán ejecutados:

class RelayCommand : ICommand
{
    private Action handler;
    private bool _IsEnabled;

    //Constructor
    public RelayCommand(Action _handler)
    {
        handler = _handler;
    }
    //Determina si el comando se puede ejecutar y desactiva o activa los controles asociados.
    public bool IsEnabled
    {
        get { return _IsEnabled; }
        set
        {
            if (value != _IsEnabled)
            {
                _IsEnabled = value;
                if (CanExecuteChanged != null)
                {
                    CanExecuteChanged(this, EventArgs.Empty);
                }
            }
        }
    }
    //Llamada desde WPF, le indica si el comando se puede ejecutar, no la llamamos directamente nosotros.
    public bool CanExecute(object parameter)
    {
        return IsEnabled;
    }
    public event EventHandler CanExecuteChanged;
    //Ejecuta la acción indicada en la variable handler.
    public void Execute(object parameter)
    {
        handler();
    }
}

Esta clase es muy sencilla, implementa los mismos métodos de ICommand , simplemente en el constructor le pasamos el método a ejecutar y usamos su propiedad pública IsEnabled para establecer si está o no habilitado el comando.

 

Compartiendo Código

Vamos a empezar con la parte divertida, todo esto que hemos contado está muy bien MVVM, Comandos, desacoplar la lógica visual de la capa visual propiamente dicha… pero ¿para que nos puede servir?

Pues nos puede servir para hacer una aplicación WPF, Silverlight y WP7 que compartan TODO su código de presentación, a parte del xaml que obviamente hay que tener en cada proyecto.

¿Como? Vamos a verlo.

Para hacer un ejemplo sencillo he elegido el servicio http://is.gd un acortador de direcciones muy sencillo de implementar por código. Lo primero que tenemos que hacer es crear una nueva solución de Visual Studio 2010 vacía y agregar 4 proyectos: un proyecto WPF, un proyecto Silverlight, un proyecto Silverlight for Windows Phone 7 y una librería de clases. Al terminar debería tener algo así:

image

Vamos a empezar a trabajar con la librería de clases, añade una nueva clase que se llame RelayCommand y pon el siguiente código, será la encargada de soportar la infraestructura de nuestros comandos (debes añadir un using System.Windows.Input al archivo):

private Action handler;
private bool _IsEnabled;

//Constructor
public RelayCommand(Action _handler)
{
    handler = _handler;
}
//Determina si el comando se puede ejecutar y desactiva o activa los controles asociados.
public bool IsEnabled
{
    get { return _IsEnabled; }
    set
    {
        if (value != _IsEnabled)
        {
            _IsEnabled = value;
            if (CanExecuteChanged != null)
            {
                CanExecuteChanged(this, EventArgs.Empty);
            }
        }
    }
}
//Llamada desde WPF, le indica si el comando se puede ejecutar, no la llamamos directamente nosotros.
public bool CanExecute(object parameter)
{
    return IsEnabled;
}
public event EventHandler CanExecuteChanged;
//Ejecuta la acción indicada en la variable handler.
public void Execute(object parameter)
{
    handler();
}

Una vez hecho esto, vamos a añadir otra clase, que será nuestro ViewModel, llamada URLShortenerViewModel, debe implementar el interface INotifyPropertyChanged:

//Class constructor.
public URLShortenerViewModel()
{
    _ShortURLCommand = new RelayCommand(ShortURLMethod) { IsEnabled = false };
}

//Private state variables.
private string _originalurl = string.Empty;
private string _shortenedurl = string.Empty;

//Public properties for binding.
public string OriginalURL
{
    get { return _originalurl; }
    set
    {
        _originalurl = value;
        OnPropertyChanged("OriginalURL");

        if (String.IsNullOrEmpty(_originalurl))
        {
            (ShortURLCommand as RelayCommand).IsEnabled = false;
        }
        else
        {
            (ShortURLCommand as RelayCommand).IsEnabled = true;
        }
    }
}

public string ShortenedURL
{
    get { return _shortenedurl; }
    set
    {
        _shortenedurl = value;
        OnPropertyChanged("ShortenedURL");
    }
}

//Change Notifications
public event PropertyChangedEventHandler PropertyChanged;

protected void OnPropertyChanged(String propertyName)
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

//Comand to short URL
private readonly ICommand _ShortURLCommand;

public ICommand ShortURLCommand
{
    get { return _ShortURLCommand; }
}

public void ShortURLMethod()
{
    String url = OriginalURL;
    url = Uri.EscapeUriString(url);
    ShortenedURL = string.Empty;
    url = String.Format(@"http://is.gd/api.php?longurl={0}", url);
    WebClient peticionUrl = new WebClient();
    peticionUrl.DownloadStringCompleted += DownloadComplete;
    peticionUrl.DownloadStringAsync(new Uri(url));
}

private void DownloadComplete(object sender, DownloadStringCompletedEventArgs e)
{
    if (e.Error != null)
    {
        throw e.Error;
    }
    if (e.Result != null)
    {
        ShortenedURL = e.Result;
    }
}

Con esto ya tenemos nuestro ViewModel terminado, y con el hemos terminado TODO el código necesario para nuestras 3 aplicaciones, vamos a diseñar cada una de ellas.

 

Aplicación WPF

Lo primero que tenemos que hacer es añadir una referencia en nuestro proyecto WPF a nuestro ViewModel, despues de esto solo tenemos que añadir en MainWindow.xaml una referencia a nuestra clase URLShortenerViewModel:

xmlns:viewmodel="clr-namespace:URLShortenerViewModel;assembly=URLShortenerViewModel"

Y tras eso, usar nuestro ViewModel como el DataContext de la ventana:

<Window.DataContext>
    <viewmodel:URLShortenerViewModel></viewmodel:URLShortenerViewModel>
</Window.DataContext>

Ahora solo tenemos que diseñar la pantalla, es muy sencilla, un textbox para la url original, un botón que la acorte y un textbox para la url corta:

image

<StackPanel x:Name="LayoutRoot" Background="White">
    <TextBlock Text="Original URL:" Margin="5"></TextBlock>
    <TextBox Height="23" HorizontalAlignment="Stretch" Margin="5" Name="txtOriginalURL" VerticalAlignment="Top" Width="Auto" 
                Text="{Binding Path=OriginalURL,Mode=TwoWay}" />
    <Button Content="Short IT!" Height="23" HorizontalAlignment="Stretch" Margin="5" Name="button1" VerticalAlignment="Top" Width="Auto" 
            Command="{Binding ShortURLCommand}" />
    <TextBlock Text="Shortened URL:" Margin="5"></TextBlock>
    <TextBox Height="23" HorizontalAlignment="Stretch" Margin="5" Name="txtShortenedURL" VerticalAlignment="Top" Width="Auto" 
                Text="{Binding Path=ShortenedURL,Mode=TwoWay}" />
</StackPanel>

Aquí es donde el enlace a datos de WPF entra en acción, simplemente enlazamos los textbox a las propiedades de nuestro ViewModel usando el modo bidireccional y enlazamos el botón a nuestro comando.

Ya no tenemos nada más que hacer, si ejecutamos el proyecto y escribimos una url en el cuadro superior, el botón se activará automáticamente al salir el foco del textbox y al pulsarlo obtendremos nuestra url acortada totalmente funcional.

 

Aplicación Silverlight

Con Silverlight las cosas se nos complican un poco, ya que no podemos añadir una referencia a nuestra librería de clases directamente, y si copiásemos las clases RelayCommand y URLShortenerViewModel, sería un infierno mantener dos veces el mismo código, además de que es precisamente lo que queremos evitar.

Para solucionar esto, Visual Studio nos permite hacer algo muy util, a la hora de añadir un elemento existente a un proyecto la ventana que sale es la siguiente:

image

El truco se encuentra en la flecha del botón abrir, si la pulsamos tendremos dos opciones: Add que es el comportamiento por defecto y Add as a Link que es el que nos interesa, Add as a Link añade una referencia al archivo seleccionado, pero no mueve el archivo a nuestro proyecto, podemos realizar cambios en el archivo desde nuestro proyecto y se reflejarán en el original o cambios en el original y se reflejarán en el nuestro, problema resuelto. usando Add as a Link navega hasta la carpeta de la librería de clases y añade los dos archivos .cs RelayCommand.cs y URLShortenerViewModel.cs.

Ya solo nos queda realizar las mismas modificaciones en el xaml que ya hicimos en la aplicación WPF y nuestra aplicación Silverlight estará lista y funcional:

xmlns:viewmodel="clr-namespace:URLShortenerViewModel"
<UserControl.DataContext>
    <viewmodel:URLShortenerViewModel></viewmodel:URLShortenerViewModel>
</UserControl.DataContext>
<StackPanel x:Name="LayoutRoot" Background="White">
    <TextBlock Text="Original URL:" Margin="5"></TextBlock>
    <TextBox Height="23" HorizontalAlignment="Stretch" Margin="5" Name="txtOriginalURL" VerticalAlignment="Top" Width="Auto" 
                Text="{Binding Path=OriginalURL,Mode=TwoWay}" />
    <Button Content="Short IT!" Height="23" HorizontalAlignment="Stretch" Margin="5" Name="button1" VerticalAlignment="Top" Width="Auto" 
            Command="{Binding ShortURLCommand}" />        
    <TextBlock Text="Shortened URL:" Margin="5"></TextBlock>
    <TextBox Height="23" HorizontalAlignment="Stretch" Margin="5" Name="txtShortenedURL" VerticalAlignment="Top" Width="Auto" 
                Text="{Binding Path=ShortenedURL,Mode=TwoWay}" />
</StackPanel>

Como podéis ver el xaml es idéntico, salvo que en el caso de Silverlight trabajamos en un UserControl y en el caso de WPF con una Window. Si ejecutáis veréis que el comportamiento es el mismo que el de la aplicación WPF, ya tenemos nuestra aplicación lista para usarse desde escritorio y desde internet, ¿Que tal si también la ponemos en nuestras manos con Windows Phone 7? Vamos a ello.

Aplicación Windows Phone 7

Quizás la versión de Windows Phone 7 es la más problemática, por una simple razón: los comando fueron introducidos en Silverlight en la versión 4.0, como WP7 usa Silverlight 3.0 con algunas mejoras, los comandos no están disponibles desde xaml.

Pero siempre hay formas de hacer las cosas, aunque en este caso necesitaremos 1 evento y 2 líneas de C# para llevar nuestra idea a buen puerto. Lo primero es repetir los mismos pasos que en la aplicación Silverlight, añadimos como enlaces (Add as a Link) las clases de nuestro ViewModel y las referenciamos en xaml, añadimos los controles, con la diferencia de que en el botón especificamos un manejador de eventos para el evento Click:

xmlns:viewmodel="clr-namespace:URLShortenerViewModel"
<phone:PhoneApplicationPage.DataContext>
    <viewmodel:URLShortenerViewModel></viewmodel:URLShortenerViewModel>
</phone:PhoneApplicationPage.DataContext>
<StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <TextBlock Text="URL Original:"></TextBlock>
    <TextBox Height="72" Name="txtOriginalURL"  Text="{Binding Path=OriginalURL,Mode=TwoWay}" VerticalAlignment="Top" />
    <Button Content="Short IT!" Height="72" HorizontalAlignment="Stretch" Name="button2" VerticalAlignment="Top"  
            Click="button1_Click"  />            
    <TextBlock Text="URL Acortada:"></TextBlock>
    <TextBox Height="72" Name="txtShortenedURL"  Text="{Binding Path=ShortenedURL,Mode=TwoWay}" VerticalAlignment="Top" />
</StackPanel>

 

Ahora en el code behind MainPage.xaml.cs en el evento Click vamos a invocar manualmente a nuestro comando:

private void button1_Click(object sender, RoutedEventArgs e)
{
    URLShortenerViewModel.URLShortenerViewModel vm = (URLShortenerViewModel.URLShortenerViewModel)this.DataContext;
    vm.ShortURLCommand.Execute(null);
}

 

No mentía, solo hemos necesitado dos líneas de código para resolver el problema. Lo único que perdemos es la desactivación automática del botón, al no estar enlazado al comando, a cambio de esto gracias a dos líneas tenemos la misma lógica de presentación que nuestras aplicaciones en WPF y Silverlight.

Si ejecutas la aplicación Windows Phone 7 verás que funciona igual de bien que las otras dos.

Conclusión

Las posibilidades de integración y reutilización de código que nos ofrece MVVM junto con .NET 4 WPF, Silverlight y Windows Phone 7 son enormes, podremos transformar aplicaciones de escritorio en aplicaciones móviles o web con una rapidez nunca vista hasta ahora.

Espero que os haya parecido instructivo, espero vuestros comentarios, criticas y sugerencias para seguir mejorando con vosotros día a día. También os dejo el código fuente de una solución con todos los proyectos funcionando perfectamente por si queréis echarle un vistazo y ya sabéis que ando por los foros de MSDN y por twitter (@JosueYeray) para lo que os haga falta.

Un gran saludo y Happy Coding!

[OT] Cambio de Aires

Hola a todos!

Hoy es mi último día de trabajo en mi actual empresa, Intrasoft, a partir del 4 de Noviembre pasaré a formar parte del equipo de Plain Concepts Bilbao!!

Es un cambio brutal en mi vida, dejo en Intrasoft grandes compañeros que me han ayudado a llegar donde estoy hoy, a Victor, Ivan, Ciani, Alberto, Francisco muchas gracias. También dejo un gran jefe, Fran, que me ha ayudado en todo momento. Todos se han convertido en amigos más que compañeros y jefes, y sin duda les extrañaré mucho… a todos GRACIAS AMIGOS!

staré lejos de mi familia durante un tiempo, mi mujer e hijos que me han ayudado en todo este cambio, gr.

Gracias a Rodrigo, Ibon e Iker de Plain Concepts Bilbao por creer en mi y darme esta oportunidad, no os defraudaré!!!!

Plain Concepts Bilbao…. Alla voy!!!!!

Compartiendo Código: Móvil + Web + Escritorio (1/2)

Introducción

Desde hace mucho tiempo, una de las principales preocupaciones de todo programador es la reutilización del código escrito a través de distintos proyectos.

Hasta hace relativamente poco, un proyecto en el que tuviesemos que realizar aplicaciones de escritorio (Windows forms), web (asp.net) y móvil (compact framework) requería reescribir en cada proyecto gran parte de nuestro código, salvando la lógica de negocio y acceso a datos, casi todo lo demás se escribía en exclusiva para cada plataforma.

Con las nuevas tecnologías de desarrollo a nuestro alcance (WPF, Silverlight, Silverlight Mobile) y haciendo uso del patrón MVVM este escenario cambia radicalmente, pudiendo compartir y reutilizar la mayoría de nuestro código entre los distintos tipos de aplicaciones.

A esta reutilización más eficiente de nuestro código debemos añadir el hecho de que, al independizar nuestro código de nuestra capa de visualización, el trabajo de Unit Testing se simplifica en gran manera.

¿Que es MVVM?

MVVM es un patrón de diseño creado por Jhon Grossman, uno de los arquitectos de WPF en Microsoft y desvelado por primera vez en 2005.

Este patrón se compone del Model, la representación de nuestros datos, el ViewModel, un adaptador intermedio que hace nuestro modelo apto para ser consumido por la vista y por último la View, la vista, nuestra capa de presentación.

Gracias al magnífico Binding de WPF / Silverlight este patrón es muy sencillo de usar y en combinación con los comandos, puede reemplazar totalmente a los eventos y desplazar la mayoría del código de la vista al viewmodel, haciéndolo totalmente independiente de la vista en si misma. A continuación tenéis un esquema de esto:

MVVM

Este es un resumen de lo que es MVVM, podéis encontrar una explicación más detallada aquí.

Un ejemplo básico de MVVM

Ahora vamos a ver un ejemplo muy básico de una aplicación MVVM que muestre dos cadenas de texto en una ventana WPF.

Para ello creamos un nuevo proyecto WPF Application, vamos a tener dos clases en este proyecto: BasicModel y BasicViewModel, y vamos a renombrar nuestra ventana MainWindow a BasicView, al terminar deberíamos tener una estructura parecida a esta:

image

Vamos a empezar por definir nuestro modelo, en este caso simplemente tenemos dos métodos públicos que devuelven cadenas de texto y un constructor de clase:

 

 

    class BasicModel
    {
        public BasicModel() { }

        public string SayHello()
        {
            return "Hello Brain";
        }

        public string SayBye()
        {
            return "Bye bye Brain!! (the best WP7 game ever...)";
        }
    }

 

 

Como podéis ver es extremadamente simple, pensad que en el modelo, en vez de devolver simplemente una cadena, consultaríamos la base de datos, etc…

Ahora vamos a por nuestro ViewModel, es muy sencillo también:

 

    class BasicViewModel 
    {
        private BasicModel Model { get; set; }

        public BasicViewModel() 
        {
            Model = new BasicModel();
        }

        public string SayHello
        { 
            get
            {
                return Model.SayHello();
            }
        }

        public string SayBye
        {
            get
            {
                return Model.SayBye();
            }
        }
    }

 

Como podéis ver nuestro ViewModel simplemente actua de intermediario entre nuestra vista final y nuestro modelo, de esta forma conseguimos independizar ambos extremos y nos resultará más sencillo el mantenimiento en ambos puntos.

Finalmente vamos a definir el código xaml que enlazará con nuestro ViewModel para mostrar los datos:

 

<Window x:Class="BasicMVVM.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:Basic="clr-namespace:BasicMVVM"
        Title="MainWindow" Height="171" Width="285">
        
    <Window.Resources>
        <Basic:BasicViewModel x:Key="BasicVM"></Basic:BasicViewModel>
    </Window.Resources>

    <Grid DataContext="{StaticResource BasicVM}">
        <TextBlock Text="{Binding Path=SayHello}"></TextBlock>
        <TextBlock Text="{Binding Path=SayBye}" Margin="0,27,0,0"></TextBlock>   
    </Grid>
</Window>

 

Simplemente añadimos una referencia al namespace en el que se encuentra nuestra clase ViewModel, creamos con el un recurso de la ventana, usamos el Binding de WPF para establecer nuestro ViewModel como el contexto de datos de la grid y por último enlazamos las propiedades de los textblock a nuestras propiedades.

Y aquí está la mayor virtud de MVVM, como podéis ver, no existe más código en nuestra ventana que el propio xaml para definir los controles y sus bindings, todo el resto del código se encuentra en el Model y el ViewModel, con lo que conseguimos una independencia total de la vista, abriendo el camino hacia la reutilización de nuestro código de una manera más eficiente en diferentes tipos de proyecto.

Si ejecutamos nuestra aplicación veremos que el resultado es el siguiente:

image

 

Conclusiones 1º Parte

Bueno, con esto terminamos la primera parte de este artículo, ya sabemos en líneas generales que es esto del MVVM, de donde viene, las ventajas que aporta y hemos visto un pequeño ejemplo de como usarlo…

En la segunda parte nos centraremos en desarrollar aplicaciones WPF, Silverlight y WP7 que compartan el 80% del código fuente gracias al patrón MVVM.

Espero que os haya resultado entretenido este artículo, a los que ya conocíais MVVM espero que os parezca correcto a los que no lo conocíais espero que os pique la curiosidad por seguir investigando y a todos, muchas gracias por leerme!

Aquí tenéis el código de ejemplo de este artículo, Happy Coding!

Expression Blend 4: Enriqueciendo tus aplicaciones.

Introducción

Cuando Microsoft lanzó oficialmente Silverlight y WPF, se dieron cuenta de que los diseñadores tenían un gran handycap para diseñar usando estas tecnologias: Visual Studio. Visual Studio siempre ha estado dirigido a los desarrolladores y muchos diseñadores no se sentían cómodos usandolo, pues debían lidiar con multitud de elementos que les eran totalmente ajenos.

Para remediar esto, en Junio de 2006 microsoft lanzo una nueva apuesta al mercado: Expression Blend.

Este nuevo software permitía a diseñadores y desarrolladores trabajar juntos en un proyecto Silverlight o WPF, pero cada uno usando una herramienta específica para sus necesidades. De esta forma, Blend, eliminaba todo el contenido superfluo para un diseñador y le permitía centrarse en su trabajo: diseñar.

En estos momentos nos encontramos ya en su versión 4, con el paso de las versiones se ha ido convirtiendo en una herramienta que no podemos ignorar, pues, hasta para los desarrolladores, es muy util para simplificar el trabajo con XAML y dotar de manera rápida y sencilla a nuestras aplicaciones de un aspecto más rico y atractivo.

Interacción

Uno de los puntos fuertes de Blend es la interacción que existe entre este y Visual Studio.

Podemos crear un nuevo proyecto en Visual Studio y después con un simple click de ratón editarlo en Expression Blend, o al reves, crearlo en Expression Blend y editar su código en Visual Studio. Todo de manera sencilla y sin complicaciones, veamos un ejemplo:

1º Abrimos Expression Blend 4 (si no lo tenemos, podemos descargar una demo aquí):

image

Seleccionamos “New Project” y creamos un nuevo proyecto Silverlight Application:

image

En la pestaña de Projects pulsamos con el botón derecho sobre la solución y seleccionamos la opción “Edit in Visual Studio”

Esto abrirá una nueva instancia de Visual Studio en la que podremos trabajar y modificar el proyecto, cuando volvamos a Blend nos advertirá de que se han realizado cambios en el proyecto y nos preguntará si queremos cargar estos cambios.

Con esto podéis ver que la integración entre Visual Studio y Expression Blend es verdaderamente sencilla.

Para ver las ventajas de utilizar Expression Blend en nuestros proyectos, vamos a realizar unos pequeños gráficos para una aplicación Silverlight que servirá como frontend para una pizzeria llamada “PizzaBlend” 🙂

Dibujar en Blend

Personalmente soy partidario de hacer todo el trabajo posible directamente escribiendo XAML pero hay ocasiones en que es bastante complicado o largo de realizar y resulta más productivo usar Blend, para empezar vamos a dibujar una Pizza de pepperoni y aceitnuas (la favorita de mi mujer):

Con el proyecto de Silverlight que hemos creado, vamos a añadir un nuevo usercontrol al mismo, Seleccionando el proyecto y haciendo Click derecho, después seleccionando “Add New Item” nos aparecerá una pantalla con los elementos que podemos añadir al proyecto:

image

Seleccionamos UserControl y cambiamos su nombre a Pizza, presionamos OK y se abrirá el nuevo elemento en Blend.

Seleccionamos la pestaña “Objects and Timeline” que se encuentra al lado de la de proyectos:

image

En esta pestaña tenemos representados todos los elementos que se encuentran el archivo xaml seleccionado, en nuestro caso solo tenemos el userControl y la grid principal llamada LayoutRoot. si seleccionamos UserControl, veremos que en la vista del control aparecen los bordes del mismo con unos puntos y lineas en los bordes derecho e inferior y en la esquina inferior derecha:

image

Bien cada punto y rectángulo ofrecen distinta funcionalidad, los puntos ajustan el tamaño horizontal y vertical de nuestro control, mientras que los rectángulos y la flecha hacen lo mismo pero solo para la vista del diseñador, es decir, si ajustamos el tamaño usando los rectángulos solo lo haremos para la vista de Expression Blend y el tamaño del control se situará en Automático.

También podemos hacer esto con las propiedades que se muestran a la derecha:

image Como podemos ver en esta captura las propiedades Height y Width tienen dos valores Auto y un número, Auto indica que el control no tiene un tamaño fijo definido, el número entre paréntesis indica el tamaño que se muestra en el diseñador, el simbolo image  al lado de cada propiedad indica que la propiedad esta establecida en Auto. Por ahora nos valdrá con establecer estas propiedades en Auto y ajustar el tamaño para el diseñador en 280 de alto por 280 de ancho.

Ahora vamos a diseñar la masa de la Pizza, para esto vamos a añadir un elipse al Usercontrol, esto lo podemos realizar desde la pestaña Assets colocada al lado de la pestaña de proyectos (si no la tenéis podéis mostrarla en el Menu Window –> Assets), En esta pestaña tenemos una lista de varias categorías, una de ellas “Shapes”, la seleccionamos y veremos al lado todas las formas que podemos añadir al proyecto:

image

 

 

Seleccionamos Ellipse y pintamos el elipse sobre el userControl, no importa el tamaño, lo ajustaremos usando un Width y Height Auto y usando los margenes a las esquinas del control para darle un tamaño. Una vez dibujado el elipse, en las propiedades a la derecha verás una propiedad Margin con 4 valores, ajusta los cuatro a 10 pixeles y verás como el elipse se redimensiona, en la parte superior de las propiedades al lado de “Name” escribe Masa.

Para darle color vamos a usar un degradado radial, en la misma pestaña de propiedades de la derecha, en la sección Brushes seleccionamos “Fill”, debajo encontramos varias opciones del tipo de relleno:

image

Nos interesa esta que está seleccionada, la encargada de los degradados, establecemos el degradado como se ve en la siguiente imagen:

image

 

En principio solo nos aparecerán dos puntos de degradado, para añadir más solo debemos pulsar en el lugar de la barra donde queramos añadirlo, para eliminarlo lo seleccionamos con el botón izquierdo y tiramos de el hacia abajo, desaparecerá.

Con esto ya tenemos nuestra masa, no tiene una pinta muy interesante por ahora, pero mejorará, algo al menos… espero… soy programador, comprendedme jeje.

Ahora añadimos un segundo elipse al user control, establecemos su margen en 30 píxeles y como relleno le establecemos este degradado radial:

image

En este caso también seleccionamos la Brush “Stroke” y le aplicamos un color rojo solido con un Alpha del 33%:

image

Bien, con esto nuestra pizza ya tiene otro aspecto, pero el borde entre el segundo y el primer elipse es muy evidente, vamos a usar un efecto de desdibujado para “maquillarlo un poco”,seleccionamos el elipse que acabamos de crear, seleccionamos de nuevo la pestaña “Assets” y esta vez seleccionamos el elemento “Effects”, seleccionamos el efecto BlurEffect y lo arrastramos sobre nuestro segundo elipse, en las propiedades le aplicamos un radio de 9 pixeles.

Bueno, ahora ya solo queda ponerse creativo con los ingredientes, esto lo dejo a vuestro parecer, pero básicamente el resultado es algo como esto:

image

Ahora ya tenemos nuestra pizza, de plastico… y no demasiado apetecible… pero nuestra al fin y al cabo. ¿Por que no le damos algo de movimiento?

Animación en Blend

Vamos a realizar una sencilla animación a nuestra pizza que la haga rotar indefinidamente, gracias a Blend las animaciones son muy sencillas de realizar y a cambio le otorgan a nuestra aplicación mucho dinamismo.

En la pestaña de “Objects and Timeline” seleccionamos “LayoutRoot” y creamos una nueva animaciíon presionando el simbolo + que se encuentra bajo la pestaña:

image

 

 

Establecemos el nombre de la animación en la ventana emergente y presionamos OK:

image

Y en este momento aparece la “magia” de blend para las animaciones, un marco rojo aparecerá en nuestra vista de diseño junto con la indicación “PizzaRotation timeline recording is on” y una linea de tiempo al lado de nuestras pestañas izquierdas:

image

En este momento y hasta que presionemos el botón redondo rojo al lado de “PizzaRotation timeline recording is on” todos los parámetros y propiedades que toquemos serán animados en el tiempo. desplazando la línea de tiempo amarilla estableceremos los KeyFrames donde cada propiedad cambiará de valor, esto es si la rotación del LayoutRoot en el segundo 0 es 0, y movemos la línea amarilla hasta el segundo 3, y acto seguido rotamos el LayoutRoot 360º, automáticamente Silverlight mostrará una animación de 3 segundos con nuestra pizza rotando 360º.

La animación tiene varias propiedades:

imageAutoreverse causará que, al terminar, la animación se reproduzca automáticamente en sentido inverso hasta llegar al comienzo.

RepeatBehavior: Nos permite indicar cuantas veces se debe repetir la animación, si indicamos Forever siempre estará reproduciendose.

Bien ahora solo nos queda indicar a la animación que comience a reproducirse cuando nosotros queramos, en este caso esto será cuando se dispare el evento Loaded del UserControl.

En la pestaña “Objects and Timeline” seleccionamos el userControl y en las propiedades pulsamos el botón eventos al lado del nombre:image .

Con esto veremos una lista de los eventos que soporta el UserControl, entre ellos veremos el evento Loaded, hacemos doble click sobre la caja de texto vacía a su lado y nos crea por defecto el manejador de eventos para Loaded, al que añadiremos el código que inicia la animación:

image

 

Bien, ahora solo tenemos que incorporar el userControl a una página de silverlight para que funcione.

Lo primero que necesitamos es compilar todo el proyecto para que nuestro usercontrol pase a formar parte de nuestro ensamblado. Esto lo podemos realizar desde el menu “Project” en la opción “Rebuild Project”

Una vez hecho esto, seleccionamos en la pestaña “Projects” el archivo MainPage.xaml y hacemos doble click sobre el para que  se abra en el editor, nos vamos a la pestaña “Assets” y seleccionamos el elemento “Project”, en el deberemos encontrar el UserControl1, nuestra pizza, simplemente debemos arrastrarlo hasta el formulario y podremos verlo.

Si ejecutamos el proyecto usando la tecla “F5” o la opción Run del menú “Project” veremos que nuestra pizza rota indefinidamente.

Básicamente la animación en Blend no tiene muchos más secretos y esto es lo mejor de todo, en el proyecto adjunto he añadido algunas animaciones más jugando con efectos en la animación para que podáis practicar por vosotros mismos:

image

P.D.: Espero que mis habilidades de diseño no hayan herido la sensibilidad de ningún diseñador, si es así, creedme, no ha sido mi intención 🙂

Espero que os haya gustado, ya sabéis, espero vuestros comentarios 🙂

Un gran saludo y Happy Coding!

WP7: Acceso a la información de Licencia y Al Marketplace desde nuestra aplicación.

Ahora que se acerca la apertura del marketplace para Windows Phone 7 es hora de ir dando los últimos toques a nuestras aplicaciones e ir preparándolas para el gran público.
Algo muy importante para que nuestra aplicación tenga buena acogida entre los usuarios es que estos sean capaces de probarla y verla en funcionamiento antes de tener que invertir su dinero en ella, quizás incluso sería interesante el poder ofrecer a los usuarios una versión gratuita de nuestra aplicación para que la probasen, que tuviese todas las características de la versión de pago y sin limitaciones, usando publicidad para ganar algo de dinero con esta versión y ofreciendo al usuario eliminar esta publicidad comprando la versión de pago.

Tradicionalmente en otras plataformas para aplicaciones móviles de la “competencia” la forma de realizar esto pasaba por crear versiones “Lite” de nuestra aplicación que eran subidas como una aplicación independiente, duplicando de esa forma el esfuerzo necesario para realizar el mantenimiento de nuestra aplicación y duplicando el numero de aplicaciones en la tienda en cuestión.
Microsoft ha resuelto esto, como de costumbre, de forma rápida, elegante y sencilla.

El namespace Microsoft.Phone.Marketplace

Este namespace se encuentra en el ensamblado Microsoft.Phone y en estos momentos expone solo una clase: LicenseInformation.
Esta clase LicenseInformation expone un sólo método: IsTrial, el cual devuelve un valor boolean indicando si nuestra aplicación se encuentra en modo de prueba o no.
Pero…. ¿Como sabe esto el teléfono? Bueno, el sistema que usan en microsoft para instalar la aplicación en un dispositivo y validar que proceda del marketplace hace posible la magia:
Cuando el usuario accede a los detalles de nuestra aplicación en el marketplace se le presenta la opción de “probarla” o “comprarla”, en cualquiera de los dos casos la aplicación descargada es la misma, pero el certificado de seguridad que se descarga es distinto, en el caso de que la compre, se descarga el certificado real de la aplicación, sin embargo si se descarga una “prueba” el certificado que obtenemos es un certificado de pruebas, De esta forma examinando este certificado podemos saber en que estado se encuentra nuestra aplicación, y una vez que el usuario acabe de probar y decida comprar, no debe descargar de nuevo toda la aplicación, tan solo obtendrá el certificado real y la aplicación empezará a funcionar de forma completa.
Bien, como puedes ver es muy sencillo y transparente tanto para el desarrollador como para el usuario. Para implementar este comportamiento solo debemos comprobar cuando nos interese la respuesta del método IsTrial en la clase LicenseInformatión, Por ejemplo podríamos llamar a este método en los eventos Launching y Activated de nuestra aplicación y guardar el resultado en una variable global que nos permita consultarla desde cualquier punto de la aplicación de forma sencilla:
Primero definimos nuestra variable en la clase App:
public partial class App : Application
{
public static Boolean DemoMode = false;
}

En el evento Launching, que se ejecuta cuando la aplicación se abre desde 0, sin que haya sido desactivada por otro programa o por el usuario, comprobamos en que modo nos encontramos:

// Code to execute when the application is launching (eg, from Start)
// This code will not execute when the application is reactivated
private void Application_Launching(object sender, LaunchingEventArgs e)
{
//Comprobamos si nos encontramos en modo demo.
Microsoft.Phone.Marketplace.LicenseInformation InfoLicencia;
InfoLicencia = new Microsoft.Phone.Marketplace.LicenseInformation();
//Establecemos si nos encontramos en modo demo.
DemoMode = InfoLicencia.IsTrial();
}

Y en el evento Activated, que se ejecuta cuando la aplicación se abre después de ser desactivada por otro proceso o por el usuario, comprobamos en que modo nos encontramos de nuevo:

// Code to execute when the application is activated (brought to foreground)
// This code will not execute when the application is first launched
private void Application_Activated(object sender, ActivatedEventArgs e)
{
//Comprobamos si nos encontramos en modo demo.
Microsoft.Phone.Marketplace.LicenseInformation InfoLicencia;
InfoLicencia = new Microsoft.Phone.Marketplace.LicenseInformation();
DemoMode = InfoLicencia.IsTrial();
}

Y con esto, en nuestro código ya solo tendremos que comprobar el valor de la propiedad DemoMode de la clase App para saber si debemos mostrar la publicidad, limitar el numero de items de algunas listas, pedirle al usuario que nos ayude a llegar a fin de mes o la estrategia que queramos seguir para mostrar y vender nuestra aplicación.

Bien, ya sabemos como convertir nuestra aplicación en una demo de forma automática, pero…. ¿como hacemos para ayudar al usuario a comprar nuestra aplicación? Bien, aquí entra en juego uno de los Launchers de WP7: el MarketplaceDetailTask.

El launcher MarketplaceDetailTask

Espera, espera…. ¿Por las barbas de mi abuelo…..que es un launcher? Bien, es muy común el caso en el que queramos hacer uso de funcionalidad del propio sistema operativo, como puede ser hacer una llamada, enviar un email o sms, abrir el navegador web y algunas cosas más. Esto lo podemos realizar mediante un Api que expone el sistema, localizada en el namespace Microsoft.Phone.Tasks. Hay dos tipos de tareas, las que lanzan una característica del teléfono, como por ejemplo enviar un email, y no devuelven nada a nuestra aplicación se llaman Launchers y las que lanzan una característica del teléfono y devuelven un resultado, como por ejemplo seleccionar una imagen del HUB de imágenes, que se llaman Choosers.

Una vez aclarado esto, existe un Launcher llamado MarketplaceDetailTask que nos permite abrir desde nuestra aplicación el Hub del marketplace del sistema en los detalles de una aplicación específica.

Esta clase tiene dos propiedades principales: ContentType y ContentIdentifier:

 

  • ContentType indica el tipo de contenido que podemos mostrar, se le asigna un valor del enumerador Microsoft.Phone.Tasks.MarketplaceContentType, que puede ser Applications o Music.
  • ContentIdentifier indica el ID único del marketplace de la aplicación que queremos mostrar, si queremos mostrar los detalles de nuestra propia aplicación bastará con pasarle un valor nulo.

Por último, solo debemos usar el método Show de la clase MarketplaceDetailTask para que nuestra aplicación se desactive y se muestre el marketplace con nuestros detalles.

El código quedaría así:

 

Microsoft.Phone.Tasks.MarketplaceDetailTask Detalles;
Detalles = new Microsoft.Phone.Tasks.MarketplaceDetailTask();
Detalles.ContentType = Microsoft.Phone.Tasks.MarketplaceContentType.Applications;
Detalles.ContentIdentifier = App.AppUniqueID;
Detalles.Show();

 

Conclusión

Y con esto terminamos este artículo, Como siempre os dejo un pequeño proyecto de ejemplo con todo lo que hemos visto aplicado, para que podáis probarlo, tened en cuenta que el marketplace os dirá que no se puede acceder en estos momentos, pues todavía no está disponible para su uso.

Podéis contactar conmigo por mi correo, por Twitter, aquí dejando un mensaje o incluso en los foros de Silverlight / WPF de MSDN por los que siempre ando. Estaré encantado de resolver cualquier duda que tengáis (sobre esto… el sentido de la vida no me dejan revelarlo) y charlar un rato con vosotros.

Muchas gracias por leerme, sin todos vosotros estas palabras no tendrían sentido de existir.

Un gran saludo y Happy Coding!

WPF: Arboles

Hola a todos

Los elementos de la interface de usuario de una aplicación WPF tienen una relación jerárquica, esta relación toma el nombre de Object Tree, un árbol en el que podemos encontrar todos los objetos anidados que tenemos en nuestra aplicación.
El Object Tree es más un concepto o metáfora que una realidad, pues ciertas propiedades y comportamientos de controles pueden romper esta vista de árbol en tiempo de ejecución. Para evitar esto WPF expone dos arboles distintos que pueden ser accedidos por nuestra aplicación: Logical Tree y Visual Tree.

 

En el gráfico anterior podéis ver el árbol de objetos (Object Tree) de una ventana WPF, y como podemos subdividirlo entre el árbol lógico y el árbol visual
Como sabéis un control en WPF se compone en su forma visual de una plantilla que contiene los controles que dan forma a nuestro control, el Object Tree de WPF contiene información de cada control que tenemos en nuestra ventana, sus hijos y los controles que lo componen en su plantilla.

Logical Tree

El árbol lógico de una ventana en WPF contiene información acerca de la organización jerárquica de los controles en la misma, tendremos normalmente un Objeto Window como principio del árbol del cual se desprenderán de forma ordenada el resto de controles que componen la ventana, tal y como los hayamos definido en código o en Xaml.
El propósito principal de este árbol lógico es el de ofrecer en tiempo de ejecución una representación veraz y realista de nuestros objetos de forma que podamos consultarlos sin preocuparnos de los controles que componen a cada uno, por ejemplo para poder buscar un control de un cierto tipo dentro de nuestra ventana sin tener que recorrer los controles que componen la visualización:
<RichTextBox>
<FlowDocument>
<Paragraph>
Hola <Rectangle Width='10' Height='10' Fill='Red' />
</Paragraph>
</FlowDocument>
</RichTextBox>

Si miramos el Xaml escrito aquí, veremos que tenemos un control Rectangle dentro de un Paragraph que a su vez se encuentra en un FlowDocument, contenido por un RichTextBox. Así si queremos obtener el Padre lógico del control rectangle este será el control Paragraph pues es quien lo contiene. Esta secuencia es la que nos devolvería el Logical Tree, más adelante veremos este mismo ejemplo con el Visual Tree para observar las diferencias entre ambos.

Este es un ejemplo del resultado de recorrer el árbol lógico del Xaml que tenemos arriba:

image

 

Visual Tree

El árbol visual de una ventana WPF contiene información acerca de los controles representados gráficamente en la misma. De esta forma, siguiendo el ejemplo anterior de la Ventana, y como podemos ver en el gráfico anterior, de la Ventana no se desprenderá directamente el contenido de la misma, primero tendremos los controles que componen la plantilla de la ventana y bajo el contentpresenter de la misma encontraremos el resto de controles, junto a su composición interna.

El propósito principal de este árbol visual es el de ofrecer una relación de TODOS los controles dibujados en nuestra ventana, sin distinguir entre controles insertados en la ventana y los controles que componen a estos como puede ser el Border, ContentPresenter y los demás, examinemos el ejemplo anterior:

 

<RichTextBox>
<FlowDocument>
<Paragraph>
Hola <Rectangle Width='10' Height='10' Fill='Red' />
</Paragraph>
</FlowDocument>
</RichTextBox>

En este caso, si queremos obtener el Padre visual de nuestro rectangle usando el árbol visual este nos devolverá como control padre el RichTextBox, en vez del Paragraph, pues los controles Paragraph, FlowDocument, etc… son considerados elementos inline y no controles. Este es un ejemplo del resultado de recorrer el árbol visual del Xaml que tenemos arriba:

image 

 

Diferencias entre Logical Tree y Visual Tree

Como podéis existen grandes diferencias entre el Árbol Lógico y Visual, y sin duda dependiendo de la situación nos será útil recorrer uno u otro, pero, ¿Cuando usar cada uno? Aquí tenéis las principales características de cada uno:

  • Logical Tree:
    • Responsable de la herencia de valores de las DependencyProperties
    • Resuelve referencias a DynamicResources
    • Busqueda de Nombre de elementos para Binding
    • Pasar RoutedEvents a ancestros.
  • Visual Tree:
    • Dibujado de elementos Visuales
    • Propagación de opacidad de elementos
    • Propagación de LayoutTransform y RenderTransform
    • Propagación de la propiedad IsEnabled
    • Hit Testing
    • RelativeSource (FindAncestor)

     

Conclusión

Para poder trabajar con estos arboles disponemos de dos clases en WPF: VisualTreeHelper y LogicalTreeHelper que nos ofrecen métodos para movernos en el árbol de cada uno de forma sencilla, Como ejemplo os dejo dos métodos recursivos que recorren el árbol lógico y el visual añadiendo a un treeview todas las ocurrencias a partir de un control dado:

'Obtenemos todos los controles hijos visuales del control base indicado.
Private Sub Recursive_GetVisualChildrens(ByVal BaseControl As DependencyObject,
ByVal ParentNode As TreeViewItem)
If VisualTreeHelper.GetChildrenCount(BaseControl) > 0 Then
For i As Integer = 0 To VisualTreeHelper.GetChildrenCount(BaseControl) - 1
Dim Hijo As New DependencyObject()
Hijo = VisualTreeHelper.GetChild(BaseControl, i)
Dim Nodo As New TreeViewItem
Nodo.Header = Hijo.DependencyObjectType.Name
Recursive_GetVisualChildrens(Hijo, Nodo)
ParentNode.Items.Add(Nodo)
Next
End If
End Sub

'Obtenemos todos los controles hijos lógicos del control base indicado.
Private Sub Recursive_GetLogicalChildrens(ByVal BaseControl As DependencyObject,
ByVal ParentNode As TreeViewItem)
For Each Hijo As Object In LogicalTreeHelper.GetChildren(BaseControl)
Dim Nodo As New TreeViewItem
Nodo.Header = Hijo.GetType().Name
Try
Recursive_GetLogicalChildrens(CType(Hijo, DependencyObject), Nodo)
Catch ex As Exception
End Try
ParentNode.Items.Add(Nodo)
Next
End Sub

Y como ayuda y demostración os dejo una aplicación WPF que hace uso de estos métodos para que juguéis con ella:

image

 

Espero que os haya gustado tanto leer este artículo como a mi escribirlo.

 

Por si tenéis alguna dificultad, a parte por supuesto de poder contactar conmigo tanto dejando mensajes, como en mi twitter, como en msdn o a mi email directamente, os dejo el proyecto completo para descarga.

 

Y recordad, con un simple comentario, podéis hacer feliz a un pequeño bloguero 🙂

 

Muchas gracias por leerme y Happy Coding!

Estrenandome en Geeks.ms

Hola a todos!

Ayer Rodrigo Corral me dió la gran oportunidad de unirme a esta comunidad.

Hasta ahora escribía mi blog sobre tecnología en http://jyeray.blogspot.com, a partir de ahora intentare mantener ambos.

Espero poder ayudar a que la gente que se está introduciendo en este mundo que es .NET tengan los conceptos claros y aprendan como hacer las cosas bien y de forma efectiva.

Un gran saludo a todos y Happy Coding!