﻿<?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; WPF</title>
	<atom:link href="http://blog.foxandxss.net/index.php/tag/wpf/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>Reseña: WPF Unleashed</title>
		<link>http://blog.foxandxss.net/index.php/resena-wpf-unleashed/</link>
		<comments>http://blog.foxandxss.net/index.php/resena-wpf-unleashed/#comments</comments>
		<pubDate>Mon, 10 May 2010 13:33:22 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Reseñas]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://blog.foxandxss.net/?p=393</guid>
		<description><![CDATA[¿Te cuesta entender los artículos de WPF del blog? ¿Crees que necesitas aprender lo básico de WPF primero? Para eso está &#8220;Windows Presentation Foundation Unleashed&#8221; de Sams. Windows Presentation Foundation Unleashed (WPF-U a partir de ahora) ha sido aclamado como el mejor libro de WPF que había en el mercado. Ya han pasado 4 años [...]]]></description>
			<content:encoded><![CDATA[<p>¿Te cuesta entender los artículos de WPF del blog? ¿Crees que necesitas aprender lo básico de WPF primero?</p>
<p>Para eso está &#8220;Windows Presentation Foundation Unleashed&#8221; de Sams.</p>
<p><a href="http://www.informit.com/ShowCover.aspx?isbn=0672328917&#038;type=f"><img alt="" src="http://www.informit.com/ShowCover.aspx?isbn=0672328917&#038;type=f" class="alignnone" width="160" height="209" /></a><br />
<span id="more-393"></span><br />
Windows Presentation Foundation Unleashed (WPF-U a partir de ahora) ha sido aclamado como el mejor libro de WPF que había en el mercado. Ya han pasado 4 años del lanzamiento (2006) pero sigue siendo igual de util a dia de hoy.</p>
<p>Nada mas abrir el libro, te enamoras de el, pues está a todo color, lleno de imagenes con colores vivos, el código tal y como lo verás en Visual Studio y lleno de recuadros con información. Precioso sin duda.</p>
<p>Ya hablando del libro en si, está muy bien como la gente aclama aunque yo le veo algunos fallitos.</p>
<p>Tiene un comienzo muy muy duro, los 3 primeros temas volverán loco a cualquiera que se quiera meter con WPF, ya que te cuenta TODO lo que ofrece WPF y claro, empiezas a leer sobre <i>Dependency properties</i>, <i>Commands</i>, <i>Routed events</i>, <i>Markup extensions</i> y claro lo más lógico es decir algo en plan: ¿Pero que carajo es todo esto? Si apenas hemos visto 3 líneas de XAML&#8230;</p>
<p>La verdad, esta primera parte es un trago complicado, pero ya luego empieza a explicar las cosas paso a paso y empieza lo bueno.</p>
<p>Tiene una buena parte explicando los controles que WPF nos ofrece, como cambiarles el tamaño, aplicarles transformaciones tales como rotaciones&#8230; Sigue explicandos como estructurar una aplicación visualmente usando los <i>Layouts</i> que WPF nos pone a nuestra disposición. Incluso nos dice como hacer ventanas tipo Vista o Win 7, con sus bordes de cristal y tal.</p>
<p>Despues de la introducción a WPF ya se mete a temas más avanzados como los <i>Data Bindings</i>, estilos, temas&#8230;</p>
<p>Luego continua hablandonos de graficos en 2D y 3D, animaciones, meter audio y video en nuestras aplicaciones&#8230;</p>
<p>Termina hablandonos un poco de como funciona la interoperabilidad con <i>Win32</i>, <i>Windows Forms</i> y <i>ActiveX</i> además de darnos una pequeña explicación de qué es un control de usuario y como crear controles personalizados (de una forma muy muy básica).</p>
<p>En resumen, es un libro bueno, toca casi todo lo que WPF ofrece, aunque algunos temas pecan de ser simplones y otros quizás menos interesantes los explica a fondo&#8230;</p>
<p>El problema que yo le veo al libro, es que se escribió cuando WPF era bastante nuevo, y a dia de hoy algunas de las cosas que el libro explica pues ya no se hacen de esa forma o incluso he visto un par de cosas que ya no eran ni válidas.</p>
<p>Aún así sigue siendo una de las mejores opciones para aprender WPF, hay alternativas, pero dan sueño.</p>
<p><b>Cosas positivas:</b></p>
<ul>
<li>Buenísisisima presentación</li>
<li>Te muestra casi todo lo que WPF ofrece</li>
<li>Muchos de los temas están muy bien explicados</li>
<li>La parte de interoperabilidad está bastante bien</li>
</ul>
<p><b>Cosas negativas:</b></p>
<ul>
<li>Algunas cosas que explica ya no son validas</li>
<li>Tiene algún fallito que otro</li>
<li>La introducción da miedo de verdad</li>
<li>Algun tema es bastante simplón y hasta sobraría</li>
</ul>
<p>Yo le doy un <b>8</b> a este libro.</p>
<p>Como nota final, yo para los que se quieren iniciar en WPF, aparte de leer mi blog a diario, les recomiendo primero leer el libro <a href="http://blog.foxandxss.net/index.php/resena-teach-yourself-wpf-in-24-hours/">WPF in 24 Hours</a> y luego leer WPF-U.</p>
<p>Una pena que ambos estén solo en inglés, pero es lo que tiene la informática y concretamente WPF que no tiene tanto impacto (por ahora) en el mundo hispano.</p>
<p>Hasta otra.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.foxandxss.net/index.php/resena-wpf-unleashed/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Truco: Forzando nuestras apps con el estilo de Vista / 7</title>
		<link>http://blog.foxandxss.net/index.php/truco-forzando-nuestras-apps-con-el-estilo-de-vista-7/</link>
		<comments>http://blog.foxandxss.net/index.php/truco-forzando-nuestras-apps-con-el-estilo-de-vista-7/#comments</comments>
		<pubDate>Fri, 26 Mar 2010 12:16:03 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Trucos]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://blog.foxandxss.net/?p=229</guid>
		<description><![CDATA[¿Habéis creado alguna vez una aplicación en vuestro Windows Vista / 7 y al probarlo en un Windows XP habéis visto que no se ve igual? Si hacéis alguna aplicación en la que os ponéis a cambiar un poco el apartado visual, comprobaréis que en XP no se ve igual ni por asomo. Por ejemplo, [...]]]></description>
			<content:encoded><![CDATA[<p>¿Habéis creado alguna vez una aplicación en vuestro Windows Vista / 7 y al probarlo en un Windows XP habéis visto que no se ve igual?</p>
<p>Si hacéis alguna aplicación en la que os ponéis a cambiar un poco el apartado visual, comprobaréis que en XP no se ve igual ni por asomo.<br />
<span id="more-229"></span><br />
Por ejemplo, imaginad que tenéis una ventana y esta ventana tiene un <i>Border</i> y lo quereis poner azul. Creais un estilo para que los bordes sean azules.</p>
<p>Además de eso, la ventana tiene un <i>TabControl</i> con sus pestañas ahi majas.</p>
<p>Nada, ejecutáis la aplicación, sale la ventana y de puta madre, los <i>Border</i> salen en azul y el resto sigue bien, ya que el estilo es solo para dicho control.</p>
<p>Ahora se lo pasais a algun colega que tiene XP y os dice&#8230; macho, vaya pedazo de birria de programa que has hecho&#8230; Y tu&#8230; No está tan mal&#8230;</p>
<p>Le decís que os pase una screenshot y sorpresa, ves recuadros azules por todos lados, las pestañas del <i>TabControl</i> tienen 1-2 recuadros azules ahi por la cara (Es porque dichas pestañas estan compuesta por un <i>Border</i> entre otras cosas).</p>
<p>No solo eso, los colores pueden aparecer en otra tonalidad, si usais sombras ya podeis despediros de ellas&#8230;</p>
<p>En resumen, cualquier floritura extra que le pongáis, en XP no se va a ver igual ni por asomo.</p>
<p>Pero hay una solución&#8230;.</p>
<p>¡Forzar a la aplicación a usar el estilo de Vista / 7 aunque sea en XP!</p>
<p>¿Cómo? En dos simples pasos:</p>
<p>Añadimos una referencia a nuestra aplicación:</p>
<p><b>PresentationFramework.Aero</b></p>
<p>Vamos, es el .dll para usar el aspecto gráfico de Vista / 7. Este .dll viene por defecto, no hace falta bajar nada.</p>
<p>Ahora en nuestro <i>App.xaml</i>, tenemos que añadir un diccionario de recursos nuevo. Si no os acordáis o no lo sabeis, la forma de meter diccionarios en el <i>App.xaml</i> es fusionando todos los diccionarios que queramos de ésta forma:</p>
<pre class="brush: xml;">
&lt;Application.Resources&gt;
	&lt;ResourceDictionary&gt;
		&lt;ResourceDictionary.MergedDictionaries&gt;
			&lt;!--Diccionarios--&gt;
		&lt;/ResourceDictionary.MergedDictionaries&gt;
	&lt;/ResourceDictionary&gt;
&lt;/Application.Resources&gt;
</pre>
<p>En este caso, tenemos que meter un diccionario que existe dentro de <b>PresentationFramework.Aero</b>:</p>
<pre class="brush: xml;">
&lt;Application.Resources&gt;
	&lt;ResourceDictionary&gt;
		&lt;ResourceDictionary.MergedDictionaries&gt;
			&lt;ResourceDictionary Source=&quot;/PresentationFramework.Aero;V3.0.0.0;31bf3856ad364e35;component/themes/aero.normalcolor.xaml&quot; /&gt;
		&lt;/ResourceDictionary.MergedDictionaries&gt;
	&lt;/ResourceDictionary&gt;
&lt;/Application.Resources&gt;
</pre>
<p>o si usamos WPF 4:</p>
<pre class="brush: xml;">
&lt;Application.Resources&gt;
	&lt;ResourceDictionary&gt;
		&lt;ResourceDictionary.MergedDictionaries&gt;
			&lt;ResourceDictionary Source=&quot;/PresentationFramework.Aero;V4.0.0.0;31bf3856ad364e35;component\themes/aero.normalcolor.xaml&quot;/&gt;
		&lt;/ResourceDictionary.MergedDictionaries&gt;
	&lt;/ResourceDictionary&gt;
&lt;/Application.Resources&gt;
</pre>
<p>Con esto forzaremos a nuestra aplicación a usar el tema Aero (podemos cambiarlo por otro si queremos) aunque nuestro SO no esté usando dicho tema actualmente.</p>
<p>Asunto solucionado.</p>
<p>Hasta otra <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/truco-forzando-nuestras-apps-con-el-estilo-de-vista-7/feed/</wfw:commentRss>
		<slash:comments>2</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>TwitFox 1.0</title>
		<link>http://blog.foxandxss.net/index.php/twitfox-1-0/</link>
		<comments>http://blog.foxandxss.net/index.php/twitfox-1-0/#comments</comments>
		<pubDate>Sun, 20 Dec 2009 13:52:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Mis Programas]]></category>
		<category><![CDATA[Blend]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[MVP]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://blog.foxandxss.net/?p=174</guid>
		<description><![CDATA[Hola! He creado un cliente de Twitter, es un cliente sencillito que he hecho con el proposito de aprender y de divertirme un poco. Os dejo una screen: Mi primera intención era la de crear un artículo explicando paso por paso como crear un cliente Twitter, pero la verdad es que aunque simple el cliente, [...]]]></description>
			<content:encoded><![CDATA[<p>Hola!</p>
<p>He creado un cliente de <b>Twitter</b>, es un cliente sencillito que he hecho con el proposito de aprender y de divertirme un poco.</p>
<p>Os dejo una screen:</p>
<p><a href="http://www.foxandxss.net/misprogramas/twitfox/principal.PNG"><img alt="ScreenTwitFox" src="http://www.foxandxss.net/misprogramas/twitfox/principal.PNG" class="alignnone" width="467" height="720" /></a><br />
<span id="more-174"></span></p>
<p>Mi primera intención era la de crear un artículo explicando paso por paso como crear un cliente Twitter, pero la verdad es que aunque simple el cliente, ha terminado con más código del que pensaba.</p>
<p>Aun así os daré algunos detalles para que cuando mirés el código pues sepais más o menos qué hace cada cosa.</p>
<p>No he usado ninguna librería concreta para desarrollar esta primera versión del cliente de Twitter. Simplemente he usado el <b>REST API</b> el cual es bastante limitado.</p>
<p>La clase <i>TwitterClient</i> es la que nos permitirá descargar nuestros Tweets y cambiar nuestro estado. No hace nada más. Cuando cambie la librería, añadiré más opciones a la interfaz de dicha clase sin modificar las opciones que ya hay.</p>
<p>Podeis observar que la clase lo que hace es descargar un XML con los tweets y parsearlos.</p>
<p>Por otro lado, podéis ver que la estructura del proyecto es MVP aunque le he añadido tambien la clase <i>DelegateCommand</i> para usar comandos siempre que sea posible.</p>
<p>Lo más complejo del proyecto es la UI, en la cual he usado <b>Data Templates</b>, <b>Fake DataContext</b> (Dos cosas que habéis aprendido aquí), además de un botón custom con una pequeña animación.</p>
<p>El código de la UI quizá sea un poco guarrete, pero es la primera aplicación que hago usando <b>Blend 3</b> como aplicación de diseño principal.</p>
<p>Nada más, os dejo aquí el enlace a la aplicación:</p>
<p><a href="http://www.foxandxss.net/misprogramas/twitfox/twitfox.php">TwitFox</a></p>
<p>Un saludo!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.foxandxss.net/index.php/twitfox-1-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[WPF] Datos en tiempo de diseño (Design-time DataContext)</title>
		<link>http://blog.foxandxss.net/index.php/datos-en-tiempo-de-diseno-design-datacontext/</link>
		<comments>http://blog.foxandxss.net/index.php/datos-en-tiempo-de-diseno-design-datacontext/#comments</comments>
		<pubDate>Wed, 09 Dec 2009 15:13:22 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Articulos]]></category>
		<category><![CDATA[Blend]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://www.foxandxss.net/?p=125</guid>
		<description><![CDATA[¡Hola! Para seguir este artículo necesitaréis de Microsoft Expression Blend 3 o Visual Studio 2010 Beta 2. Además necesitaréis una copia del proyecto del artículo &#8220;Data Templates&#8220;. Antes de explicaros qué significa exactamente eso de Datos en tiempo de diseño quiero que veais el problema en vuestras carnes y así buscarle una solución idónea. Yo [...]]]></description>
			<content:encoded><![CDATA[<p>¡Hola!</p>
<p>Para seguir este artículo necesitaréis de <b>Microsoft Expression Blend 3</b> o <b>Visual Studio 2010 Beta 2</b>. Además necesitaréis una copia del proyecto del artículo &#8220;<a href="http://www.foxandxss.net/index.php/2009/08/wpf-data-templates/">Data Templates</a>&#8220;.</p>
<p>Antes de explicaros qué significa exactamente eso de <i>Datos en tiempo de diseño</i> quiero que veais el problema en vuestras carnes y así buscarle una solución idónea.</p>
<p>Yo usaré <b>Blend 3</b> así que las imágenes y las instrucciones serán usando este soft, pero se pueden aplicar con Visual Studio 2010 sin ningún problema.</p>
<p>Imaginad esta situación:</p>
<p>Queréis modificar el <i>Data Template</i> que habíamos creado del ejemplo citado. No sé, el borde ese verde que tiene cada item no os gusta y queréis ir probando colores hasta encontrar uno que os guste más. Ningún problema, abres el proyecto con el <b>Blend 3</b> y&#8230;.<br />
<span id="more-125"></span><br />
<a href="http://www.foxandxss.net/CosasBlog/FakeDataContext/1.png"><img alt="Screenshot" src="http://www.foxandxss.net/CosasBlog/FakeDataContext/1.png" title="Imagen 1" class="alignnone" width="485" height="484" /></a></p>
<p>Vaya tela, nos sale una bonita ventana en blanco&#8230; ¿Por qué no sale el contenido? No nos sale porque ni Blend ni Visual studio ni nadie sabe qué ha de representar ahí, o mejor dicho, nosotros estamos <i>&#8216;bindeando&#8217;</i> ese contenido a una propiedad del DataContext, o sea del ViewModel. Blend no sabe nada sobre ese DataContext que hemos establecido en código, así que el no sabe que ha de mostrar ahi ni nada. Si bien sabe como dibujar el Data Template, no sabe qué <i>&#8216;Data&#8217;</i> tiene que reprentar ahi.</p>
<p>Entonces con <b>Blend 3</b> llegó una nueva cosita llamada <i>Datos en tiempo de diseño</i>, o lo que es lo mismo, ofrecerle unos datos <i>&#8216;de mentira&#8217;</i> a <b>Blend 3</b> a fin de que los use para dibujar los Data Template en la ventana.</p>
<p>¿Qué quiero decir con eso de ofrecerle unos datos de mentira? Fácil, el <i>ItemsControl</i> está asociado a una lista llamada <i>ListaPersonas</i>, pero dicha lista &#8216;viene&#8217; del <i>DataContext</i> y como ya os he dicho, el editor visual no puede mostrar nada que venga de ahi, por eso nos aparece la ventana en blanco, porque ignora el DataContext.</p>
<p>Aquí es donde entra el <i>Datos en tiempo de diseño</i> (Design-time Data). es digamos un <i>DataContext</i> especial sólo para diseñar, así podemos mostrar datos &#8216;Fake&#8217; y ver como quedaría sin ejecutar la aplicación ni nada. Por ejemplo:</p>
<p>Imaginad que estais haciendo una aplicación de Twitter. Cuando la aplicación se conecta a la red, descarga tus tweets, y crea una instancia de la clase <i>Tweet</i> por cada tweet que recoja. ¿Cómo diseñarías la ventana principal del programa? ¿Creas un no sé, <i>ItemsControl</i> y creas un DataTemplate para los Tweet? Es una idea, pero es un coñazo, tienes que crear un template, abrir el programa, conectarte a tu Twitter, que descargue tus Tweets y ver que&#8230; oh mierda, ese borde no moooola nada. Cierras la aplicación, modifica el borde y otra vez a probarlo. Si tienes que hacer eso 50 veces para dejar el estilo a tu gusto, mueres.</p>
<p>¿Qué hacer entonces? Creas una clase llamada&#8230; FakeTweets por ejemplo que herede de la clase que usa tu ventana de DataContext, ahí instancias la lista del datacontext, creas unos cuantos tweets de mentira y usas la técnica que explicaré a continuación <img src='http://blog.foxandxss.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Este ejemplo es algo muy común, porque donde dices Twitter, dices aplicación de msn y su ventana de contactos, etc.</p>
<p>Vamos a nuestra aplicación que ya está abierta en Blend, y añadimos lo siguiente dentro del <i>Tag</i> de la ventana&#8230;</p>
<pre class="brush: xml;">
xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
xmlns:local=&quot;clr-namespace:DataTemplates&quot;
mc:Ignorable=&quot;d&quot;
</pre>
<p>Con lo que quedaría así:</p>
<pre class="brush: xml;">
&lt;Window x:Class=&quot;DataTemplates.Window1&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;
    xmlns:local=&quot;clr-namespace:DataTemplates&quot;
	mc:Ignorable=&quot;d&quot;
    Title=&quot;Data Templates&quot; Height=&quot;600&quot; Width=&quot;600&quot;
    Background=&quot;#f8fffb&quot;&gt;
</pre>
<p>Voy a detallar para qué sirve cada uno:</p>
<pre class="brush: xml;">
xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
xmlns:local=&quot;clr-namespace:DataTemplates&quot;
</pre>
<p>Los 3 son namespace como podeis ver, cada uno con una idea en mente.</p>
<p>El primero es el que añade todo el tema de <i>Datos en tiempo de diseño</i>.<br />
El tercero es para importar el namespace de nuestra aplicación (luego veremos por qué)<br />
El segundo va en conjunto con:</p>
<pre class="brush: xml;">
mc:Ignorable=&quot;d&quot;
</pre>
<p>El namespace &#8216;mc&#8217; que hemos importando antes nos sirve para usar el <i>Ignorable</i>. ¿Para qué sirve esto? Sirve para excluir todo lo que sea del namespace indicado a la hora de compilar. ¿Por qué ignoramos el namespace &#8216;d&#8217;? Porque lo que nos ofrece son cosas que nos facilitan la vida a la hora de diseñar la aplicación, pero que a la hora de ejecutarla ya no nos sirve. Así que la aplicación compilada no contendrá nada de lo que coloquemos de cara a ayudarnos a diseñar.</p>
<p>¿Y ahora qué? Ahora tenemos que cargar en el XAML la clase con los datos &#8216;fake&#8217; (como por ejemplo la clase con tweets de mentira), en nuestro caso nos basta con cargar el <i>Presenter</i> ya que trae datos de ejemplos que nos servirá para el caso.</p>
<p>Para esto podemos usar por ejemplo un <i>ObjectDataProvider</i>:</p>
<pre class="brush: xml;">
&lt;Window.Resources&gt;
	&lt;ObjectDataProvider ObjectType=&quot;{x:Type local:Presenter}&quot; x:Key=&quot;FakeVM&quot; /&gt;
&lt;/Window.Resources&gt;
</pre>
<p>Como ves, he cargado el Presenter (usando el namespace <i>local</i> que cargué antes) y le he dado el nombre de <i>FakeVM</i>.</p>
<p>Ya solo nos quedaría cargar dicho objeto dentro del <i>Data Context</i> en tiempo de diseño, el cual está en el namcespace &#8216;d&#8217;.</p>
<p>En nuestro ejemplo, se lo asignaremos al <i>ItemsControl</i> como era de esperar:</p>
<pre class="brush: xml;">
&lt;ItemsControl ItemsSource=&quot;{Binding ListaPersonas}&quot; d:DataContext=&quot;{StaticResource FakeVM}&quot;&gt;
</pre>
<blockquote><p>NOTA: El método que he descrito aquí, inclusive los namespaces de blend, sirve tanto para <b>Blend 3</b> como para <b>Visual Studio 2010</b> (Beta 2 en adelante)</p></blockquote>
<p>ahora, si vamos al modo diseño&#8230;</p>
<p><a href="http://www.foxandxss.net/CosasBlog/FakeDataContext/2.png"><img alt="Screenshot" src="http://www.foxandxss.net/CosasBlog/FakeDataContext/2.png" title="Imagen 1" class="alignnone" width="485" height="484" /></a></p>
<p>Ya se ve!! Pero dirás&#8230; ¿Y ahora qué? ¿Puedo modificar el template en modo diseño y en ver los resultados en tiempo real? Claro que sí!</p>
<p>En <b>Blend 3</b>, abajo a la izquierda nos aparecerá el arbol de objetos de nuestra aplicación:</p>
<div class="wp-caption alignnone" style="width: 293px"><a href="http://www.foxandxss.net/CosasBlog/FakeDataContext/3.png"><img alt="Screenshot" src="http://www.foxandxss.net/CosasBlog/FakeDataContext/3.png" width="283" height="158" /></a><p class="wp-caption-text">Screenshot</p></div>
<p>Ahi hacemos click derecho en ItemsControl y luego <i>Edit Aditional Templates -> Edit Generated Items (ItemTemplate) -> Edit Current</i>. Al hacer esto vemos como se señala el primer objeto del <i>ItemsControl</i> (ya que realmente editando uno, cambian todos).</p>
<p>Ya solo nos queda hacer los cambios pertinentes, por ejemplo cambiando el borde de cada objeto por uno con gradiente Negro <-> Blanco. Comprobareis con alegría que mientras moveis el cursor en la paleta de colores, el resultado se va viendo en tiempo real, y no necesitaréis ejecutar la aplicación con cada cambio.</p>
<p><a href="http://www.foxandxss.net/CosasBlog/FakeDataContext/4.png"><img alt="Screenshot" src="http://www.foxandxss.net/CosasBlog/FakeDataContext/4.png" title="Imagen 1" class="alignnone" width="485" height="484" /></a></p>
<p>Así que en resumen, teneis una manera de poder diseñar los <i>Data Templates</i> de forma visual usando datos &#8216;fake&#8217; y que no afectará para nada a la aplicación compilada.</p>
<p>Espero vuestros comentarios <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/datos-en-tiempo-de-diseno-design-datacontext/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nueva versión de Apunta Notas 2</title>
		<link>http://blog.foxandxss.net/index.php/nueva-version-de-apunta-notas-2/</link>
		<comments>http://blog.foxandxss.net/index.php/nueva-version-de-apunta-notas-2/#comments</comments>
		<pubDate>Thu, 17 Sep 2009 21:27:35 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Mis Programas]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[MVVM]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://www.foxandxss.org/blog/?p=109</guid>
		<description><![CDATA[Hola! Siento no escribir tanto como me gustaría, pero estuve de exámenes hace poco, y ahora he empezado a trabajar. Bueno, antes de dichos exámenes escribí una nueva versión del Apunta Notas y la anucio por aquí para que la probeis. Dicha versión tiene: Ahora al borrar una categoría te da la opción de borrar [...]]]></description>
			<content:encoded><![CDATA[<p>Hola!</p>
<p>Siento no escribir tanto como me gustaría, pero estuve de exámenes hace poco, y ahora he empezado a trabajar.</p>
<p>Bueno, antes de dichos exámenes escribí una nueva versión del Apunta Notas y la anucio por aquí para que la probeis.</p>
<p>Dicha versión tiene:<br />
<span id="more-109"></span></p>
<ul>
<li>Ahora al borrar una categoría te da la opción de borrar todas las notas asociadas a ella.</li>
<li>Si decides no borrar dichas notas, se enviarán a una categoría oculta llamada &#8220;Papelera&#8221;.</li>
<li>Ahora al pulsar intro se añadirá la nota automaticamente (antes no me funcionaba por un pequeño bug que no veía)</li>
<li>Los rectangulos de los colores también son botones para seleccionar el color</li>
<li>Algun bug solucionado</li>
</ul>
<p>Quizá se me olvide algo, pero ahora no caigo, realmente metí muchas mejoras a lo largo de 2 dias de trabajo con el.</p>
<p>Los enlaces están donde siempre <img src='http://blog.foxandxss.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>A ver si este fin de semana puedo hacer algo más interesante.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.foxandxss.net/index.php/nueva-version-de-apunta-notas-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
