﻿<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>El Blog de Fox &#187; Silverlight</title>
	<atom:link href="http://blog.foxandxss.net/index.php/tag/silverlight/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.foxandxss.net</link>
	<description>Fomentando el desarrollo y el software libre bajo .NET</description>
	<lastBuildDate>Thu, 12 Aug 2010 12:22:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Silverlight 4 final</title>
		<link>http://blog.foxandxss.net/index.php/silverlight-4-final/</link>
		<comments>http://blog.foxandxss.net/index.php/silverlight-4-final/#comments</comments>
		<pubDate>Fri, 16 Apr 2010 12:58:18 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Noticias]]></category>
		<category><![CDATA[Silverlight]]></category>

		<guid isPermaLink="false">http://blog.foxandxss.net/?p=337</guid>
		<description><![CDATA[Bueno, despues de muchos meses de desarrollo y versiones betas, ya está aquí Silverlight 4 final. Como requisito previo es necesario tener instalado el Visual Studio 2010 o el Visual Web Developer 2010 express. Una vez cumplas dicho requisitos solo necesitas: Herramientas Silverlight 4 Ahi ya viene incluido Silverlight en si, las herramientas para vs [...]]]></description>
			<content:encoded><![CDATA[<p>Bueno, despues de muchos meses de desarrollo y versiones betas, ya está aquí <b>Silverlight 4</b> final.</p>
<p>Como requisito previo es necesario tener instalado el <b>Visual Studio 2010</b> o el <b>Visual Web Developer 2010 express</b>.</p>
<p>Una vez cumplas dicho requisitos solo necesitas:</p>
<p><a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=bf5ab940-c011-4bd1-ad98-da671e491009&#038;displaylang=en">Herramientas Silverlight 4</a></p>
<p>Ahi ya viene incluido Silverlight en si, las herramientas para vs 2010, el sdk y los servicios RIA.</p>
<p>Un alivio, que siempre había que instalar tropecientos paquetes para echar esto a andar jeje.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.foxandxss.net/index.php/silverlight-4-final/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MVVM Light: Localización</title>
		<link>http://blog.foxandxss.net/index.php/mvvm-light-localizacion/</link>
		<comments>http://blog.foxandxss.net/index.php/mvvm-light-localizacion/#comments</comments>
		<pubDate>Thu, 25 Mar 2010 14:26:17 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Articulos]]></category>
		<category><![CDATA[MVVM]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Windows Phone 7]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://blog.foxandxss.net/?p=223</guid>
		<description><![CDATA[Hola, Aquí está el último artículo de esta serie sobre MVVM Light Realmente la localización no forma parte de MVVM Light en sí, es algo que ya existía de antes y que sirve para todo tipo de aplicaciones. Pero vamos a aprovechar esta serie para meter aquí el artículo y así podamos hacer aplicaciones con [...]]]></description>
			<content:encoded><![CDATA[<p>Hola,</p>
<p>Aquí está el último artículo de esta serie sobre <b>MVVM Light</b></p>
<p>Realmente la localización no forma parte de <b>MVVM Light</b> en sí, es algo que ya existía de antes y que sirve para todo tipo de aplicaciones.</p>
<p>Pero vamos a aprovechar esta serie para meter aquí el artículo y así podamos hacer aplicaciones con buena arquitectura y localizados.</p>
<p>Pero antes que nada&#8230;.<br />
<span id="more-223"></span></p>
<h3>¿Qué es la localización?</h3>
<p>Básicamente es el proceso de adaptar un software a un idioma concreto, por ejemplo, traduciendo sus textos y esto es precisamente lo que vamos a aprender aquí.</p>
<p>¿Cómo se hace eso? Pues el texto está escrito en el xaml y en los .cs&#8230;</p>
<p>Es muy fácil como veremos a continuación:</p>
<p>Para empezar, abrimos el proyecto del artículo de <i>comandos</i>, que como recordaréis lo dejamos en inglés a conciencia.</p>
<p>Ejecutamos el proyecto, rellenamos los campos y el resultado es como este:</p>
<p><a href="http://foxandxss.net/CosasBlog/mvvmlight/localizacion/1.JPG"><img alt="" src="http://foxandxss.net/CosasBlog/mvvmlight/localizacion/1.JPG" class="alignnone" width="343" height="460" /></a></p>
<p>Todo perfectamente en inglés.</p>
<p>¿Cual es el primer paso a la hora de localizar una aplicación?</p>
<p>Colocar todas las cadenas en un recurso aparte y nunca escribirlas directamente en el código.</p>
<p>Para ello creamos un nueva carpeta en nuestro proyecto llamada <b>Resources</b>, dentro creamos un nuevo item del tipo <i>Resources File</i> (O ficheros de recursos como me imagino que será en castellano).</p>
<p>A este fichero le vamos a poner de nombre Strings.resx. Si lo abrimos, vemos que tenemos 3 columnas en las que rellenar datos. En la primera va el identificador de la cadena, en la segunda irá la cadena en sí y en la tercera podemos poner un comentario que ayude a aquella persona que le toque traducir a saber en qué contexto estaba esa palabra (opcional).</p>
<p>Por ejemplo, imaginad que tenemos la siguiente cadena: &#8220;Choose Color&#8221; y la tenemos que meter en el fichero Strings.resx, pues básicamente sería algo del tipo:</p>
<ul>
<li>ChooseColor &#8211; Choose Color &#8211; Color Picker window</li>
</ul>
<p>O sea: identificador &#8211; cadena &#8211; comentario</p>
<p>Bueno, ya que sabemos como rellenar el fichero, voy a colocar la lista de todas las cadenas que estamos usando en la aplicación:</p>
<ul>
<li>InsertName &#8211; Insert your name:</li>
<li>InsertAge &#8211; Insert your age:</li>
<li>Accept &#8211; Accept</li>
<li>Count &#8211; Count</li>
<li>Reset &#8211; Reset</li>
<li>Greeting &#8211; Hello, my name is {0} and Im {1} years old.</li>
<li>CountMessage &#8211; Greeting has {0} characters.</li>
</ul>
<p>Como véis, hemos colocado aquí todas las cadenas tanto de los .xaml como de los .cs</p>
<blockquote><p>
<b>NOTA:</b> Solo se han de colocar aquellas cadenas que van a ser mostradas por pantalla (pues son las que nos interesan), aquellas cadenas como las de los <i>RaisePropertyChanged</i> pues no hay que meterlas ahí.
</p></blockquote>
<p><b>MUY IMPORTANTE:</b> En la ventana de <i>Strings.resx</i> donde metéis todos los datos, arriba hay un combobox que pone: Modificador de acceso, tenéis que cambiarlo de <i>internal</i> a <i>public</i>. Además vais a tener que ir al fichero Strings.Designer.cs y ahi modificar el constructor cambiandole el modificador de acceso de <i>internal</i> a <i>public</i>. Además, tendrás que hacer estas 2 cosas cada vez que se guarde el fichero (por ejemplo al meter una nueva entrada). Esto es MUY importante y nada más que por esto merece la pena leer el tutorial.</p>
<p>Bien, este fichero contiene el idioma por defecto de la aplicación, esto quiere decir que si abrimos el programa en un windows ruso y no lo tenemos localizado al ruso, usará el lenguaje por defecto, en este caso, inglés.</p>
<p>Ahora bien, necesitamos quitar todas las cadenas de nuestro programa y sustituirlas por las que están en este fichero. ¿Cómo?</p>
<p>Para empezar necesitamos poder acceder a dicho recurso de forma global en todos los .xaml, y ya sabemos que para eso todo lo que definamos en App.xaml será global para todo fichero .xaml</p>
<p>Así que vamos a App.xaml y colocamos:</p>
<p>Un nuevo namespace:</p>
<pre class="brush: xml;">
xmlns:res=&quot;clr-namespace:EjemploMVVML.Resources&quot;
</pre>
<p>Y ahora creamos una instancia del recurso:</p>
<pre class="brush: xml;">
&lt;res:Strings x:Key=&quot;LocStrings&quot; /&gt;
</pre>
<p>Ésta linea la colocamos junto a la instancia del <i>ViewModelLocator</i></p>
<p>Bien, ya que tenemos acceso a <i>Strings</i> en cualquier .xaml, vamos a empezar a sustituir las viejas cadenas de esta forma:</p>
<pre class="brush: xml;">
{Binding Source={StaticResource LocStrings}, Path=Identificador}
</pre>
<p>Por ejemplo, el primer label, el de insertar la edad:</p>
<pre class="brush: xml;">
&lt;Label Content=&quot;{Binding Source={StaticResource LocStrings}, Path=InsertName}&quot; Height=&quot;23&quot;
	   HorizontalAlignment=&quot;Left&quot; Margin=&quot;30,31,0,0&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;123&quot; /&gt;
</pre>
<p>Simplemente hemos sustituido la cadena escrita a mano por la que tenemos en <i>Strings.resx</i></p>
<p>Ahora tienes que hacerlo con las demás cadenas que están en el .xaml (por simplificar el tamaño del tutorial no voy a pegar aqui el código, pero vamos, es algo mecánico.</p>
<p>Y bueno suponiendo que tenemos el .xaml listo con todo modificado, vamos a explicar como hacer esto mismo pero en C# para las cadenas de nuestras clases:</p>
<pre class="brush: csharp;">
string cadena = Resources.Strings.Identificador;
</pre>
<p>¿Nada complicado verdad? <img src='http://blog.foxandxss.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Así que nuestras dos propiedades del <i>MainViewModel</i> quedarían así:</p>
<pre class="brush: csharp;">
Greeting = string.Format(Resources.Strings.Greeting,
	APerson.Name, APerson.Age);
</pre>
<pre class="brush: csharp;">
CountMessage = string.Format(Resources.Strings.CountMessage, characters);
</pre>
<p>Ala, ya tenemos todo listo.</p>
<p>Normalmente cuando creamos una aplicación que soportará localización, metemos directamente todas las cadenas al <i>Strings.resx</i> para ahorrarnos trabajo <img src='http://blog.foxandxss.net/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<p>Bueno, ya tenemos todo listo. Así que lo que queda es añadir un nuevo fichero de recursos por cada lenguaje que vayamos a meter, cada fichero tendrá un nombre del tipo:</p>
<p><b>Strings.xx-yy.resx</b></p>
<p>Por ejemplo:</p>
<ul>
<li>Strings.es-es.resx</li>
<li>Strings.en-us.resx</li>
<li>Strings.de-de.resx</li>
</ul>
<p>Para nuestro ejemplo, creamos un fichero de recursos llamado <i>Strings.es-es.resx</i> junto a <i>Strings.resx</i>.</p>
<p>Este fichero es igual al anterior y se usa igual que el anterior. En este caso, la primera columna llevará los identificadores (los mismos que antes) y en la segunda la cadena pero ya en el idioma que estamos localizando:</p>
<ul>
<li>InsertName &#8211; Introduce tu nombre:</li>
<li>InsertAge &#8211; Introduce tu edad:</li>
<li>Accept &#8211; Aceptar</li>
<li>Count &#8211; Contar</li>
<li>Reset &#8211; Reiniciar</li>
<li>Greeting &#8211; Hola, mi nombre es {0} y tengo {1} años.</li>
<li>CountMessage &#8211; El saludo tiene {0} caracteres.</li>
</ul>
<p>Nada más, ahora si abrimos nuestro programa&#8230;</p>
<p><a href="http://foxandxss.net/CosasBlog/mvvmlight/localizacion/2.JPG"><img alt="" src="http://foxandxss.net/CosasBlog/mvvmlight/localizacion/2.JPG" class="alignnone" width="343" height="460" /></a></p>
<p>Nos sale totalmente en castellano, puesto que tenemos nuestro sistema operativo en castellano.</p>
<p>Así que sólo quedaría añadir un fichero por cada idioma que queramos soportar y nada más.</p>
<p>Os adjunto el proyecto (.NET 4):</p>
<p><a href='http://foxandxss.net/CosasBlog/mvvmlight/localizacion/EjemploMVVML.zip' >EjemploMVVML.zip</a></p>
<p>Con esto doy por concluida la serie de artículos sobre <b>Iniciación a MVVM Light.</b></p>
<p>Como ejercicio final os recomendaría echarle un ojo por encima a mi aplicación <b>Apunta Notas</b> ya que está escrita usando todo lo que aquí hemos aprendido y quizá os pueda solucionar muchas de las dudas que tengáis, aunque podéis preguntar en cualquier artículo las dudas que os hayan quedado.</p>
<p><a href="http://apuntanotas.codeplex.com/">Apunta Notas</a></p>
<p>Hasta la próxima.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.foxandxss.net/index.php/mvvm-light-localizacion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MVVM Light: Messenger</title>
		<link>http://blog.foxandxss.net/index.php/mvvm-light-messenger/</link>
		<comments>http://blog.foxandxss.net/index.php/mvvm-light-messenger/#comments</comments>
		<pubDate>Wed, 24 Mar 2010 22:32:28 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Articulos]]></category>
		<category><![CDATA[MVVM]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Windows Phone 7]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://blog.foxandxss.net/?p=217</guid>
		<description><![CDATA[Y aquí estamos con la tercera parte de este artículo sobre MVVM Light. En esta ocasión hablaremos sobre Messenger y no, no es el que usas para chatear con tus colegas, aunque la idea es parecida. Antes de explicar en qué consiste lo de Messenger vamos a presentar al concursante el ejemplo. El ejemplo es [...]]]></description>
			<content:encoded><![CDATA[<p>Y aquí estamos con la tercera parte de este artículo sobre MVVM Light.</p>
<p>En esta ocasión hablaremos sobre <b>Messenger</b> y no, no es el que usas para chatear con tus colegas, aunque la idea es parecida.</p>
<p>Antes de explicar en qué consiste lo de <b>Messenger</b> vamos a presentar <strike>al concursante</strike> el ejemplo.<br />
<span id="more-217"></span><br />
El ejemplo es parecido al del anterior artículo, pero le hemos añadido una vuelta de tuerca más para mostraros otros conceptos nuevos.</p>
<p>El ejemplo se mantiene simple para no liaros con cosas que no tienen que ver con lo que vamos a explicar hoy.</p>
<p>Creamos una nueva aplicación MVVM Light para WPF, y añadimos la siguiente clase al modelo:</p>
<pre class="brush: csharp;">
using System.ComponentModel;

namespace EjemploMessenger.Model
{
    public class Persona : INotifyPropertyChanged
    {
        private string _nombre;
        private int _edad;

        public Persona()
        {

        }

        public string Nombre
        {
            get { return _nombre; }
            set
            {
                _nombre = value;
                RaisePropertyChanged(&quot;Nombre&quot;);
            }
        }

        public int Edad
        {
            get { return _edad; }
            set
            {
                _edad = value;
                RaisePropertyChanged(&quot;Edad&quot;);
            }
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        private void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(
                    this,
                    new PropertyChangedEventArgs(propertyName)
                    );
            }
        }

        #endregion
    }
}
</pre>
<p>Hemos cogido prestada la misma clase que hemos usado en el anterior ejemplo, aunque ya están puesto las variables en castellano pues aunque sea buena practica hacerlo en inglés, este blog está en castellano y muchos no saben inglés.</p>
<p>La ventana quedaría así:</p>
<pre class="brush: xml;">
&lt;Window x:Class=&quot;EjemploMessenger.MainWindow&quot;
        xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
        xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
        xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
        xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
        mc:Ignorable=&quot;d&quot;
        Height=&quot;300&quot;
        Width=&quot;400&quot;
        Title=&quot;Ejemplo Messaging&quot;
        DataContext=&quot;{Binding Main, Source={StaticResource Locator}}&quot; Background=&quot;#FFD0FFB9&quot; ResizeMode=&quot;NoResize&quot;&gt;

    &lt;Grid x:Name=&quot;LayoutRoot&quot;&gt;
    	&lt;Label Content=&quot;Inserta tu nombre:&quot; Height=&quot;27&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;30,31,0,0&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;123&quot; /&gt;
		&lt;TextBox Height=&quot;25&quot; Margin=&quot;30,58,82,0&quot; VerticalAlignment=&quot;Top&quot;
                 Text=&quot;{Binding UnaPersona.Nombre}&quot;/&gt;
		&lt;Label Content=&quot;Inserta tu edad:&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;30,87,0,0&quot; VerticalAlignment=&quot;Top&quot;/&gt;
		&lt;TextBox Margin=&quot;30,116.96,181,0&quot; VerticalAlignment=&quot;Top&quot; Height=&quot;25&quot;
                 Text=&quot;{Binding UnaPersona.Edad}&quot; IsReadOnly=&quot;True&quot;/&gt;
		&lt;Button Content=&quot;Elegir edad&quot; HorizontalAlignment=&quot;Right&quot; Margin=&quot;0,116.96,82,0&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;75&quot;/&gt;
        &lt;Button Content=&quot;Aceptar&quot; Margin=&quot;0,155,82,0&quot; VerticalAlignment=&quot;Top&quot; HorizontalAlignment=&quot;Right&quot; Width=&quot;74&quot; /&gt;
        &lt;TextBox x:Name=&quot;Greet&quot; Margin=&quot;30,197.98,82,0&quot; IsEnabled=&quot;True&quot;
                 Text=&quot;{Binding Saludo}&quot; IsReadOnly=&quot;True&quot; Height=&quot;25&quot; VerticalAlignment=&quot;Top&quot; /&gt;

	&lt;/Grid&gt;
&lt;/Window&gt;
</pre>
<p>Ahora necesitamos crear otra ventana con su ViewModel. Creamos un ViewModel llamado <i>EdadViewModel</i> (Para ello al darle a añadir, nos saldrá la opcion de crear un nuevo MvvmViewModel directamente, así que seleccionamos esta opción). Luego creamos una ventana dándole a la opción MvvmView. A esta ventana le damos el nombre de <i>EdadWindow.xaml</i> y le añadimos el siguiente código:</p>
<pre class="brush: xml;">
&lt;Window x:Class=&quot;EjemploMessenger.EdadWindow&quot;
        xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
        xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
        xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
        xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
        mc:Ignorable=&quot;d&quot;
        Title=&quot;Ejemplo Messaging&quot;
        DataContext=&quot;{Binding Edad, Source={StaticResource Locator}}&quot; Height=&quot;253&quot; Width=&quot;334&quot; Background=&quot;#FFFFD1FA&quot; ResizeMode=&quot;NoResize&quot;&gt;

    &lt;Grid&gt;
    	&lt;Label Content=&quot;Fecha Nacimiento (xx/xx/xxxx):&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;8,8,0,0&quot; VerticalAlignment=&quot;Top&quot;/&gt;
    	&lt;Label Content=&quot;Dia:&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;8,46,0,0&quot; VerticalAlignment=&quot;Top&quot;/&gt;
    	&lt;Label Content=&quot;Mes:&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;8,75.96,0,0&quot; VerticalAlignment=&quot;Top&quot;/&gt;
    	&lt;Label Content=&quot;Año:&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;8,105.92,0,0&quot; VerticalAlignment=&quot;Top&quot;/&gt;
    	&lt;TextBox Margin=&quot;0,50,97.254,0&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;184&quot; Height=&quot;21.96&quot; HorizontalAlignment=&quot;Right&quot;/&gt;
    	&lt;TextBox Margin=&quot;0,79.96,97.254,0&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;184&quot; HorizontalAlignment=&quot;Right&quot;/&gt;
    	&lt;TextBox Margin=&quot;0,109.92,97.254,0&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;184&quot; HorizontalAlignment=&quot;Right&quot;/&gt;
    	&lt;Button Content=&quot;Aceptar&quot; Margin=&quot;155.746,146,97.254,0&quot; VerticalAlignment=&quot;Top&quot;/&gt;

    &lt;/Grid&gt;
&lt;/Window&gt;
</pre>
<p>Cada vez que añadamos un nuevo <i>ViewModel</i> a nuestro proyecto, deberemos añadir la referencia al <b>ViewModelLocator</b>, para ello abrimos la clase <i>ViewModelLocator.cs</i> y le damos a añadir nuevo snippet de código (o lo escribes a mano si quieres) y añades un <i>ViewModelLocator property</i>, luego lo modificamos para que quede así:</p>
<pre class="brush: csharp;">
private static EdadViewModel _edad;

/// &lt;summary&gt;
/// Gets the ViewModelPropertyName property.
/// &lt;/summary&gt;
public static EdadViewModel EdadStatic
{
	get
	{
		if (_edad == null)
		{
			CreateEdad();
		}

		return _edad;
	}
}

/// &lt;summary&gt;
/// Gets the ViewModelPropertyName property.
/// &lt;/summary&gt;
[System.Diagnostics.CodeAnalysis.SuppressMessage(&quot;Microsoft.Performance&quot;,
	&quot;CA1822:MarkMembersAsStatic&quot;,
	Justification = &quot;This non-static member is needed for data binding purposes.&quot;)]
public EdadViewModel Edad
{
	get
	{
		return EdadStatic;
	}
}

/// &lt;summary&gt;
/// Provides a deterministic way to delete the ViewModelPropertyName property.
/// &lt;/summary&gt;
public static void ClearEdad()
{
	_edad.Cleanup();
	_edad = null;
}

/// &lt;summary&gt;
/// Provides a deterministic way to create the ViewModelPropertyName property.
/// &lt;/summary&gt;
public static void CreateEdad()
{
	if (_edad == null)
	{
		_edad = new EdadViewModel();
	}
}
</pre>
<p>Básicamente por cada <i>ViewModel</i> en el proyecto, necesitamos una referencia de éste en el <i>ViewModelLocator</i>, cada referencia consta de una instancia estática del ViewModel, una propiedad estática y otra normal de ésta, y un método para hacer una limpieza (como recordaréis, al crear un ViewModel, éste nos dá la posibilidad de hacer una limpieza una vez que deje de ser útil.).</p>
<p>Bueno, ya tenemos creado la primera parte del esqueleto de la aplicación, ahora sólo nos queda añadir código a cada ViewModel.</p>
<p>Antes de eso, quiero explicar el proposito de este ejemplo.</p>
<p>El ejemplo en sí es el mismo que el anterior, con tu nombre y edad forma un saludo. En este caso, no puedes introducir la edad directamente en la casilla, sino que tienes que introducirla en otra ventana aparte.</p>
<p>Antes de nada vamos a instanciar la clase <i>Persona</i> y vamos a crear la propiedad Saludo:</p>
<pre class="brush: csharp;">
private Persona _unaPersona;
private string _saludo;

public Persona UnaPersona
{
	get { return _unaPersona; }
	set
	{
		_unaPersona = value;
		RaisePropertyChanged(&quot;UnaPersona&quot;);
	}
}

public string Saludo
{
	get { return _saludo; }
	set
	{
		_saludo = value;
		RaisePropertyChanged(&quot;Saludo&quot;);
	}
}
</pre>
<pre class="brush: csharp;">
public MainViewModel()
{
	_unaPersona = new Persona();
}
</pre>
<p>Ahora, empezamos con el botón que nos permitirá usar la otra ventana. Para ello creemos un <strike>evento</strike> comando que haga precisamente eso:</p>
<pre class="brush: csharp;">
public RelayCommand RecogerEdadCommand { get; private set;}
</pre>
<pre class="brush: csharp;">
RecogerEdadCommand = new RelayCommand(RecogerEdad);
</pre>
<pre class="brush: csharp;">
private void RecogerEdad()
{
	var edad = new EdadWindow();
	edad.ShowDialog();
}
</pre>
<p>Y bindeamos el botón al comando:</p>
<pre class="brush: xml;">
&lt;Button Content=&quot;Elegir edad&quot; HorizontalAlignment=&quot;Right&quot; Margin=&quot;0,116.96,82,0&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;75&quot;
        Command=&quot;{Binding RecogerEdadCommand}&quot;/&gt;
</pre>
<p>Con esto ya se abre la ventana, ¿Nada nuevo verdad? Simplemente instanciamos la ventana y la mostramos como un dialogo modal.</p>
<p>Vamos a escribir el código necesario en el <i>EdadViewModel</i> para recoger lo que escribamos y calcular nuestra edad, además crearemos el comando del botón y lo bindearemos, escribiré todo el código para simplificar, total, no es nada nuevo:</p>
<p><b>EdadViewModel</b></p>
<pre class="brush: csharp;">
using System;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;

namespace EjemploMessenger.ViewModel
{
    public class EdadViewModel : ViewModelBase
    {
        public int Dia { get; set; }
        public int Mes { get; set; }
        public int Año { get; set; }

        public RelayCommand CalcularEdadCommand { get; private set; }

        public EdadViewModel()
        {
            CalcularEdadCommand = new RelayCommand(CalcularEdad);
        }

        private void CalcularEdad()
        {
            var añoActual = DateTime.Now.Year;
            var mesActual = DateTime.Now.Month;

            var edad = añoActual - Año;

            if (Mes &gt; mesActual)
                edad += 1;
        }
    }
}
</pre>
<p>Nada que deba sorprendernos.</p>
<p><b>EdadWindow.xaml</b></p>
<pre class="brush: xml;">
&lt;Window x:Class=&quot;EjemploMessenger.EdadWindow&quot;
        xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
        xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
        xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
        xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
        mc:Ignorable=&quot;d&quot;
        Title=&quot;Ejemplo Messaging&quot;
        DataContext=&quot;{Binding Edad, Source={StaticResource Locator}}&quot; Height=&quot;253&quot; Width=&quot;334&quot; Background=&quot;#FFFFD1FA&quot; ResizeMode=&quot;NoResize&quot;&gt;

    &lt;Grid&gt;
    	&lt;Label Content=&quot;Fecha Nacimiento (xx/xx/xxxx):&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;8,8,0,0&quot; VerticalAlignment=&quot;Top&quot;/&gt;
    	&lt;Label Content=&quot;Dia:&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;8,46,0,0&quot; VerticalAlignment=&quot;Top&quot;/&gt;
    	&lt;Label Content=&quot;Mes:&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;8,75.96,0,0&quot; VerticalAlignment=&quot;Top&quot;/&gt;
    	&lt;Label Content=&quot;Año:&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;8,105.92,0,0&quot; VerticalAlignment=&quot;Top&quot;/&gt;
    	&lt;TextBox Margin=&quot;0,50,97.254,0&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;184&quot; Height=&quot;21.96&quot; HorizontalAlignment=&quot;Right&quot;
                 Text=&quot;{Binding Dia}&quot;/&gt;
    	&lt;TextBox Margin=&quot;0,79.96,97.254,0&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;184&quot; HorizontalAlignment=&quot;Right&quot;
                 Text=&quot;{Binding Mes}&quot;/&gt;
    	&lt;TextBox Margin=&quot;0,109.92,97.254,0&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;184&quot; HorizontalAlignment=&quot;Right&quot;
                 Text=&quot;{Binding Año}&quot;/&gt;
        &lt;Button Content=&quot;Aceptar&quot; Margin=&quot;155.746,146,97.254,0&quot; VerticalAlignment=&quot;Top&quot;
                Command=&quot;{Binding CalcularEdadCommand}&quot; Click=&quot;OnAceptar&quot; /&gt;

    &lt;/Grid&gt;
&lt;/Window&gt;
</pre>
<p>Aqui el código de la ventana, no he puesto ninguna validación (¿Material para otro artículo? <img src='http://blog.foxandxss.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> , asi que vamos a suponer que introducimos los datos correctos). Además de eso, tenemos los bindings puestos y &#8230; ¿El botón tiene un comando y un evento a la vez? Sí. Puedes tener ambas cosas a la vez.</p>
<p>En este caso, necesito crear un evento en el botón para que haga algo relacionado con la ventana en sí y no con datos (O sea, trabajo para el code-behind en este caso). Lo lógico es que cerremos la ventana a la hora de hacer click, pero claro, no podemos hacer eso desde el ViewModel, así que necesitamos hacerlo en el code-behind. Así que el comando calcula la edad y el evento cierra la ventana.</p>
<pre class="brush: csharp;">
private void OnAceptar(object sender, RoutedEventArgs e)
{
	Close();
}
</pre>
<p>Guay del paraguay, pero la edad está en <i>EdadViewModel</i> y la necesitamos en la instancia de <i>Persona</i> que está en <i>MainViewModel</i>. ¿Cómo la pasamos alli? ¿Cómo podemos hacer que <i>MainViewModel</i> obtenga la edad?</p>
<p>La solución más típica era la de crear un método en el code-behind de la ventana el cual nos devuelve lo que esa ventana a generado o directamente acceder a las propiedades.</p>
<p>Esta solución se ha usado mucho siempre, pero tiene un gran problema y es precisamente el que MVVM intenta resolver; el acople entre clases.</p>
<p>Si el método que abre la ventana necesita también saber como acceder a los datos que ésta genera, ya esas dos clases dependerían mucho la una de la otra.</p>
<p>Como solución a esto (y a otros muchos casos de este estilo) nació la clase <b>Messenger</b>. Ésta clase sirve para enviar mensajes de un lado a otro en una aplicación, de forma totalmente desacoplada.</p>
<p>La idea es que un objeto se registra para recibir mensajes de cierto tipo pero no sabe quien lo envia, simplemente espera dichos mensajes y nada más. Con esto conseguimos el buscado desacople.</p>
<p>Como se suele decir: Más vale un ejemplo que mil palabras ( ¿O eran imágenes? ):</p>
<p>¿Qué necesita recibir el <i>MainViewModel</i> para funcionar?, ¿La edad, no? ¿Qué tipo de variable es la edad? Un int.</p>
<p>Así que vamos a registrar mensajes que vengan con un int como parámetro. ¿Cómo se registra una clase para recibir mensajes?</p>
<p>Se usa el método estático <i>Register</i> de la clase <i>Messenger</i>:</p>
<pre class="brush: csharp;">
void Register&lt;T&gt;(object recipiente, Action&lt;T&gt; action);
</pre>
<p>El primer parámetro es el objeto el cual se está registrando al mensaje, y el segundo es el método que se ejecutará cuando se reciba un mensaje</p>
<p>Vamos a registrar nuestro mensaje en el <i>MainViewModel</i> para que éste quede a la escucha de dichos mensajes, para ello escribimos en el constructor:</p>
<pre class="brush: csharp;">
Messenger.Default.Register&lt;int&gt;(this, edad =&gt; UnaPersona.Edad = edad);
</pre>
<p>Decimos que queremos escuchar todos los mensajes que traigan un int y que cuando recibamos uno, asignará el int que traiga consigo a la propiedad <i>Edad</i> de <i>UnaPersona</i>.</p>
<p>¿Fácil verdad?</p>
<p>Ahora falta que alguien los envié, y en este caso sería <i>EdadViewModel</i>. Para enviar mensajes se usa el siguiente método estático de la clase <i>Messenger</i>:</p>
<pre class="brush: csharp;">
void Send&lt;T&gt;(T message);
</pre>
<p>Simplemente el tipo de mensaje a enviar y el mensaje en sí.</p>
<p>Así que dentro del método <i>CalcularEdad</i> después del <i>if</i> ponemos:</p>
<pre class="brush: csharp;">
Messenger.Default.Send(edad);
</pre>
<p>No debe sorprenderos, es bastante sencillo, enviamos edad a través de un mensaje.</p>
<p>Eso sí, este mensaje le llegara a <b>TODOS</b> los que estén escuchando mensajes que vengan con un int. En este caso da igual, pero si tenemos otras clases esperando mensajes también, pues puede liar. Así que tenemos acceso a otro tipo de método:</p>
<pre class="brush: csharp;">
void Send&lt;TMessage, TTarget&gt;(TMessage message);
</pre>
<p>Con ese método podemos especificar a quien queremos enviarle este mensaje, así que vamos a modificar nuestro ejemplo:</p>
<pre class="brush: csharp;">
Messenger.Default.Send&lt;int, MainViewModel&gt;(edad);
</pre>
<p>Mejor <img src='http://blog.foxandxss.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>La clase <i>Messenger</i> es mucho más que eso, es capaz de intercambiar varios tipos de mensajes, normalmente para cosas más especificas. Vamos a mostrar otro tipo más de mensaje.</p>
<p>Antes de hacerlo, conviene pensar que quizá el ejemplo que ya he dado quizá no sea la mejor solución al 100%. La ventana de la Edad puede ser una ventana genérica usada por muchas partes de tu software, y si el mensaje que envía ya va dirigido a alguien en concreto, nos jodería el invento. Sin embargo, la clase que usa esa supuesta ventana genérica suele usar esa y no intercambiar con 20 más, quiero decir, debería quizá la clase que está usando dicha ventana ser la que especifique claramente a quien va a usar y dicha ventana ser genérica para que cualquiera pueda usarla y cualquiera pueda recibir sus mensajes.</p>
<p>¿Cómo hacemos eso?</p>
<p>A bote pronto podemos usar otro tipo de mensaje, <i>NotificationMessageAction<t></i></p>
<p>Éste tipo de mensaje envía una notificacion y además espera que la clase que lo reciba le conteste.</p>
<p>Probemos:</p>
<p>En <i>EdadViewModel</i> registramos el mensaje, en este caso es un poco más complejo:</p>
<pre class="brush: csharp;">
private NotificationMessageAction&lt;int&gt; _message;
</pre>
<p>en el constructor:</p>
<pre class="brush: csharp;">
Messenger.Default.Register&lt;NotificationMessageAction&lt;int&gt;&gt;(
		this,
		m =&gt; _message = m);
</pre>
<p>y dentro de <i>CalcularEdad</i>:</p>
<pre class="brush: csharp;">
_message.Execute(edad);
</pre>
<p>El mensaje del tipo <i>NotificationMessageAction<t></i> nos ofrece una forma de contestar a dicho mensaje, o sea, ejecutar el callback. Para ello necesitamos usar el método <i>Execute</i> de dicho mensaje, necesitamos hacer una copia del mensaje para poder acceder a dicho mensaje desde cualquier sitio de la clase.</p>
<p>Una vez tengamos el mensaje registrado y copiado, simplemente tenemos que ejecutar el método <i>Execute</i> para devolver el mensaje, en este caso, la edad.</p>
<p>Ahora bien, en la clase <i>MainViewModel</i> necesitamos enviar dicho mensaje y manejar el callback:</p>
<pre class="brush: csharp;">
var edad = new EdadWindow();
Messenger.Default.Send(new NotificationMessageAction&lt;int&gt;(&quot;Dame la edad&quot;, laEdad =&gt; UnaPersona.Edad = laEdad));
edad.ShowDialog();
</pre>
<p>Como veis, enviamos un nuevo mensaje del tipo <i>NotificationMessageAction<int></i>. Entre otras sobrecargas del método, tenemos una que recibe como primer parámetro el mensaje que queramos enviar (en este caso, la clase que recibe el mensaje no va a usar dicho mensaje, asi que le pasamos cualquier cosa) y como segundo parámetro recibe un delegado del tipo <i>Action<t></i>, usamos una lambda para que nos almacene la respuesta <i>UnaPersona.Edad</i>.</p>
<p>Así que la idea es: Enviamos mensaje > el recipiente lo recibe y almacena > cuando tiene la respuesta la envia > el que envió el mensaje recibe respuesta y hace algo con ella.</p>
<p>Bueno, con este tipo de mensaje conseguimos que <i>EdadWindow</i> pueda ser usada por otras muchas clases ya que ésta no sabe en ningun momento quien la usa, simplemente envia la edad como respuesta y bueno le da igual quien lo reciba o que haga con ello jeje.</p>
<p>Y bueno, se nos olvidaba que el programa tiene que enviar un saludo&#8230; Ya tenemos el nombre y podemos conseguir la edad, así que vamos a registrar el comando para el saludo, el cual es exactamente igual que el comando del articulo anterior:</p>
<pre class="brush: csharp;">
public RelayCommand AceptarCommand { get; private set; }
[/csharp

[csharp]
AceptarCommand = new RelayCommand(Aceptar);
</pre>
<pre class="brush: csharp;">
private void Aceptar()
{
	Saludo = string.Format(&quot;Hola, mi nombre es {0} y tengo {1} años.&quot;,
		UnaPersona.Nombre, UnaPersona.Edad);
}
</pre>
<pre class="brush: xml;">
&lt;Button Content=&quot;Aceptar&quot; Margin=&quot;0,155,82,0&quot; VerticalAlignment=&quot;Top&quot; HorizontalAlignment=&quot;Right&quot; Width=&quot;74&quot;
        Command=&quot;{Binding AceptarCommand}&quot;/&gt;
</pre>
<p>Para terminar, os dejo la lista de mensajes que teneis y una descripción de ellos:</p>
<ul>
<li><b>MessageBase</b>: Es el mensaje simple, puede llevar informacion opcional del que envía el mensaje.</li>
<li><b>GenericMessage<t></b>: Un mensaje simple que lleva una propiedad del tipo T.</li>
<li><b>NotificationMessage</b>: Usado para enviar una notificación (un string) hacia un recipiente. Por ejemplo podemos guardar una lista de notificaciones en una clase y enviarlas a un recipiente.</li>
<li><b>NotificationMessage<t></b>: El mismo mensaje que el anterior pero enviado además una propiedad del tipo T.</li>
<li><b>NotificationMessageAction</b>: Permite enviar un mensaje a un recipiente y le permite a dicho recipiente contestar al mensaje.</li>
<li><b>NotificationMessageAction<t></b>: Lo mismo que el anterior pero enviando además una propiedad del tipo T.</li>
<li><b>DialogMessage</b>: Usado para pedirle a un recipiente (normalmente a una vista) que muestre un dialogo y notificar el resultado al que envió dicho mensaje. El recipiente puede mostrar cómo mostrar dicho dialogo, por ejemplo usando un MessageBox o un popup personalizado.</li>
<p><b>PropertyChangedMessage<t></b>: Usado notificar a todo el mundo que una propiedad a cambiado (en la clase que envia dicho mensaje). Es lo mismo que usar el evento <i>PropertyChanged</i> solo que esto lo hace de una más simple.</li>
</ul>
<p>Bueno, y dicho esto dejo por finalizado este artículo, adjunto el proyecto también:</p>
<p><a href='http://foxandxss.net/CosasBlog/mvvmlight/messenger/EjemploMessenger.zip' >EjemploMessenger.zip</a></p>
<p>Hasta la próxima <img src='http://blog.foxandxss.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.foxandxss.net/index.php/mvvm-light-messenger/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>MVVM Light: Comandos</title>
		<link>http://blog.foxandxss.net/index.php/mvvm-light-comandos/</link>
		<comments>http://blog.foxandxss.net/index.php/mvvm-light-comandos/#comments</comments>
		<pubDate>Sun, 21 Mar 2010 18:44:16 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Articulos]]></category>
		<category><![CDATA[MVVM]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Windows Phone 7]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://blog.foxandxss.net/?p=205</guid>
		<description><![CDATA[Aquí vamos con la segunda parte del tutorial. Para este tutorial vamos a crear un ejemplito muy muy simple pero que nos ayudará a entender los conceptos básicos que es lo que realmente buscamos. Para empezar vamos a ir a la página de MVVM Light y bajarnos la última versión (la versión 3 a dia [...]]]></description>
			<content:encoded><![CDATA[<p>Aquí vamos con la segunda parte del tutorial.</p>
<p>Para este tutorial vamos a crear un ejemplito muy muy simple pero que nos ayudará a entender los conceptos básicos que es lo que realmente buscamos.</p>
<p>Para empezar vamos a ir a la página de MVVM Light y bajarnos la última versión (la versión 3 a dia de hoy)<br />
<a href="http://www.galasoft.ch/mvvm/installing/manually/"><br />
Página de MVVM Light</a></p>
<p>Que no os asuste la instalación, simplemente teneis que bajar los binarios y los templates para la versión de visual studio que estéis usando. Como extra también podéis bajar los snippets lo cual recomiendo.<br />
<span id="more-205"></span><br />
Cuando bajeis los 3 ficheros, lo descomprimís y solo es copiarlo donde corresponde, nada dificil (Si teneis problemas dejadme un comentario).</p>
<p>Una vez tienes MVVM Light instalado vamos a crear una nueva aplicación MVVM Light para WPF (Para Silverlight o Windows Phone 7 sería lo mismo realmente).</p>
<p>El template de MVVM Light es bastante bastante completito, nos vienen los directorios que tenemos que usar (con la excepción de Views aunque no sé por qué) y además nos crea ya una ventana con su ViewModel asociado. Además de un diccionario de estilos (MainSkin.xaml) en el cual podemos meter nuestros estilos de la ventana.</p>
<p>Por último, nos crea un ViewModelLocator el cual instancia en el App.xaml. ¿Para qué sirve esto?</p>
<p><i>ViewModelLocator</i> es el encargado de instanciar y mantener una referencia de cada ViewModel que existe en nuestra aplicación. Lo cual nos da ciertas ventajas, entre ellas poder asignar el DataContext de cada View en el xaml y no mediante código, lo cual nos permitirá diseñar nuestra aplicación en tiempo de diseño sin hacer ninguna floritura extra.</p>
<p>Ya en la próxima parte os explicaré como añadir más ViewModels al <i>ViewModelLocator</i> así que por ahora vamos a ignorarlo y seguir adelante.</p>
<p>Empezamos borrando el MainSkin.xaml puesto que no lo vamos a usar en este simple ejemplo.</p>
<p>Creamos en el modelo una clase llamada &#8220;Person&#8221; y le pones este código:</p>
<pre class="brush: csharp;">
using System.ComponentModel;

namespace EjemploMVVML.Model
{
    public class Person : INotifyPropertyChanged
    {
        private string _name;
        private int _age;

        public Person()
        {

        }

        public string Name
        {
            get { return _name; }
            set
            {
                _name = value;
                RaisePropertyChanged(&quot;Name&quot;);
            }
        }

        public int Age
        {
            get { return _age; }
            set
            {
                _age = value;
                RaisePropertyChanged(&quot;Age&quot;);
            }
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        private void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(
                    this,
                    new PropertyChangedEventArgs(propertyName)
                    );
            }
        }

        #endregion
    }
}
</pre>
<p>Como veis está en inglés puesto que luego vamos a usar este ejemplo en el artículo de localización, además es una <b>MUY</b> buena practica escribir todo el código en inglés (variables, comentarios, clases, todo).</p>
<p>Esta clase implementa <i>INotifyPropertyChanged</i> puesto que el modelo necesita notificar sus cambios de cara al <i>DataBinding</i>.</p>
<p>Normalmente yo suelo crear una clase llamada Notifier la cual implementa esta interfaz y luego heredo el modelo hereda de esta clase (siempre que no necesitemos heredar del modelo de otra clase y tengamos que implementar esta interfaz a mano como en el ejemplo).</p>
<p>Vamonos con la interfaz, os dejo el código, algo en plan rápido y guarrete ya que este artículo no tiene nada que ver con interfaces <img src='http://blog.foxandxss.net/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<pre class="brush: xml;">
&lt;Window
        xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
        xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
        xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
        xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
        mc:Ignorable=&quot;d&quot;
        x:Class=&quot;EjemploMVVML.MainWindow&quot;
        Title=&quot;Ejemplo MVVM&quot;
        Height=&quot;460&quot;
        Width=&quot;343&quot;
        Background=&quot;#FFA7F9FF&quot; ResizeMode=&quot;NoResize&quot;&gt;

	&lt;Window.DataContext&gt;
		&lt;Binding Path=&quot;Main&quot; Source=&quot;{StaticResource Locator}&quot;/&gt;
	&lt;/Window.DataContext&gt;

	&lt;Grid x:Name=&quot;LayoutRoot&quot;&gt;
		&lt;Label Content=&quot;Insert your name:&quot; Height=&quot;23&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;30,31,0,0&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;123&quot; /&gt;
		&lt;TextBox Height=&quot;25&quot; Margin=&quot;30,58,82,0&quot; VerticalAlignment=&quot;Top&quot;/&gt;
		&lt;Label Content=&quot;Insert your age:&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;30,87,0,0&quot; VerticalAlignment=&quot;Top&quot;/&gt;
		&lt;TextBox Margin=&quot;30,116.96,82,0&quot; VerticalAlignment=&quot;Top&quot; Height=&quot;25&quot;/&gt;
		&lt;Button Content=&quot;Accept&quot; Margin=&quot;0,155,82,0&quot; VerticalAlignment=&quot;Top&quot; HorizontalAlignment=&quot;Right&quot; Width=&quot;74&quot;/&gt;
		&lt;TextBox Margin=&quot;30,212.98,82,0&quot; IsReadOnly=&quot;True&quot; Height=&quot;25&quot; VerticalAlignment=&quot;Top&quot; d:LayoutOverrides=&quot;HorizontalAlignment, Height&quot;/&gt;
		&lt;Button Content=&quot;Reset&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;8,0,0,8&quot; VerticalAlignment=&quot;Bottom&quot; Width=&quot;75&quot;/&gt;
	&lt;/Grid&gt;
&lt;/Window&gt;
</pre>
<p>Lo importante de aquí, es ver como se ha definido el <b>DataContext</b> en la ventana. Hemos cogido la referencia del ViewModel que nos interesa (el MainViewModel) desde el <i>ViewModelLocator</i>. ¿Chulo verdad? <img src='http://blog.foxandxss.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Ahora vamonos al <i>MainViewModel</i>, uhm, ya tiene código por defecto&#8230; (Le he quitado algun comentario para simplificar el ejemplo):</p>
<pre class="brush: csharp;">
using GalaSoft.MvvmLight;

namespace EjemploMVVML.ViewModel
{
    public class MainViewModel : ViewModelBase
    {
        public string Welcome
        {
            get
            {
                return &quot;Welcome to MVVM Light&quot;;
            }
        }

        public MainViewModel()
        {
            if (IsInDesignMode)
            {
                // Code runs in Blend --&gt; create design time data.
            }
            else
            {
                // Code runs &quot;for real&quot;
            }
        }

        ////public override void Cleanup()
        ////{
        ////    // Clean up if needed

        ////    base.Cleanup();
        ////}
    }
}
</pre>
<p>Cada ViewModel heredará de ViewModelBase el cual nos provee de ciertos helpers que nos facilitarán la vida. Por ejemplo dicho ViewModelBase implementa ya el INotifyPropertyChanged y además nos provee de un método en el cual podemos hacer limpieza en caso de que sea necesaria (Una especie de destructor).</p>
<p>Además tenemos una propiedad bastante util, <b>IsInDesignMode</b> y ya el constructor viene listo para usarlo. Simplemente podemos colocar código dentro de <i>IsInDesignMode</i> para hacer uso del &#8220;Design-time DataContext&#8221; (Revisar el artículo si quereis saber qué es esto) y luego el código real dentro del else.</p>
<p>Como ya sabemos usar el Design-time DataContext y no tiene nada que ver con MVVM Light, vamos a borrar eso y escribir directamente el código real.</p>
<p>Vamos a borrar el método Cleanup y borrar la propiedad &#8220;Welcome&#8221; y dejar solo el costructor vacío.</p>
<p>Para empezar vamos a crear una instancia de la clase Person.</p>
<p>Normalmente el instanciar una clase que va a ser expuesta a la vista necesita 3 pasos:</p>
<p>Crear la instancia:</p>
<pre class="brush: csharp;">
private Person _aPerson;
</pre>
<p>Instanciarla en el constructor:</p>
<pre class="brush: csharp;">
_aPerson = new Person();
</pre>
<p>y crearle su propiedad con notificación de cambios:</p>
<pre class="brush: csharp;">
public Person APerson
{
    get { return _aPerson; }
    set
    {
        _aPerson = value;
        RaisePropertyChanged(&quot;APerson&quot;);
    }
}
</pre>
<p>Ya tenemos lista la instancia de Person para ser bindeada por la vista.</p>
<p>Vamos a bindear las 2 cajas (las de nombre y edad) a sus respectivas propiedades de la instancia de Person:</p>
<pre class="brush: xml;">
&lt;TextBox Height=&quot;25&quot; Margin=&quot;30,58,82,0&quot; VerticalAlignment=&quot;Top&quot;
         Text=&quot;{Binding APerson.Name}&quot;/&gt;
&lt;TextBox Margin=&quot;30,116.96,82,0&quot; VerticalAlignment=&quot;Top&quot; Height=&quot;25&quot;
         Text=&quot;{Binding APerson.Age}&quot;/&gt;
</pre>
<p>Nada nuevo aquí, solo hacemos los binding como estamos acostumbrados a hacer.</p>
<p>También vamos a necesitar bindear el tercer TextBox el cual contendrá un pequeño saludo.</p>
<p>Para ello creamos una propiedad en el ViewModel:</p>
<pre class="brush: csharp;">
private string _greeting = string.Empty;

public string Greeting
{
    get { return _greeting; }
    set
    {
        _greeting = value;
        RaisePropertyChanged(&quot;Greeting&quot;);
    }
}
</pre>
<p>y bindeamos la tercera caja:</p>
<pre class="brush: xml;">
&lt;TextBox Margin=&quot;30,212.98,82,0&quot; IsReadOnly=&quot;True&quot; Height=&quot;25&quot; VerticalAlignment=&quot;Top&quot;
         Text=&quot;{Binding Greeting}&quot;/&gt;
</pre>
<p>Ahora, si ejecutamos la aplicación&#8230;</p>
<p><a href="http://foxandxss.net/CosasBlog/mvvmlight/comandos/1.JPG"><img alt="" src="http://foxandxss.net/CosasBlog/mvvmlight/comandos/1.JPG" class="alignnone" width="343" height="460" /></a></p>
<p>Vemos que no hace nada, los botones no responden (¡Sorpresa!)</p>
<p>¿Cómo podemos solucionar esto?</p>
<p>Ah claro, creamos un evento por cada botón y asunto solucionado.</p>
<p>Pero&#8230; Habíamos dicho que todo el trabajo referente a datos se hacía en el ViewModel y no en el Code-Behind de la vista&#8230; Bueno, delegamos la acción al ViewModel desde el Code-Behind y ya está.</p>
<p>Vale, funciona, pero&#8230; ¿No es un poco guarrete esto que proponemos? Sí, sin duda.</p>
<p>WPF y Silverlight ofrecen algo más especializado para estas cosas que los propios eventos, ese algo se llama &#8220;Commands&#8221; o &#8220;Comandos&#8221; en castellano.</p>
<p>¿Qué ofrecen estos _Commands_ como ventaja frente a los eventos? Muchas. Las iremos viendo a lo largo del resto del artículo.</p>
<p>Para empezar, los comandos no se definen en el Code-Behind, sino directamente en el DataContext, que en nuestro caso es en el MainViewModel. Con esto, nuestro código será mucho más limpio puesto que no tenemos que delegar el trabajo desde el Code-Behind y asi dejamos a éste para lo que realmente está, para hacer todo lo referente a la vista y no a los datos.</p>
<p>Así que vamos al lío.</p>
<p>¿Cómo se crea un comando?</p>
<p>Originalmente quizá crear un comando no era tan facil como crear un evento, pero gracias a la comunidad tenemos unas clases que harán que crear comandos sea incluso más facil que crear eventos.</p>
<p>MVVM Light incluye una de esas clases, <b>RelayCommand</b></p>
<p>Usar un RelayCommand es lo más facil del mundo, empezamos por crear el comando en sí como una propiedad autocompletada del MainViewModel:</p>
<pre class="brush: csharp;">
public RelayCommand AcceptCommand { get; private set; }
</pre>
<p>Los comandos por convención incluyen la palabra <i>Command</i> al final.</p>
<p>Ahora creamos el comando en el Constructor:</p>
<pre class="brush: csharp;">
AcceptCommand = new RelayCommand(Accept);
</pre>
<p>El constructor del RelayCommand recibe un delegado (Comunmente llamado el parametro <i>Execute</i> pues será el que ejecute código) del tipo <b>Action</b> el cual espera un método que no acepte parámetros y tampoco devuelva nada, así que le hemos pasado el método &#8220;Accept&#8221; al RelayCommand, así que vamos a crear dicho método (sin parametro y devolviendo void):</p>
<pre class="brush: csharp;">
private void Accept()
{
	Greeting = string.Format(&quot;Hello, my name is {0} and Im {1} years old.&quot;,
		APerson.Name, APerson.Age);
}
</pre>
<p>Ya solo nos queda bindear el botón Accept al comando:</p>
<pre class="brush: xml;">
&lt;Button Content=&quot;Accept&quot; Margin=&quot;0,155,82,0&quot; VerticalAlignment=&quot;Top&quot; HorizontalAlignment=&quot;Right&quot; Width=&quot;74&quot;
        Command=&quot;{Binding AcceptCommand}&quot;/&gt;
</pre>
<p>Tan fácil como esperabas <img src='http://blog.foxandxss.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Ejecutamos la aplicación y&#8230; Funciona!</p>
<p><a href="http://foxandxss.net/CosasBlog/mvvmlight/comandos/2.JPG"><img alt="" src="http://foxandxss.net/CosasBlog/mvvmlight/comandos/2.JPG" class="alignnone" width="343" height="460" /></a></p>
<p>Vamos a crear ahora el comando para el botón reset, seguro que ya sabréis hacerlo por vosotros mismos&#8230;</p>
<pre class="brush: csharp;">
public RelayCommand ResetCommand { get; private set; }
</pre>
<pre class="brush: csharp;">
ResetCommand = new RelayCommand(Reset);
</pre>
<pre class="brush: csharp;">
private void Reset()
{
	APerson = new Person();
	Greeting = string.Empty;
}
</pre>
<pre class="brush: xml;">
&lt;Button Content=&quot;Reset&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;8,0,0,8&quot; VerticalAlignment=&quot;Bottom&quot; Width=&quot;75&quot;
		Command=&quot;{Binding ResetCommand}&quot;/&gt;
</pre>
<p>Creo que no harán falta las explicaciones aquí, ¿Verdad?</p>
<p>Ahora probemos una cosa&#8230; Abrimos la aplicación y le damos a Accept&#8230;</p>
<p><a href="http://foxandxss.net/CosasBlog/mvvmlight/comandos/3.JPG"><img alt="" src="http://foxandxss.net/CosasBlog/mvvmlight/comandos/3.JPG" class="alignnone" width="343" height="460" /></a></p>
<p>Uh, esto ya no mola tanto&#8230; ¡Ah! Ya lo tengo, pongo el botón como disabled y cuando rellene los dos textbox lo pongo enabled&#8230; Uhm, la idea es buena, pero&#8230; ¿Cómo lo implemento? Podría crear unos eventos que comprobaran que los textbox tienen información y luego desbloquear el botón o algo. Nah, muy dificil, mejor compruebo a la hora de hacer click de que haya info, en caso de no haberla que suelte un MessageBox diciendo que has de rellenar las cajas o mejor, no hago nada, se supone que si no escribes algo no va a valer.</p>
<p>Bueeeno, vamos a hacerlo bien, que lo importante en una aplicación con interfaces es la experiencia de usuario (UX).</p>
<p>Los comandos tienen la capacidad de saber cuando pueden ser ejecutados y cuando no. La forma que tienen de avisar de que no pueden ser ejecutados es simplemente bloqueando el control (¡Justo lo que queremos!).</p>
<p>Para ello, RelayCommand acepta otro delegado (éste comunmente llamado <i>CanExecute</i>), en este caso del tipo <b>Func<bool></b> el cual no acepta ningun valor y a la vez devuelve un bool, el cual si es true el comando se puede ejecutar y si es false, pues lo contrario.</p>
<p>Antes que nada, necesitamos una forma de comprobar si los atributos de la clase están &#8220;rellenos&#8221; o no, para ello vamos a implementar una pequeña propiedad en la clase <b>Person</b>:</p>
<pre class="brush: csharp;">
public bool IsValid
{
	get
	{
		return _name != string.Empty &amp;amp;&amp;amp; _age &gt; 0;
	}
}
</pre>
<p>Vamos a modificar nuestro <i>AcceptCommand</i></p>
<p>En el constructor lo cambiamos por:</p>
<pre class="brush: csharp;">
AcceptCommand = new RelayCommand(Accept, CanAccept);
</pre>
<p>La convención también suele decir que los métodos para comprobar si un comando se puede ejecutar o no van prefijados por <i>Can</i>.</p>
<p>Ahora escribámos el método:</p>
<pre class="brush: csharp;">
private bool CanAccept()
{
	return APerson.IsValid;
}
</pre>
<p>Si ejecutamos el código, vemos que el botón Accept está bloqueado:</p>
<p><a href="http://foxandxss.net/CosasBlog/mvvmlight/comandos/4.JPG"><img alt="" src="http://foxandxss.net/CosasBlog/mvvmlight/comandos/4.JPG" class="alignnone" width="343" height="460" /></a></p>
<p>Para desbloquearlo deberemos rellenar los 2 textboxes primero.</p>
<blockquote><p>
<b>NOTA:</b> Por defecto el binding se hace cuando el campo pierde el foco, así que hasta que no le quitemos el foco a la ultima caja que rellenemos, no se activará el control. Esto puede ser modificado cambiando el modo del binding a <i>PropertyChanged</i>.
</p></blockquote>
<p>Una de las cosas buenas de los RelayCommands es que aceptan un delegado, y en este caso el CanAccept es simplemente una linea&#8230;</p>
<p>Así que vamos a borrar el método CanAccept entero y vamos a modificar la inicialización del RelayCommand para que reciba una lambda:</p>
<pre class="brush: csharp;">
AcceptCommand = new RelayCommand(Accept, () =&gt; APerson.IsValid);
</pre>
<p>Te quitas 4 líneas de encima.</p>
<p>Vamos a meterle una nueva feature a la aplicación, una que nos diga el número de caracteres que tiene el saludo.</p>
<p>Vamos a la vista y debajo del bóton reset insertamos:</p>
<pre class="brush: xml;">
&lt;TextBox Margin=&quot;30,0,82,120.04&quot; VerticalAlignment=&quot;Bottom&quot; RenderTransformOrigin=&quot;0.7,-1.23&quot; Height=&quot;25&quot; IsReadOnly=&quot;True&quot;/&gt;
&lt;Button Content=&quot;Count&quot; HorizontalAlignment=&quot;Right&quot; Margin=&quot;0,0,82,86.04&quot; VerticalAlignment=&quot;Bottom&quot; Width=&quot;75&quot;/&gt;
</pre>
<p>Nada extraño, bueno, código feo de Blend, pero no nos preocupa eso para el tutorial (pero si para nuestras aplicaciones reales ehh <img src='http://blog.foxandxss.net/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> )</p>
<p>¿Cómo vamos a contar los carácteres del mensaje? En el mundo real simplemente bindeariamos la nueva caja a &#8220;Greeting.Length&#8221; y asunto solucionado, pero como esto no es el mundo real y sí un artículo de aprendizaje, vamos a usar otro método el cual nos será util para otras muchas cosas en dicho mundo real <img src='http://blog.foxandxss.net/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<p>Los comandos nos permiten la posibilidad de enviar un parámetro con ellos, así que vamos a aprovechar eso para enviar el numero de caracteres directamente sacado del textbox del Greeting.</p>
<p>Para ello empezamos dandole un nombre a dicho TextBox:</p>
<pre class="brush: xml;">
&lt;TextBox x:Name=&quot;Greet&quot; Margin=&quot;30,212.98,82,0&quot; Height=&quot;25&quot; IsEnabled=&quot;True&quot; VerticalAlignment=&quot;Top&quot;
         Text=&quot;{Binding Greeting}&quot; IsReadOnly=&quot;True&quot; /&gt;
</pre>
<p>Ahora nos vamos con la creación del comando:</p>
<pre class="brush: csharp;">
public RelayCommand&lt;int?&gt; CountCommand { get; private set; }
</pre>
<p>Como veis, ahora usamos una versión genérica del RelayCommand que acepta un parámetro pero&#8230;. ¿Por qué <i>int?</i> y no un int normal?</p>
<p>Atención a esto, ya que probablemente esto solo sea suficiente para leer el artículo.</p>
<p>El RelayCommand va a intentar comparar el parámetro con <i>null</i>, un tipo primitivo no puede almacenar null, así que comparar un int contra null dará una preciosa excepción la mar de maja.</p>
<p>Entonces existen versiones nullables de los tipos primitivos, para usar esos tipos hay que colocar la interrogación detrás del tipo, int?, double?, bool?, etc.</p>
<p>Con decir que yo pasé horas investigando esto e incluso terminé reescribiendo parte de la clase para que no reventara&#8230; Oye, ya no hacía falta pasarle ningún nullable, pero vamos, ya que se como va, os lo explico bien <img src='http://blog.foxandxss.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Pasemos a lo siguiente, inicializar el comando:</p>
<pre class="brush: csharp;">
CountCommand = new RelayCommand&lt;int?&gt;(Count, noused =&gt; Greeting != string.Empty);
</pre>
<p>¿Qué es eso de noused? El parámetro que pasamos con el comando lo recibirá tanto el &#8220;Execute&#8221; como el &#8220;CanExecute&#8221; y en este caso, el &#8220;CanExecute&#8221; no necesita para nada ese parámetro, aun asi, tiene que recibirlo, asi que le pongo de nombre &#8220;noused&#8221; para dar a entender que no lo necesitamos. Aparte de eso, comprobamos que ya se haya creado el mensaje del greeting para activar el botón.</p>
<p>Antes de implementar el método Count necesitamos una propiedad donde alojar el mensaje con el numero de caracteres, tal y como hicimos con la propiedad Greeting:</p>
<pre class="brush: csharp;">
private string _countMessage = string.Empty;

public string CountMessage
{
	get { return _countMessage; }
	set
	{
		_countMessage = value;
		RaisePropertyChanged(&quot;CountMessage&quot;);
	}
}
</pre>
<p>y ahora la bindeamos a la caja:</p>
<pre class="brush: xml;">
&lt;TextBox Margin=&quot;30,0,82,120.04&quot; VerticalAlignment=&quot;Bottom&quot; RenderTransformOrigin=&quot;0.7,-1.23&quot; Height=&quot;25&quot; IsReadOnly=&quot;True&quot;
		 Text=&quot;{Binding CountMessage}&quot;/&gt;
</pre>
<p>Ahora vamos a crear el método &#8220;Count&#8221;:</p>
<pre class="brush: csharp;">
private void Count(int? characters)
{
	CountMessage = string.Format(&quot;Greeting has {0} characters.&quot;, characters);
}
</pre>
<p>Lo unico que queda es bindear el comando al botón:</p>
<pre class="brush: xml;">
&lt;Button Content=&quot;Count&quot; HorizontalAlignment=&quot;Right&quot; Margin=&quot;0,0,82,86.04&quot; VerticalAlignment=&quot;Bottom&quot; Width=&quot;75&quot;
		Command=&quot;{Binding CountCommand}&quot; CommandParameter=&quot;{Binding Text.Length, ElementName=Greet}&quot;/&gt;
</pre>
<p>¿No es difícil verdad? Hacemos uso de <i>CommandParameter</i> para enviar un parámetro, en este caso el numero de carácteres del textbox &#8220;Greet&#8221;.</p>
<p><a href="http://foxandxss.net/CosasBlog/mvvmlight/comandos/5.JPG"><img alt="" src="http://foxandxss.net/CosasBlog/mvvmlight/comandos/5.JPG" class="alignnone" width="343" height="460" /></a></p>
<p>Todavía queda algo más. No todos los controles implementan comandos y normalmente estos comandos son ejecutados cuando haces click en el control. No siempre va a ser eso lo que necesitas y muchas veces directamente no vas a tener opción a ningun tipo de comando. Así que en vez de tirar de eventos, podemos usar una librería que trae MVVM Light, <b>EventToCommand</b>, con esta librería podemos &#8220;transformar&#8221; cualquier evento a un comando.</p>
<p>Para evitar hacer más complejo el ejemplo, vamos a suponer que los botones no tienen comandos y queremos transformar su evento &#8220;Click&#8221; en un comando.</p>
<p>Para ello tenemos que importar estos namespaces en nuestra ventana:</p>
<pre class="brush: xml;">
xmlns:i=&quot;clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity&quot;
xmlns:cmd=&quot;clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4&quot;
</pre>
<p><b>NOTA:</b> Si estais usando Visual Studio 2008 con WPF3.5 has de cambiar uno de los namespaces:</p>
<pre class="brush: xml;">
xmlns:cmd=&quot;clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras&quot;
</pre>
<p>Bueno, ahora nos vamos a un botón cualquiera (por ejemplo reset) y lo dejamos así:</p>
<pre class="brush: xml;">
&lt;Button Content=&quot;Reset&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;8,0,0,8&quot; VerticalAlignment=&quot;Bottom&quot; Width=&quot;75&quot;&gt;
	&lt;i:Interaction.Triggers&gt;
		&lt;i:EventTrigger EventName=&quot;Click&quot;&gt;
			&lt;cmd:EventToCommand Command=&quot;{Binding ResetCommand, Mode=OneWay}&quot;/&gt;
		&lt;/i:EventTrigger&gt;
	&lt;/i:Interaction.Triggers&gt;
&lt;/Button&gt;
</pre>
<p>No es tan complejo, ¿no? Hemos seleccionado el tipo de evento que estará bindeado al comando y luego hemos dicho cual es el comando <img src='http://blog.foxandxss.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  No hemos tenido que modificar el ViewModel siquiera.</p>
<p>Esto suele venir bien por ejemplo para ejecutar un comando cada vez que seleccionas un elemento en un ListBox, ya que <i>SelectionChanged</i> no puede ser bindeado a un comando por defecto.</p>
<p>Y bueno, hasta aquí la explicación de comandos, más largo de lo que esperaba, y espero que no se olvide nada.</p>
<p>Os dejo un zip con el código fuente (Visual Studio 2010) para los que no queráis hacerlo mientras lo leeis (¡Mal! <img src='http://blog.foxandxss.net/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> )</p>
<p><a href='http://foxandxss.net/CosasBlog/mvvmlight/comandos/EjemploMVVML.zip' >Código fuente</a></p>
<p>Espero vuestros comentarios (que va a ser que no habrán) y nos vemos en la próxima parte.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.foxandxss.net/index.php/mvvm-light-comandos/feed/</wfw:commentRss>
		<slash:comments>31</slash:comments>
		</item>
		<item>
		<title>MVVM Light: ¿Qué es?</title>
		<link>http://blog.foxandxss.net/index.php/mvvm-light-que-es/</link>
		<comments>http://blog.foxandxss.net/index.php/mvvm-light-que-es/#comments</comments>
		<pubDate>Sat, 20 Mar 2010 18:30:59 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Articulos]]></category>
		<category><![CDATA[MVVM]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Windows Phone 7]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://blog.foxandxss.net/?p=195</guid>
		<description><![CDATA[Empezamos con la primera parte de la serie de artículos de MVVM Light, en concreto con la gran pregunta: ¿Qué es exactamente MVVM o MVVM Light? Vamos a empezar explicando qué es MVVM: MVVM es un patrón de diseño que entra dentro de los llamados patrones mv* como podrían ser: MVC MVP Ambos son patrones [...]]]></description>
			<content:encoded><![CDATA[<p>Empezamos con la primera parte de la serie de artículos de MVVM Light, en concreto con la gran pregunta:</p>
<h3>¿Qué es exactamente MVVM o MVVM Light?</h3>
<p>Vamos a empezar explicando qué es MVVM:<br />
<span id="more-195"></span><br />
MVVM es un patrón de diseño que entra dentro de los llamados patrones <i>mv*</i> como podrían ser:</p>
<ul>
<li>MVC</li>
<li><a href="http://blog.foxandxss.net/index.php/ejemplo-mvp-con-wpf/">MVP</a></li>
</ul>
<p>Ambos son patrones muy usados a la hora de crear la arquitectura de la aplicación. De MVP ya hemos hablado en otro <a href="http://blog.foxandxss.net/index.php/ejemplo-mvp-con-wpf/">artículo</a> y bueno, <b>MVVM</b> es una alternativa mejor a la hora de desarrollar aplicaciones tanto <b>WPF</b>, <b>Silverlight</b> y <b>Windows Phone 7</b>.</p>
<p>Antes de entrar en explicaciones concretas, os dejo un diagrama que os ayudará a entender las cosas:</p>
<p><a href="http://foxandxss.net/CosasBlog/mvvmlight/diagrama.gif"><img alt="" src="http://foxandxss.net/CosasBlog/mvvmlight/diagrama.gif" class="alignnone" width="500" height="400" /></a></p>
<p>Como podéis ver aquí, existen tres componentes en este patrón: <b>M</b>odel-<b>V</b>iew-<b>V</b>iew<b>M</b>odel, osea, <b>MVVM</b>.</p>
<p>En el <i>Modelo</i> irá toda la lógica de negocio de nuestra aplicación, como podría ser la clase <i>Libro</i>, <i>Persona</i>, <i>Factura</i>&#8230; Este tipo de clases tambien son llamadas <i>POCO&#8217;s</i> (Plain Old C# Objects), o sea, clases básicas sin ninguna funcionalidad de WPF ni Silverlight.</p>
<p>El <i>ViewModel</i> como su nombre indica, es el modelo de la vista, o dicho de otra forma, es donde irá todo el trabajo que la vista necesita hacer. Si tomamos como ejemplo mi <b>ApuntaNotas</b>, el ViewModel se encargaría de añadir nuevas notas cuando el usuario hace click en el botón, borrar notas, renombrarlas, cambiarles la categoría&#8230; En resumen, el ViewModel hace todo el trabajo de la vista que tiene que ver con datos.</p>
<p>La <i>Vista</i> como cabe de esperar será la que contendrá el XAML de nuestra aplicación WPF, Silverlight o Windows Phone 7. Nada raro aquí.</p>
<p>Eso si, todo el mundo se pregunta&#8230; ¿Y el Code-Behind de la vista? ¿Vale para algo?</p>
<p>Por supuesto que sí, es un tema controvertido quizá, el code-behind en aplicaciones WinForms por ejemplo ha sido siempre usado para hacer todo el trabajo de la vista. Luego dijeron que eso estaba mal y decidieron delegar todo ese trabajo a un controlador y dejaron el code-behind inutil sin ningún uso.</p>
<p>En MVVM el code-behind es bastante usado, ¿Para qué exactamente? El code-behind lo usaremos para <b>hacer todo el trabajo que tiene que ver con la vista en sí</b>. ¿Recuerdas que dije que el ViewModel haría todo el trabajo de la vista relacionado con datos? Pues ahora el code-behind hace el trabajo restante, o sea, lo que tiene que ver exclusivamente con la vista.</p>
<p>Por ejemplo&#8230; Imaginad que si seleccionamos un elemento de un ListBox queremos que cierto TextBox coja el foco; esto es cosa de la vista en sí, no tiene que ver con datos ni nada así que el mejor lugar para hacerlo es el code-behind.</p>
<p>Explicandolo de otra forma que quizá os quede más clara:</p>
<p>Tenemos una aplicación para mostrar una serie de resultados que extraemos de una base de datos.</p>
<p>Para ello tenemos un ViewModel que extrae esos datos del modelo, y prepara esos datos para que una vista pueda usarlos. El ViewModel en sí no sabe nada acerca de las vistas, éste simplemente tiene un conjunto de propiedades para que una vista pueda hacer DataBinding a ellas (como podeis ver en el diagrama de antes). A este ViewModel podemos asignarle cualquier numero de vistas que queramos y dichas vistas representará esos datos como quiera.</p>
<p>Entonces imaginemos que una de esas vistas representará esos datos usando graficas y esas graficas contendrán cosas como animaciones, por ejemplo dandole a un botón la grafica hace una animación chula para mostrar los datos. ¿Quien ha de hacer ese trabajo? Está claro que el ViewModel no, puesto que el ViewModel no sabe nada acerca de las Vistas que lo están usando y si tuviera que implementar cosas por cada vista que lo use, perdería ya el desacople, ¿no? Así que es el code-behind el que hace estas cosas puesto que son cosas que solo atañen a la vista y nadie más.</p>
<p>Hasta aquí es básicamente MVVM, queda algo importante que contar, los comandos, pero eso lo dejaré para la próxima parte donde ya pondré un ejemplillo para que todo esto quede bien claro <img src='http://blog.foxandxss.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.foxandxss.net/index.php/mvvm-light-que-es/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Introducción a MVVM Light: Índice</title>
		<link>http://blog.foxandxss.net/index.php/introduccion-a-mvvm-light-indice/</link>
		<comments>http://blog.foxandxss.net/index.php/introduccion-a-mvvm-light-indice/#comments</comments>
		<pubDate>Sat, 20 Mar 2010 18:25:36 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Articulos]]></category>
		<category><![CDATA[MVVM]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Windows Phone 7]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://blog.foxandxss.net/?p=192</guid>
		<description><![CDATA[Voy a escribir un artículo de introducción al patrón MVVM y en concreto usando MVVM Light. Voy a dividir este artículo en varias partes para no agobiar al lector con un artículo muy largo. MVVM Light: ¿Qué es? MVVM Light: Comandos MVVM Light: Messenger MVVM Light: Localización Nos vemos en la primera parte]]></description>
			<content:encoded><![CDATA[<p>Voy a escribir un artículo de introducción al patrón MVVM y en concreto usando MVVM Light.</p>
<p>Voy a dividir este artículo en varias partes para no agobiar al lector con un artículo muy largo.</p>
<ul>
<li><a href="http://blog.foxandxss.net/index.php/mvvm-light-que-es/">MVVM Light: ¿Qué es?</a></li>
<li><a href="http://blog.foxandxss.net/index.php/mvvm-light-comandos/">MVVM Light: Comandos</a></li>
<li><a href="http://blog.foxandxss.net/index.php/mvvm-light-messenger/">MVVM Light: Messenger</a></li>
<li><a href="http://blog.foxandxss.net/index.php/mvvm-light-localizacion/">MVVM Light: Localización</a></li>
</ul>
<p>Nos vemos en la primera parte <img src='http://blog.foxandxss.net/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.foxandxss.net/index.php/introduccion-a-mvvm-light-indice/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Expression Blend 4 Beta y Silverlight 4 RC</title>
		<link>http://blog.foxandxss.net/index.php/expression-blend-4-beta-y-silverlight-4-rc/</link>
		<comments>http://blog.foxandxss.net/index.php/expression-blend-4-beta-y-silverlight-4-rc/#comments</comments>
		<pubDate>Tue, 16 Mar 2010 11:57:09 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Noticias]]></category>
		<category><![CDATA[Blend]]></category>
		<category><![CDATA[Silverlight]]></category>

		<guid isPermaLink="false">http://blog.foxandxss.net/?p=188</guid>
		<description><![CDATA[Los que usamos Visual Studio 2010 RC estamos de enhorabuena. La release de Visual Studio 2010 RC tenia 2 grandes puntos negros: Silverlight 4 Beta no funcionaba en VS 2010 RC sabes dios por qué, la cosa es que nos dijeron que esperasemos a una nueva release de Silverlight, y claro, ahora que estos días [...]]]></description>
			<content:encoded><![CDATA[<p>Los que usamos Visual Studio 2010 RC estamos de enhorabuena.</p>
<p>La release de Visual Studio 2010 RC tenia 2 grandes puntos negros:</p>
<p>Silverlight 4 Beta no funcionaba en VS 2010 RC sabes dios por qué, la cosa es que nos dijeron que esperasemos a una nueva release de Silverlight, y claro, ahora que estos días es el MIX 2010 pues han aprovechado para anunciar Silverlight 4 RC el cual es compatible con el último VS.</p>
<p>Os dejo aquí el enlace de la descarga:<br />
<a href="http://go.microsoft.com/fwlink/?LinkID=141284"><br />
Herramientas de Silverlight 4 para Visual Studio 2010</a><br />
<a href="http://go.microsoft.com/fwlink/?LinkID=169408"><br />
SDK de Silverlight 4</a></p>
<p><a href="http://silverlight.codeplex.com/">Silverlight toolkit (Opcional)</a></p>
<p>Por otro lado había una Preview de Blend 3 con soporte para WPF 4 y Silverlight 4, pero esta preview dejó de funcionar con Visual Studio 2010 RC así que sólo tocaba esperar para una versión con soporte que según los desalladores, saldría pronto y claro han aprovechado el MIX 2010 también. Así que ahora tenemos Blend 4 Beta disponible para todos <img src='http://blog.foxandxss.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=6f014e07-0053-4aca-84a7-cd82f9aa989f">Blend 4 Beta</a></p>
<p>Y por favor, no seais tan tontos como yo que me volví loco con la key que pide&#8230; Solo has de hacer click en el enlace que os da el instalador cuando os pide la key, ahí podeis crear una.</p>
<p>Por último, han sacado un add-in para Windows Phone 7 para Blend 4 y aunque el telefono no está en la calle, trae un emulador por si quiereis ir probando:</p>
<p><a href="http://www.microsoft.com/expression/try-it/Default.aspx#PageTop">Paquetes necesarios</a></p>
<p>Un saludo.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.foxandxss.net/index.php/expression-blend-4-beta-y-silverlight-4-rc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Silverlight &amp; HTML &amp; Apache</title>
		<link>http://blog.foxandxss.net/index.php/silverlight-html-apache/</link>
		<comments>http://blog.foxandxss.net/index.php/silverlight-html-apache/#comments</comments>
		<pubDate>Fri, 24 Jul 2009 13:56:26 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Articulos]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.foxandxss.org/blog/?p=66</guid>
		<description><![CDATA[Buenas! Mucha gente piensa, de hecho, yo también lo pensaba en su día, que para poder usar Silverlight necesitaríamos un servidor Windows corriendo IIS y una aplicación web usando ASP.NET. Investigando descubrí que podía embeber una aplicación Silverlight dentro de un simple HTML. Gracias a esto, podemos embeber dicha aplicación en cualquier tipo de página, [...]]]></description>
			<content:encoded><![CDATA[<p>Buenas!</p>
<p>Mucha gente piensa, de hecho, yo también lo pensaba en su día, que para poder usar <b>Silverlight</b> necesitaríamos un servidor Windows corriendo <b>IIS</b> y una aplicación web usando <b>ASP.NET</b>.</p>
<p>Investigando descubrí que podía embeber una aplicación <b>Silverlight</b> dentro de un simple HTML. Gracias a esto, podemos embeber dicha aplicación en cualquier tipo de página, ya sea PHP u otra cosa.</p>
<p>No solo eso, si no que podemos correr dicha página web bajo un servidor Apache ya sea en Windows o Linux. Ahora te surgirán las dos típicas preguntas: <i>¿Cómo?, ¿Por qué funciona?</i>. Paso a contestarlas:<br />
<span id="more-66"></span></p>
<h2> ¿Por qué funciona en algo que no sea Windows e IIS? </h2>
<p><b>Silverlight</b> no se ejecuta en el servidor, <b>Silverlight</b> se ejecuta en el cliente, es un plugin del navegador, así que somos nosotros quienes necesitamos tener <b>Silverlight</b> instalado.</p>
<p>Así que al ser nosotros quienes ejecutemos la aplicación, el servidor simplemente necesita conocer los ficheros de <b>Silverlight</b> y nada más.</p>
<h2> ¿Cómo lo hago? </h2>
<p>Tendremos que modificar el fichero .htaccess e insertar estos MimeTypes:</p>
<blockquote><p>
AddType application/x-silverlight-app xap<br />
AddType application/x-silverlight-2 xap
</p></blockquote>
<p>Realmente con uno nada más funciona, pero mejor insertamos ambos y nos quitamos de tener que editar luego el html para cambiar el MimeType.</p>
<p>Y bueno, ya que estamos, podriamos insertar todos estos:</p>
<blockquote><p>
AddType application/x-ms-application application<br />
AddType application/x-ms-manifest manifest<br />
AddType application/octet-stream deploy<br />
AddType application/vnd.ms-xpsdocument xps<br />
AddType application/xaml+xml xaml<br />
AddType application/x-ms-xbap xbap<br />
AddType application/x-silverlight-app xap<br />
AddType application/x-silverlight-2 xap
</p></blockquote>
<p>Con todos estos, podremos hacer uso del ClickOnce que nos ofrece el Visual Studio para distribuir nuestras aplicaciones de forma más comoda, en este caso, desde nuestra web.</p>
<p>Y nada más, con esto ya podemos usar alojar nuestra aplicación <b>Silverlight</b> en un servidor Linux con Apache.</p>
<h2> Vale, y&#8230; ¿Ahora como incrusto la aplicación en el HTML? </h2>
<p>Más facil todavía.</p>
<p>Si creamos una aplicación <b>Silverlight</b> en el Visual Studio, nos dará la opción de crear un proyecto <b>ASP.NET</b>, pero si le decimos que no, nos creará un .html básico con el objeto ya embebido.</p>
<p>Básicamente, al compilar una aplicación <b>Silverlight</b>, se creará un fichero .xap que no es más que un .zip que contiene los ficheros .xaml, los dll necesarios&#8230; Vamos, algo parecido a los .jar de Java.</p>
<p>Ahora con este .xap, solo necesitaremos embeberlo en el .html usando un código como este:</p>
<pre class="brush: xml;">
&lt;div id=&quot;silverlightControlHost&quot;&gt;
	&lt;object data=&quot;data:application/x-silverlight-2,&quot; type=&quot;application/x-silverlight-2&quot; width=&quot;100%&quot; height=&quot;100%&quot;&gt;
	  &lt;param name=&quot;source&quot; value=&quot;NombreDel.xap&quot;/&gt;
	  &lt;param name=&quot;background&quot; value=&quot;white&quot; /&gt;
	  &lt;param name=&quot;minRuntimeVersion&quot; value=&quot;3.0.40624.0&quot; /&gt;
	  &lt;param name=&quot;autoUpgrade&quot; value=&quot;true&quot; /&gt;
	  &lt;a href=&quot;http://go.microsoft.com/fwlink/?LinkID=149156&amp;amp;v=3.0.40624.0&quot; style=&quot;text-decoration:none&quot;&gt;
		  &lt;img src=&quot;http://go.microsoft.com/fwlink/?LinkId=108181&quot; alt=&quot;Get Microsoft Silverlight&quot; style=&quot;border-style:none&quot;/&gt;
	  &lt;/a&gt;
	&lt;/object&gt;
&lt;/div&gt;
</pre>
<p>Con esto, dentro de ese div tendremos nuestra aplicación <b>Silverlight</b> embebida.</p>
<p>Esto sería un ejemplo completo de página HTML que contiene simplemente el <b>Silverlight</b>.</p>
<pre class="brush: xml;">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; &gt;
&lt;head&gt;
    &lt;title&gt;SilverlightApplication1&lt;/title&gt;
    &lt;style type=&quot;text/css&quot;&gt;
		#silverlightControlHost {
			height: 500px;
			width: 500px
		}
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id=&quot;silverlightControlHost&quot;&gt;
	&lt;object data=&quot;data:application/x-silverlight-2,&quot; type=&quot;application/x-silverlight-2&quot; width=&quot;100%&quot; height=&quot;100%&quot;&gt;
	  &lt;param name=&quot;source&quot; value=&quot;NombreDel.xap&quot;/&gt;
	  &lt;param name=&quot;background&quot; value=&quot;white&quot; /&gt;
	  &lt;param name=&quot;minRuntimeVersion&quot; value=&quot;3.0.40624.0&quot; /&gt;
	  &lt;param name=&quot;autoUpgrade&quot; value=&quot;true&quot; /&gt;
	  &lt;a href=&quot;http://go.microsoft.com/fwlink/?LinkID=149156&amp;amp;v=3.0.40624.0&quot; style=&quot;text-decoration:none&quot;&gt;
		  &lt;img src=&quot;http://go.microsoft.com/fwlink/?LinkId=108181&quot; alt=&quot;Get Microsoft Silverlight&quot; style=&quot;border-style:none&quot;/&gt;
	  &lt;/a&gt;
	&lt;/object&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>Con el CSS ajusto el tamaño de la aplicación <b>Silverlight</b>. Imagino que no será la mejor forma para hacerlo, pero todavía estoy verde con la programación web <img src='http://blog.foxandxss.net/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<h2> Ejemplo de aplicación <b>Silverlight</b> embebida aquí en el artículo </h2>
<p><div id="silverlightControlHost"><object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="500" height="300"><param name="source" value="http://foxandxss.net/CosasBlog/silverlighthtml/SilverlightClock.xap"/><param name="background" value="white" /><param name="minRuntimeVersion" value="3.0.40723.0" /><param name="autoupgrade" value="true" /><param name="enableHtmlAccess" value="true" /><a href="http://go.microsoft.com/fwlink/?LinkID=149156" style="text-decoration: none;"><img src="http://storage.timheuer.com/sl4wp-ph.png" alt="Install Microsoft Silverlight" style="border-style: none; width:400px; height:200px"/></a></object><iframe style="visibility:hidden;height:0;width:0;border:0px" id="_sl_historyFrame"></iframe></div><br /></p>
<p>Eso es todo amigos.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.foxandxss.net/index.php/silverlight-html-apache/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
