<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://geeks.ms/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Null World</title><subtitle type="html">Donde nada es lo que parece, especialmente los punteros</subtitle><id>http://geeks.ms/blogs/fmartinez/atom.aspx</id><link rel="alternate" type="text/html" href="http://geeks.ms/blogs/fmartinez/default.aspx" /><link rel="self" type="application/atom+xml" href="http://geeks.ms/blogs/fmartinez/atom.aspx" /><generator uri="http://communityserver.org" version="4.1.31106.3070">Community Server</generator><updated>2006-12-10T17:46:00Z</updated><entry><title>Cambiando de nombre a Window1</title><link rel="alternate" type="text/html" href="/blogs/fmartinez/archive/2009/06/10/cambiando-de-nombre-a-window1.aspx" /><id>/blogs/fmartinez/archive/2009/06/10/cambiando-de-nombre-a-window1.aspx</id><published>2009-06-10T08:54:53Z</published><updated>2009-06-10T08:54:53Z</updated><content type="html">&lt;p&gt;&lt;img style="border-right-width:0px;margin:0px 15px 0px 30px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="renamingFile" border="0" alt="renamingFile" align="right" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/fmartinez/renamingFile_5F00_3256C7E9.png" width="271" height="371" /&gt;&lt;/p&gt;  &lt;p&gt;Uno de los primeros problemas con los que se encuentra un diseñador o programador de WPF es qué hacer con Window1. Como ventana principal de la aplicación, lo más común es que queramos darle otro nombre que deje clara su funcionalidad, pero no es tan sencillo. El primer paso es renombrar el fichero desde el Explorador de soluciones. Después tenemos que modificar el nombre del archivo en 3 sitios distintos:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Window1.xaml. Tendremos que modificar el x:Class, que hace referencia al nombre completo de la clase parcial donde se almacena el código de la ventana. &lt;/li&gt;    &lt;li&gt;Window1.xaml.cs. Tanto el nombre de la clase como su constructor deben ser modificados. &lt;/li&gt;    &lt;li&gt;App.xaml. Este es el punto que la mayoría de la gente olvida y que más problemas termina dando, puesto que no se nos ocurre pensar en las referencias a Window1 fuera de la propia clase. Además, el proyecto compilará perfectamente, pero nos dará una IOException diciendo que no puedo encontrar el recurso window1.xaml. La razón es que dentro de App.xaml especificamos la ventana principal de la aplicación con el atributo StartupUri que, si no lo modificamos, conservará el valor Window1.xaml. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Una vez modificados estos tres ficheros, nuestro proyecto funcionará perfectamente y no tendremos que volver a ver Window1 por ningún sitio.&lt;/p&gt;  &lt;hr /&gt;  &lt;p&gt;Rock Tip. Dudo mucho que un grupo como &lt;a href="http://en.wikipedia.org/wiki/AC/DC"&gt;AC/DC&lt;/a&gt; necesite introducción, menos aun después del impresionante concierto de este viernes en el Vicente Calderón, así que os dejaré con uno de sus grandes éxitos, &lt;a href="http://www.youtube.com/watch?v=Bomv-6CJSfM"&gt;You Shook Me All Night Long&lt;/a&gt;. Enjoy!!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=150257" width="1" height="1"&gt;</content><author><name>fmartinez</name><uri>http://geeks.ms/members/fmartinez/default.aspx</uri></author><category term="WPF" scheme="http://geeks.ms/blogs/fmartinez/archive/tags/WPF/default.aspx" /></entry><entry><title>Teclado en pantalla con WPF</title><link rel="alternate" type="text/html" href="/blogs/fmartinez/archive/2009/05/20/teclado-en-pantalla-con-wpf.aspx" /><link rel="enclosure" type="application/zip" length="211762" href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.00.14.89.52/ScreenKeyboard.zip" /><id>/blogs/fmartinez/archive/2009/05/20/teclado-en-pantalla-con-wpf.aspx</id><published>2009-05-20T08:32:00Z</published><updated>2009-05-20T08:32:00Z</updated><content type="html">&lt;p&gt;&lt;img style="border-bottom:0px;border-left:0px;margin:0px 20px 0px 10px;display:inline;border-top:0px;border-right:0px;" title="ScreenKeyboard" alt="ScreenKeyboard" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/fmartinez/ScreenKeyboard_5F00_5A5A56F7.jpg" align="left" border="0" height="170" width="128" /&gt;En algunas de nuestras aplicaciones es posible que necesitemos controlar de forma muy fina la entrada de datos por parte del usuario, o que no dispongamos de un teclado f&amp;iacute;sico. Con WPF podemos crear de forma sencilla un teclado en pantalla que se maneje con el rat&amp;oacute;n o de forma t&amp;aacute;ctil. Lo primero de todo ser&amp;aacute; crear nuestra aplicaci&amp;oacute;n WPF y a&amp;ntilde;adirle un &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.textbox.aspx"&gt;TextBox&lt;/a&gt; y varios botones.&lt;/p&gt;
&lt;p&gt;La aplicaci&amp;oacute;n resultante la pod&amp;eacute;is ver aqu&amp;iacute; a la izquierda&amp;hellip;os servir&amp;aacute; para daros cuenta de que esto no va de dise&amp;ntilde;o, sino de programaci&amp;oacute;n. Adem&amp;aacute;s al final del post hay un link para que pod&amp;aacute;is descarg&amp;aacute;rosla y comprobar lo sencilla que es.&lt;/p&gt;
&lt;p&gt;Es interesante utilizar un TextBox en lugar de otro control de texto como una &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.label.aspx"&gt;Label&lt;/a&gt; o un &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.textblock.aspx"&gt;TextBlock&lt;/a&gt;, puesto que as&amp;iacute; tendremos soporte para mostrarle al usuario la posici&amp;oacute;n del cursor (caret) mientras edita el texto. Una vez hecho esto, necesitamos gestionar una serie de temas para que el teclado funcione correctamente. Lo primero de todo, manejaremos el click de los botones para a&amp;ntilde;adir texto al TextBox:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;private void &lt;/span&gt;KeyboardPanel_Click(&lt;span style="color:blue;"&gt;object &lt;/span&gt;sender, &lt;span style="color:#2b91af;"&gt;RoutedEventArgs &lt;/span&gt;e)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#2b91af;"&gt;Button &lt;/span&gt;button = (&lt;span style="color:#2b91af;"&gt;Button&lt;/span&gt;)e.Source;&lt;br /&gt;    Text.AppendText(button.Content.ToString());&lt;br /&gt;}&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;Una vez hecho esto, solo nos quedar&amp;iacute;a hacer que el campo de texto muestre la posici&amp;oacute;n del cursor mientras se esta editando. Para ello, en el constructor de nuestra ventana a&amp;ntilde;adiremos estas dos l&amp;iacute;neas despu&amp;eacute;s del InitializeComponent:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;this&lt;/span&gt;.InitializeComponent();&lt;br /&gt;&lt;br /&gt;Text.CaretIndex = 0;&lt;br /&gt;Text.Focus();&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;La primera l&amp;iacute;nea sit&amp;uacute;a la posici&amp;oacute;n del cursor en el 0, ya que de no hacerlo el TextBox no la gestionar&amp;aacute; correctamente. La segunda l&amp;iacute;nea le da el foco de tal manera que muestre el cursor. Si probamos nuestra aplicaci&amp;oacute;n ahora veremos que aun nos queda un problema por resolver. Al hacer click en cualquiera de los botones para a&amp;ntilde;adir texto, el TextBox perder&amp;aacute; el foco, perdiendo as&amp;iacute; la funcionalidad del cursor. Para evitar esto hay varios m&amp;eacute;todos: hacer que los botones no puedan recibir el foco (Focusable=false), hacer que en cada click el TextBox recupere el foco&amp;hellip;Lo que haremos ser&amp;aacute; algo muy sencillo: evitar que el TextBox pierda el foco. A&amp;ntilde;adimos al constructor la siguiente linea: &lt;/p&gt;
&lt;blockquote&gt;
&lt;pre class="code"&gt;Text.PreviewLostKeyboardFocus += &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;KeyboardFocusChangedEventHandler&lt;/span&gt;(Text_PreviewLostKeyboardFocus);&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;Manejando el evento &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.uielement.previewlostkeyboardfocus.aspx"&gt;PreviewLostKeyboardFocus&lt;/a&gt; podemos realizar las acciones que deseemos antes de que el control pierda el foco. Y lo que deseamos es&amp;hellip;&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;void &lt;/span&gt;Text_PreviewLostKeyboardFocus(&lt;span style="color:blue;"&gt;object &lt;/span&gt;sender, &lt;span style="color:#2b91af;"&gt;KeyboardFocusChangedEventArgs &lt;/span&gt;e)&lt;br /&gt;{&lt;br /&gt;    e.Handled = &lt;span style="color:blue;"&gt;true&lt;/span&gt;;&lt;br /&gt;}&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;Marcar el evento como manejado. Con algo tan simple como esto evitamos que el control pierda realmente el foco, y tenemos nuestro teclado listo para su uso.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Rock Tip. Poca gente hace canciones y videos tan divertidos como &lt;a href="http://en.wikipedia.org/wiki/Electric_Six"&gt;Electric Six&lt;/a&gt;. Lo mejor de todo es que adem&amp;aacute;s suenan realmente bien&amp;hellip;y no tienen ninguna relaci&amp;oacute;n con el tema del post, para no perder la costumbre ;) Cierran hoy Electric Six con &lt;a href="http://www.youtube.com/watch?v=2a4gyJsY0mc"&gt;Danger! High Voltage&lt;/a&gt;. Enjoy!!!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=148952" width="1" height="1"&gt;</content><author><name>fmartinez</name><uri>http://geeks.ms/members/fmartinez/default.aspx</uri></author><category term="WPF" scheme="http://geeks.ms/blogs/fmartinez/archive/tags/WPF/default.aspx" /></entry><entry><title>Los secretos del casting al descubierto</title><link rel="alternate" type="text/html" href="/blogs/fmartinez/archive/2009/05/13/los-secretos-del-casting-al-descubierto.aspx" /><id>/blogs/fmartinez/archive/2009/05/13/los-secretos-del-casting-al-descubierto.aspx</id><published>2009-05-13T14:51:18Z</published><updated>2009-05-13T14:51:18Z</updated><content type="html">&lt;p&gt;Visto lo animada que estuvo la discusión en el anterior post sobre &lt;a href="http://geeks.ms/blogs/fmartinez/archive/2009/04/29/los-secretos-del-casting.aspx"&gt;los diferentes casts en C#&lt;/a&gt;, no podía dejar pasar la oportunidad de explicar un poco en que consistía el acertijo. Como algunos comentabais en los comentarios, las dos operaciones, as y cast explicito, son distintas en funcionalidad y también internamente. Vamos a ver por qué:&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre class="code"&gt;concursante = (&lt;span style="color:#2b91af;"&gt;Concursante&lt;/span&gt;)o;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;En esa línea, intentaremos convertir el objeto o a Concursante. Si podemos, devolveremos un objeto de tipo concursante, si no podemos lanzaremos una excepción.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;concursante = o &lt;span style="color:blue;"&gt;as &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Concursante&lt;/span&gt;;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;En esta otra línea, comprobaremos primero si el objeto es convertible a Concursante. Si lo es, lo convertiremos y devolveremos, si no lo es devolveremos null. Internamente, el operador as se convierte en una instrucción de tipo &lt;a href="http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.isinst.aspx"&gt;isinst&lt;/a&gt;, mientras que el cast directo se convierte en una instrucción &lt;a href="http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.isinst.aspx"&gt;castclass&lt;/a&gt;. Pero dejémonos de teoría y vamos a lo que nos interesa. Con un sencillo programa podemos comprobar cual de los dos es más rápido. Por ejemplo, así:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:#2b91af;"&gt;Concursante &lt;/span&gt;concursante = &lt;span style="color:blue;"&gt;null&lt;/span&gt;;
&lt;span style="color:blue;"&gt;object &lt;/span&gt;o = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Concursante&lt;/span&gt;();

&lt;span style="color:#2b91af;"&gt;ArrayList &lt;/span&gt;array = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ArrayList&lt;/span&gt;();

&lt;span style="color:#2b91af;"&gt;Stopwatch &lt;/span&gt;watch = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Stopwatch&lt;/span&gt;();
&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Begin casting&amp;quot;&lt;/span&gt;);

&lt;span style="color:blue;"&gt;for &lt;/span&gt;(&lt;span style="color:blue;"&gt;int &lt;/span&gt;i = 0; i &amp;lt; 100; i++)
{
    watch.Start();

    &lt;span style="color:blue;"&gt;for &lt;/span&gt;(&lt;span style="color:blue;"&gt;int &lt;/span&gt;j = 0; j &amp;lt; 10000000; j++)
    {
        concursante = (&lt;span style="color:#2b91af;"&gt;Concursante&lt;/span&gt;)o;
        concursante.Nombre = &lt;span style="color:#a31515;"&gt;&amp;quot;Rosa&amp;quot;&lt;/span&gt;;
    }

    watch.Stop();

    array.Add(watch.ElapsedMilliseconds);
    watch.Reset();
}

&lt;span style="color:blue;"&gt;float &lt;/span&gt;ms = 0;

&lt;span style="color:blue;"&gt;for &lt;/span&gt;(&lt;span style="color:blue;"&gt;int &lt;/span&gt;i = 0; i &amp;lt; array.Count; i++)
{
    ms += &lt;span style="color:blue;"&gt;float&lt;/span&gt;.Parse(array[i].ToString());
}

ms = ms / array.Count;

&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Median elapsed time: {0} ms&amp;quot;&lt;/span&gt;, ms);&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;Si, el programa tiene un poco mas de miga, pero tiene su sentido. Hemos de recordar que un casting, de una forma u otra, es una operación con un coste muy, muy pequeño por si sola. Para poder medirla con un poco de precisión, realizaremos diez millones de casting cien veces, y calcularemos la media. Ejecutado en mi portátil mientras escribo esto, el resultado es de unos cuantos milisegundos (40, 50…) en cada uno de los casos. Recordemos que estamos hablando del tiempo de ejecución de 10.000.000 operaciones. Lo curioso es que al ejecutar el mismo código en modo release o en modo debug, con o sin optimizaciones, nos dará resultados distintos. Qué es lo que esta pasando? &lt;/p&gt;

&lt;p&gt;Esa será la respuesta que dejaré sin responder, por una sencilla razón. Mi compañero &lt;a href="http://geeks.ms/blogs/luisguerrero/"&gt;Luis Guerrero&lt;/a&gt; me ha prometido realizar un interesantísimo post sobre este mismo tema, metiéndose hasta el fondo del asunto con WinDBG. Así pues, le paso el testigo ;)&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Rock Tip. Ya he nombrado por aquí a los finlandeses &lt;a href="http://es.wikipedia.org/wiki/Turisas"&gt;Turisas&lt;/a&gt;, pero es justo que después de verles la semana pasada en directo por segunda vez, vuelva a recordarlos. Con vosotros, &lt;a href="http://www.youtube.com/watch?v=Ift85e38H3M"&gt;Battle Metal&lt;/a&gt;. Enjoy!!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=148573" width="1" height="1"&gt;</content><author><name>fmartinez</name><uri>http://geeks.ms/members/fmartinez/default.aspx</uri></author><category term="Puzzle" scheme="http://geeks.ms/blogs/fmartinez/archive/tags/Puzzle/default.aspx" /><category term="C#" scheme="http://geeks.ms/blogs/fmartinez/archive/tags/C_2300_/default.aspx" /></entry><entry><title>Los secretos del casting</title><link rel="alternate" type="text/html" href="/blogs/fmartinez/archive/2009/04/29/los-secretos-del-casting.aspx" /><id>/blogs/fmartinez/archive/2009/04/29/los-secretos-del-casting.aspx</id><published>2009-04-29T10:09:47Z</published><updated>2009-04-29T10:09:47Z</updated><content type="html">&lt;p&gt;Y no estamos hablando de los castings de Operación Triunfo o Gran Hermano, no. Os propongo pasar la tarde de hoy pensando en una de esas cosas que no dejan de ser interesantes pese a servir para bastante poco ;)&lt;/p&gt;  &lt;p&gt;Seguro que todos los días mientras programáis os encontráis con situaciones en las que tenéis que convertir objetos de un tipo a otro, lo que se conoce como un casting (que no tiene nada que ver con concursos, por suerte). En C# las dos formas más comunes de realizarlo son con un cast explicito o utilizando el operador as:&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;object &lt;/span&gt;o = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Concursante&lt;/span&gt;();
&lt;span style="color:#2b91af;"&gt;Concursante &lt;/span&gt;concursante;

concursante = (&lt;span style="color:#2b91af;"&gt;Concursante&lt;/span&gt;)o; &lt;span style="color:green;"&gt;//Explicito
&lt;/span&gt;concursante = o &lt;span style="color:blue;"&gt;as &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Concursante&lt;/span&gt;; &lt;span style="color:green;"&gt;//Operador as&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;Visto esto ya no haré ningún comentario, y me limitare a lanzar mi pregunta. Basaros simplemente en lo que sabéis de ambas operaciones y en vuestra intuición vale? La pregunta es…cual de las dos formas de realizar un cast es más rápida?&lt;/p&gt;

&lt;p&gt;La respuesta, en breve, en esta misma cadena…o no ;)&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Rock Tip. Visto que todo lo que hemos tenido por el momento en estos rock tips ha sido música en inglés creo que por una vez, aprovechando el cambio de temática del post, podríamos buscar otro idioma…como el alemán. Hoy cierra el post &lt;a href="http://es.wikipedia.org/wiki/Rammstein"&gt;Rammstein&lt;/a&gt; con una de sus mejores canciones (IMHO) acompañada de un gran videoclip: &lt;a href="http://www.youtube.com/watch?v=w07LDCT85YQ"&gt;Ich Will&lt;/a&gt;. Enjoy!! &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=147763" width="1" height="1"&gt;</content><author><name>fmartinez</name><uri>http://geeks.ms/members/fmartinez/default.aspx</uri></author><category term="Puzzle" scheme="http://geeks.ms/blogs/fmartinez/archive/tags/Puzzle/default.aspx" /><category term="C#" scheme="http://geeks.ms/blogs/fmartinez/archive/tags/C_2300_/default.aspx" /></entry><entry><title>Un sencillo menú en WPF: Recursos (II)</title><link rel="alternate" type="text/html" href="/blogs/fmartinez/archive/2009/04/22/un-sencillo-men-250-en-wpf-recursos-ii.aspx" /><id>/blogs/fmartinez/archive/2009/04/22/un-sencillo-men-250-en-wpf-recursos-ii.aspx</id><published>2009-04-22T08:27:00Z</published><updated>2009-04-22T08:27:00Z</updated><content type="html">&lt;p&gt;Dado que en el post anterior hablábamos sobre &lt;a href="http://geeks.ms/blogs/fmartinez/archive/2009/04/15/un-sencillo-men-250-en-wpf-estilos-y-plantillas-i.aspx"&gt;estilos y plantillas&lt;/a&gt;, vamos a ver un poco mas en detalle ahora como podemos estructurarlos y acceder a ellos de la mejor manera posible. En el proyecto (adjunto en la primera parte) vemos que en la ruta /Themes/Default.xaml encontramos un &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.resourcedictionary.aspx"&gt;diccionario de recursos&lt;/a&gt;.&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ResourceDictionary
    &lt;/span&gt;&lt;span style="color:red;"&gt;xmlns&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot; 
    &lt;/span&gt;&lt;span style="color:red;"&gt;xmlns&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot; 
    &lt;/span&gt;&lt;span style="color:red;"&gt;xmlns&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;d&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;http://schemas.microsoft.com/expression/blend/2008&amp;quot; 
    &lt;/span&gt;&lt;span style="color:red;"&gt;xmlns&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;mc&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;http://schemas.openxmlformats.org/markup-compatibility/2006&amp;quot; 
    &lt;/span&gt;&lt;span style="color:red;"&gt;mc&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;Ignorable&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;d&amp;quot;&amp;gt;
    &lt;/span&gt;&lt;span style="color:green;"&gt;&amp;lt;!-- Resource dictionary entries should be defined here. --&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Style &lt;/span&gt;&lt;span style="color:red;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;Key&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;ButtonFocusVisual&amp;quot;&amp;gt;
        &lt;/span&gt;&lt;span style="color:#a31515;"&gt;...
    &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Style&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;LinearGradientBrush &lt;/span&gt;&lt;span style="color:red;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;Key&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;ButtonNormalBackground&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;EndPoint&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;0,1&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;StartPoint&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;0,0&amp;quot;&amp;gt;
        &lt;/span&gt;&lt;span style="color:#a31515;"&gt;...
    &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;LinearGradientBrush&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;SolidColorBrush &lt;/span&gt;&lt;span style="color:red;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;Key&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;ButtonNormalBorder&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Color&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;#FF707070&amp;quot;/&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Style &lt;/span&gt;&lt;span style="color:red;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;Key&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;MenuButtonStyle&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;TargetType&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color:#a31515;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Type &lt;/span&gt;&lt;span style="color:red;"&gt;Button&lt;/span&gt;&lt;span style="color:blue;"&gt;}&amp;quot;&amp;gt;
        &lt;/span&gt;&lt;span style="color:#a31515;"&gt;...
    &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Style&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ResourceDictionary&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;Como podemos ver, este diccionario de recursos contiene estilos, plantillas, brochas y demás recursos que utilizaremos a lo largo de toda nuestra aplicación. Es imprescindible que todos ellos tengan un atributo x:Key para poder ser referenciados desde nuestros elementos de interfaz. Para ello, primero necesitamos agregar a nuestro App.xaml una referencia al diccionario (o diccionarios) de recursos que queramos emplear.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Application.Resources&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
    &lt;/span&gt;&lt;span style="color:green;"&gt;&amp;lt;!-- Resources scoped at the Application level should be defined here. --&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ResourceDictionary&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ResourceDictionary.MergedDictionaries&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ResourceDictionary &lt;/span&gt;&lt;span style="color:red;"&gt;Source&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;Themes\Default.xaml&amp;quot;/&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ResourceDictionary.MergedDictionaries&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ResourceDictionary&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Application.Resources&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;Una vez hecho esto, solo necesitamos aplicar el recurso deseado mediante la extensión de marcado &lt;a href="http://msdn.microsoft.com/en-us/library/ms748942.aspx"&gt;DynamicResource&lt;/a&gt; en la propiedad que nosotros elijamos:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;StackPanel &lt;/span&gt;&lt;span style="color:red;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;Name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;LayoutRoot&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Width&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;600&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Height&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;66&amp;quot;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;StackPanel &lt;/span&gt;&lt;span style="color:red;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;Name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;ButtonStack&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Width&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;Auto&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Orientation&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;Horizontal&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;HorizontalAlignment&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;Right&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Height&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;26&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;ButtonBase.Click&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;ButtonStack_Click&amp;quot;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Button &lt;/span&gt;&lt;span style="color:red;"&gt;Content&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;Home&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;Name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;HomeButton&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Width&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;70&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Style&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color:#a31515;"&gt;DynamicResource &lt;/span&gt;&lt;span style="color:red;"&gt;MenuButtonStyle&lt;/span&gt;&lt;span style="color:blue;"&gt;}&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Height&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;24&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;MouseEnter&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;ButtonStack_MouseEnter&amp;quot;/&amp;gt;
        &lt;/span&gt;&lt;span style="color:#a31515;"&gt;...
    &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;StackPanel&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;No es necesario que especifiquemos un path al recurso, como haríamos con un binding al uso, dado que automáticamente se buscará el recurso en los diccionarios de recursos cargados en ese momento cuando sea necesario mostrarlo. Esa es la diferencia entre DynamicResource y su hermana &lt;a href="http://msdn.microsoft.com/en-us/library/ms750950.aspx"&gt;StaticResource&lt;/a&gt;: mientras que DynamicResource cargará el recurso en el momento en que se muestra el elemento que lo referencia, StaticResource realiza esa asignación en el momento en el que se carga XAML. Esto podemos aprovecharlo para cargar y modificar recursos en tiempo de ejecución, como veremos en un próximo post.&lt;/p&gt;

&lt;p&gt;Otro punto interesante en este sencillo ejemplo de un menú es el acceso a recursos dentro de la plantilla aplicada a un elemento. En nuestro caso, la plantilla que aplicamos a nuestros botones define una Storyboard que queremos utilizar. La manera de hacerlo es la siguiente:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;private void &lt;/span&gt;DoButtonMouseOver(&lt;span style="color:#2b91af;"&gt;Button &lt;/span&gt;origin)
{
    &lt;span style="color:#2b91af;"&gt;Storyboard &lt;/span&gt;mouseOver = (&lt;span style="color:#2b91af;"&gt;Storyboard&lt;/span&gt;)origin.Template.Resources[&lt;span style="color:#a31515;"&gt;&amp;quot;MouseOver&amp;quot;&lt;/span&gt;];
    mouseOver.Begin(origin, origin.Template);
}&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;Como vemos, necesitamos una referencia al objeto Button para acceder a los recursos de su plantilla y buscar la Storyboard que nos interesa, para después llamar a su método &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.media.animation.storyboard.begin.aspx"&gt;Begin&lt;/a&gt;. La particularidad aquí es que no es suficiente con pasarle como argumento el botón, puesto que la animación trabaja con objetos de la plantilla y no es capaz de encontrarlos, saludándonos con una bonita &lt;a href="http://msdn.microsoft.com/en-us/library/system.invalidoperationexception.aspx"&gt;InvalidOperationException&lt;/a&gt;. Para ello existe una sobrecarga del método Begin que recibe tanto el elemento sobre el que se inicia la animación como la plantilla que la contiene.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Rock Tip. Siguiendo mi rutina habitual de añadir canciones sin ninguna relación con lo relatado, os presento hoy uno de los grupos que mejor capturan la esencia del &lt;a href="http://en.wikipedia.org/wiki/Shock_rock"&gt;Shock Rock&lt;/a&gt; abanderado por &lt;a href="http://es.wikipedia.org/wiki/Kiss"&gt;KISS&lt;/a&gt;, el conjunto liderado por Blackie Lawless &lt;a href="http://es.wikipedia.org/wiki/W.A.S.P."&gt;W.A.S.P.&lt;/a&gt;, con su canción (de genial videoclip) &lt;a href="http://www.youtube.com/watch?v=V5LdwK5rKAU"&gt;Wild Child&lt;/a&gt;. Enjoy!!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=147175" width="1" height="1"&gt;</content><author><name>fmartinez</name><uri>http://geeks.ms/members/fmartinez/default.aspx</uri></author><category term="WPF" scheme="http://geeks.ms/blogs/fmartinez/archive/tags/WPF/default.aspx" /></entry><entry><title>La nueva MSDN</title><link rel="alternate" type="text/html" href="/blogs/fmartinez/archive/2009/04/16/la-nueva-msdn.aspx" /><id>/blogs/fmartinez/archive/2009/04/16/la-nueva-msdn.aspx</id><published>2009-04-16T10:05:51Z</published><updated>2009-04-16T10:05:51Z</updated><content type="html">&lt;p&gt;O &lt;em&gt;“Como obtener mas visitas en un blog gracias a un título levemente amarillista&lt;/em&gt;”. El caso es que no podemos hablar de una nueva MSDN, pero si de una nueva manera de acceder a su información de forma más sencilla y accesible. Microsoft mantiene diversas versiones de la MSDN para distintos soportes: dispositivos móviles, pantalla, impresión, etc. De un tiempo a esta parte se ha sumado una nueva versión “Low Bandwidth” creada para consumir menos ancho de banda. Para ello han eliminado gran cantidad de elementos pero intentando siempre mantener la información inalterable. El resultado? Una web mucho mas ligera y sencilla de consultar, como podéis comprobar vosotros mismos:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.object.aspx"&gt;System.Object en la MSDN&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.object(loband).aspx"&gt;System.Object en la MSDN Low Bandwidth&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Para acceder a los artículos de MSDN de está forma solo tenéis que añadir a la URL la opción (loband) como en el segundo enlace, y además tendréis una opción en la esquina superior derecha de vuestras pantallas para establecerlo como modo por defecto. &lt;/p&gt;  &lt;hr /&gt;  &lt;p&gt;Rock Tip. &lt;a href="http://es.wikipedia.org/wiki/Danger_Danger"&gt;Danger Danger&lt;/a&gt; es un grupo de hard rock que por desgracia llego demasiado tarde, en esa triste época en la que aparecieron Nirvana y el grunge para acabar con todo lo bueno. Pese a todo, un grupo con un gran vocalista, un excelente guitarra y melodías muy pegadizas no puede quedar en el olvido (aunque de eso ya se encarga mi compañero &lt;a href="http://geeks.ms/blogs/palvarez/"&gt;Pablo Doval&lt;/a&gt;), así que rescatare para este post su clásico &lt;a href="http://www.youtube.com/watch?v=S7C-Ynv254Y"&gt;Rock America&lt;/a&gt;, que aunque suena bien en directo, suena mejor en un Corvette rojo descapotado…Enjoy!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=146862" width="1" height="1"&gt;</content><author><name>fmartinez</name><uri>http://geeks.ms/members/fmartinez/default.aspx</uri></author><category term="Accesibilidad" scheme="http://geeks.ms/blogs/fmartinez/archive/tags/Accesibilidad/default.aspx" /><category term="MSDN" scheme="http://geeks.ms/blogs/fmartinez/archive/tags/MSDN/default.aspx" /></entry><entry><title>Un sencillo menú en WPF: Estilos y Plantillas (I)</title><link rel="alternate" type="text/html" href="/blogs/fmartinez/archive/2009/04/15/un-sencillo-men-250-en-wpf-estilos-y-plantillas-i.aspx" /><link rel="enclosure" type="application/zip" length="103192" href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.00.14.67.74/DynamicMenu.zip" /><id>/blogs/fmartinez/archive/2009/04/15/un-sencillo-men-250-en-wpf-estilos-y-plantillas-i.aspx</id><published>2009-04-15T08:53:00Z</published><updated>2009-04-15T08:53:00Z</updated><content type="html">&lt;p&gt;En el post anterior sobre la &lt;a href="http://geeks.ms/blogs/fmartinez/archive/2009/04/01/creando-un-motion-path-desde-visual-studio.aspx"&gt;creaci&amp;oacute;n de un Motion Path desde Visual Studio&lt;/a&gt;, &lt;a href="http://geeks.ms/user/Profile.aspx?UserID=5921"&gt;Julio Trujillo&lt;/a&gt; comentaba sobre la posibilidad de aplicar lo aprendido para la creaci&amp;oacute;n de un men&amp;uacute; similar al de &lt;a href="http://silverlight.net/"&gt;Silverlight.net&lt;/a&gt;. Lo que haremos ser&amp;aacute;, en lugar de limitarnos a crear el men&amp;uacute;, aprovecharlo para aprender alguna cosa nueva, en este caso, algo sobre estilos y plantillas.&lt;/p&gt;
&lt;p&gt;Lo primero de todo es saber lo que es cada cosa. Un estilo (&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.style.aspx"&gt;Style&lt;/a&gt;) no es mas que un conjunto de objetos de tipo &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.setter.aspx"&gt;Setter&lt;/a&gt;, pares de propiedad y valor, aplicados a los objetos de un tipo concreto. Es decir, un estilo nos permite definir un recurso compartido para mantener la coherencia de nuestra interfaz de usuario, abarcando tanto el aspecto visual (recursos, propiedades) como el comportamiento (&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.eventtrigger.aspx"&gt;triggers&lt;/a&gt;) de las instancias de un tipo concreto. Ve&amp;aacute;moslo con un ejemplo de nuestro proyecto.&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Style &lt;/span&gt;&lt;span style="color:red;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;Key&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;MenuButtonStyle&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;TargetType&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color:#a31515;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Type &lt;/span&gt;&lt;span style="color:red;"&gt;Button&lt;/span&gt;&lt;span style="color:blue;"&gt;}&amp;quot;&amp;gt;&lt;br /&gt;        &amp;hellip;&lt;/span&gt;&lt;span style="color:blue;"&gt;&lt;br /&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Setter &lt;/span&gt;&lt;span style="color:red;"&gt;Property&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;HorizontalContentAlignment&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Value&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;Center&amp;quot;/&amp;gt;&lt;br /&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Setter &lt;/span&gt;&lt;span style="color:red;"&gt;Property&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;VerticalContentAlignment&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Value&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;Center&amp;quot;/&amp;gt;&lt;br /&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Setter &lt;/span&gt;&lt;span style="color:red;"&gt;Property&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;Padding&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Value&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Setter &lt;/span&gt;&lt;span style="color:red;"&gt;Property&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;Template&amp;quot;&amp;gt;&lt;br /&gt;            &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Setter.Value&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;                &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ControlTemplate &lt;/span&gt;&lt;span style="color:red;"&gt;TargetType&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color:#a31515;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Type &lt;/span&gt;&lt;span style="color:red;"&gt;Button&lt;/span&gt;&lt;span style="color:blue;"&gt;}&amp;quot;&amp;gt;&lt;br /&gt;                    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ControlTemplate.Resources&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;                        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Storyboard &lt;/span&gt;&lt;span style="color:red;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;Key&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;MouseOver&amp;quot;&amp;gt;&amp;hellip;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Storyboard&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;                        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Storyboard &lt;/span&gt;&lt;span style="color:red;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;Key&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;UnMouseOver&amp;quot;&amp;gt;&amp;hellip;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Storyboard&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;                        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Storyboard &lt;/span&gt;&lt;span style="color:red;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;Key&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;Click&amp;quot;&amp;gt;&amp;hellip;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Storyboard&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;                        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Storyboard &lt;/span&gt;&lt;span style="color:red;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;Key&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;UnClick&amp;quot;&amp;gt;&amp;hellip;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Storyboard&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;                    &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ControlTemplate.Resources&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;                    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Grid &lt;/span&gt;&lt;span style="color:red;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;Name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;LayoutRoot&amp;quot;&amp;gt;&amp;hellip;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Grid&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;                &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ControlTemplate&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;            &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Setter.Value&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;        &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Setter&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;    &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Style&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ah&amp;iacute; podemos ver el estilo de los botones de nuestro men&amp;uacute; (levemente editado para que no nos ocupe media p&amp;aacute;gina). Como vemos, le asignamos al estilo una clave (imprescindible para almacenarlo en un diccionario de recursos, como veremos despu&amp;eacute;s) y un tipo de destino, de manera que el estilo se aplicar&amp;aacute; autom&amp;aacute;gicamente a todos los objetos de tipo &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.button.aspx"&gt;Button&lt;/a&gt;. Adem&amp;aacute;s, establecemos las propiedades que queremos que compartan (alineaci&amp;oacute;n y padding entre otras) y la propiedad m&amp;aacute;s interesante de todas: la plantilla (&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.controltemplate.aspx"&gt;Template&lt;/a&gt;). Las plantillas controlan la estructura visual y el comportamiento de los controles en WPF, y son la clave de su flexibilidad a la hora de modificar el aspecto de nuestra aplicaci&amp;oacute;n. Si nos fijamos en el c&amp;oacute;digo anterior, dentro de la plantilla definimos una serie de recursos (storyboard) para su uso dentro de la misma, y le a&amp;ntilde;adimos un Grid, con un contenido. En nuestro caso es el siguiente:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Grid &lt;/span&gt;&lt;span style="color:red;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;Name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;LayoutRoot&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Rectangle &lt;/span&gt;&lt;span style="color:red;"&gt;Opacity&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;0&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;Name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;MassiveGlow&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;StrokeThickness&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Rectangle.Fill&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;            &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;LinearGradientBrush &lt;/span&gt;&lt;span style="color:red;"&gt;EndPoint&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;0.5,1&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;StartPoint&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;0.5,0&amp;quot;&amp;gt;&lt;br /&gt;                &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;GradientStop &lt;/span&gt;&lt;span style="color:red;"&gt;Color&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;#00FFFFFF&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Offset&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;0&amp;quot;/&amp;gt;&lt;br /&gt;                &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;GradientStop &lt;/span&gt;&lt;span style="color:red;"&gt;Color&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;#BEFFFFFF&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Offset&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;0.74&amp;quot;/&amp;gt;&lt;br /&gt;                &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;GradientStop &lt;/span&gt;&lt;span style="color:red;"&gt;Color&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;#00FFFFFF&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Offset&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;            &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;LinearGradientBrush&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;        &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Rectangle.Fill&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;    &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Rectangle&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Rectangle &lt;/span&gt;&lt;span style="color:red;"&gt;Opacity&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;0&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;Name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;Glow&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;StrokeThickness&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Rectangle.Fill&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;            &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;LinearGradientBrush &lt;/span&gt;&lt;span style="color:red;"&gt;EndPoint&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;0.5,1&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;StartPoint&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;0.5,0&amp;quot;&amp;gt;&lt;br /&gt;                &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;GradientStop &lt;/span&gt;&lt;span style="color:red;"&gt;Color&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;#00FFFFFF&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Offset&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;0&amp;quot;/&amp;gt;&lt;br /&gt;                &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;GradientStop &lt;/span&gt;&lt;span style="color:red;"&gt;Color&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;#7FFFFFFF&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Offset&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;0.74&amp;quot;/&amp;gt;&lt;br /&gt;                &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;GradientStop &lt;/span&gt;&lt;span style="color:red;"&gt;Color&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;#00FFFFFF&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Offset&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;            &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;LinearGradientBrush&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;        &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Rectangle.Fill&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;    &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Rectangle&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Rectangle &lt;/span&gt;&lt;span style="color:red;"&gt;Opacity&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;0.795&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;HorizontalAlignment&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;Left&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;Name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;LeftSeparator&amp;quot; &lt;br /&gt;             &lt;/span&gt;&lt;span style="color:red;"&gt;Width&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;1&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Fill&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;#FFFFFFFF&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Stroke&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;#FFFFFFFF&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;StrokeThickness&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Rectangle &lt;/span&gt;&lt;span style="color:red;"&gt;Opacity&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;0.795&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;HorizontalAlignment&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;Right&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;Name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;RightSeparator&amp;quot; &lt;br /&gt;             &lt;/span&gt;&lt;span style="color:red;"&gt;Width&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;1&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Fill&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;#FFFFFFFF&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Stroke&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;#FFFFFFFF&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;TextBlock &lt;/span&gt;&lt;span style="color:red;"&gt;HorizontalAlignment&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;Center&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;Name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;NameTextBlockShadow&amp;quot; &lt;br /&gt;             &lt;/span&gt;&lt;span style="color:red;"&gt;VerticalAlignment&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;Center&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;FontSize&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;14&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Foreground&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;#FF000000&amp;quot; &lt;br /&gt;             &lt;/span&gt;&lt;span style="color:red;"&gt;TextWrapping&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;Wrap&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;d&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;LayoutOverrides&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;Height&amp;quot; &lt;br /&gt;             &lt;/span&gt;&lt;span style="color:red;"&gt;Text&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color:#a31515;"&gt;TemplateBinding &lt;/span&gt;&lt;span style="color:red;"&gt;Content&lt;/span&gt;&lt;span style="color:blue;"&gt;}&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Margin&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;2,2,0,0&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;TextBlock &lt;/span&gt;&lt;span style="color:red;"&gt;HorizontalAlignment&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;Center&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;Name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;NameTextBlock&amp;quot; &lt;br /&gt;             &lt;/span&gt;&lt;span style="color:red;"&gt;VerticalAlignment&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;Center&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;FontSize&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;14&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Foreground&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;#FFFFFFFF&amp;quot; &lt;br /&gt;             &lt;/span&gt;&lt;span style="color:red;"&gt;Text&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color:#a31515;"&gt;TemplateBinding &lt;/span&gt;&lt;span style="color:red;"&gt;Content&lt;/span&gt;&lt;span style="color:blue;"&gt;}&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;TextWrapping&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;Wrap&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Grid&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;Como podemos ver, dentro de ese Grid estamos redefiniendo por completo el aspecto visual de nuestro bot&amp;oacute;n. Creamos dos rect&amp;aacute;ngulos con un brillo para hacer efectos cuando el bot&amp;oacute;n sea seleccionado, otros dos rect&amp;aacute;ngulos como separadores laterales, y dos bloques de texto para el contenido del bot&amp;oacute;n. Ya hemos visto como cambiar el aspecto visual de un elemento editando su estilo y su plantilla, y en el pr&amp;oacute;ximo post veremos como trabajar c&amp;oacute;modamente con los recursos de nuestra aplicaci&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Rock Tip. Aunque es muy com&amp;uacute;n que un grupo musical realice versiones de otros temas adapt&amp;aacute;ndolos con mayor o menor acierto a su estilo, no es tan com&amp;uacute;n que un grupo metal, como los impactantes &lt;a href="http://es.wikipedia.org/wiki/Turisas"&gt;Turisas&lt;/a&gt;, se dedique a versionar a un grupo disco, como &lt;a href="http://es.wikipedia.org/wiki/Boney_M"&gt;Boney M&lt;/a&gt;. Sin embargo, como de cambio de estilos precisamente estamos hablando, me parece mas que interesante resaltar este &lt;a href="http://www.youtube.com/watch?v=Y150Lm4kZ_M"&gt;Rasputin&lt;/a&gt;. Enjoy!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=146774" width="1" height="1"&gt;</content><author><name>fmartinez</name><uri>http://geeks.ms/members/fmartinez/default.aspx</uri></author><category term="WPF" scheme="http://geeks.ms/blogs/fmartinez/archive/tags/WPF/default.aspx" /></entry><entry><title>Creando un Motion Path desde Visual Studio</title><link rel="alternate" type="text/html" href="/blogs/fmartinez/archive/2009/04/01/creando-un-motion-path-desde-visual-studio.aspx" /><link rel="enclosure" type="application/zip" length="43651" href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.00.14.60.24/MotionPathVS.zip" /><id>/blogs/fmartinez/archive/2009/04/01/creando-un-motion-path-desde-visual-studio.aspx</id><published>2009-04-01T08:34:00Z</published><updated>2009-04-01T08:34:00Z</updated><content type="html">&lt;p&gt;En el post anterior vimos &lt;a href="http://geeks.ms/blogs/fmartinez/archive/2009/03/25/creando-un-motion-path-desde-blend.aspx"&gt;como crear un Motion Path desde Blend&lt;/a&gt;, y en este vamos a hacer lo mismo pero desde Visual Studio 2008, a base de c&amp;oacute;digo C#, como verdaderos programadores que somos. Comenzaremos creando un rect&amp;aacute;ngulo id&amp;eacute;ntico al del ejemplo anterior.&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Window&lt;br /&gt;    &lt;/span&gt;&lt;span style="color:red;"&gt;xmlns&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color:red;"&gt;xmlns&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color:red;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;Class&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;MotionPathVS.Window1&amp;quot;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color:red;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;Name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;Window&amp;quot;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color:red;"&gt;Title&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;Window1&amp;quot;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color:red;"&gt;Width&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;640&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Height&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;480&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Grid &lt;/span&gt;&lt;span style="color:red;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;Name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;LayoutRoot&amp;quot;&amp;gt;&lt;br /&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Rectangle &lt;/span&gt;&lt;span style="color:red;"&gt;HorizontalAlignment&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;Left&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;VerticalAlignment&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;Top&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Width&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;100&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Height&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;100&amp;quot; &lt;br /&gt;                   &lt;/span&gt;&lt;span style="color:red;"&gt;Fill&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;#FFF50000&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Stroke&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;#FF000000&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;Name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;rect&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Grid&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Window&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Como vemos aqu&amp;iacute;, no necesitamos para nada el Path, que en nuestro primer ejemplo nos serv&amp;iacute;a para establecer la ruta que seguir&amp;iacute;a el rect&amp;aacute;ngulo. Y este ser&amp;aacute; el &amp;uacute;nico c&amp;oacute;digo XAML que veremos en este post, ya que toda la animaci&amp;oacute;n la construiremos, paso a paso, desde Visual Studio en C#. As&amp;iacute; que empecemos. Lo primero que necesitamos es, valga la redundancia, crear la animaci&amp;oacute;n. Para ello crearemos un &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.media.animation.storyboard.aspx"&gt;Storyboard&lt;/a&gt; al que a&amp;ntilde;adiremos dos animaciones, una para desplazar el objeto por el eje X, otra para el eje Y.&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre class="code"&gt;&lt;span style="color:#2b91af;"&gt;Storyboard &lt;/span&gt;motion = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Storyboard&lt;/span&gt;();&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#2b91af;"&gt;DoubleAnimationUsingPath &lt;/span&gt;x = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DoubleAnimationUsingPath&lt;/span&gt;();&lt;br /&gt;&lt;span style="color:#2b91af;"&gt;DoubleAnimationUsingPath &lt;/span&gt;y = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DoubleAnimationUsingPath&lt;/span&gt;();&lt;br /&gt;&lt;br /&gt;motion.Children.Add(x);&lt;br /&gt;motion.Children.Add(y);&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Est&amp;aacute; animaci&amp;oacute;n tendr&amp;aacute; que trabajar sobre la &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.media.translatetransform.aspx"&gt;TranslateTransform&lt;/a&gt; del objeto que queremos desplazar, en este caso rect. Pero si nos fijamos en el c&amp;oacute;digo XAML, esa TranslateTransform no parece por ning&amp;uacute;n sitio, as&amp;iacute; que tendremos que crearla, asign&amp;aacute;rsela a rect como &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.uielement.rendertransform.aspx"&gt;RenderTransform&lt;/a&gt; y registrarla para que pueda ser utilizada por nuestra animaci&amp;oacute;n.&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre class="code"&gt;&lt;span style="color:#2b91af;"&gt;TranslateTransform &lt;/span&gt;translate = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;TranslateTransform&lt;/span&gt;(0,200);&lt;br /&gt;&lt;span style="color:blue;"&gt;this&lt;/span&gt;.RegisterName(&lt;span style="color:#a31515;"&gt;&amp;quot;Translate&amp;quot;&lt;/span&gt;, translate);&lt;br /&gt;rect.RenderTransform = translate;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;El pr&amp;oacute;ximo paso es construir el path que queremos que recorra nuestra animaci&amp;oacute;n. En este caso utilizaremos una &lt;a href="http://es.wikipedia.org/wiki/Curva_de_B%C3%A9zier"&gt;Curva de B&amp;eacute;zier&lt;/a&gt;, partiendo del punto (0, 200), finalizando en (500, 300) y con el punto de control en (150, 0). Esto generar&amp;aacute; de forma bastante sencilla una curva sobre la que desplazaremos el objeto entre los dos puntos.&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre class="code"&gt;&lt;span style="color:#2b91af;"&gt;PathGeometry &lt;/span&gt;geometry = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;PathGeometry&lt;/span&gt;();&lt;br /&gt;&lt;span style="color:#2b91af;"&gt;PathFigure &lt;/span&gt;figure = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;PathFigure&lt;/span&gt;();&lt;br /&gt;figure.StartPoint = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Point&lt;/span&gt;(0,200);&lt;br /&gt;figure.Segments.Add(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;QuadraticBezierSegment&lt;/span&gt;(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Point&lt;/span&gt;(150, 0), &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Point&lt;/span&gt;(500, 300), &lt;span style="color:blue;"&gt;false&lt;/span&gt;));&lt;br /&gt;geometry.Figures.Add(figure);&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;Con esto tenemos los elementos b&amp;aacute;sicos que necesitamos: la animaci&amp;oacute;n, la ruta y el objeto. Lo &amp;uacute;nico que nos queda es relacionarlos entre s&amp;iacute;. Utilizamos los m&amp;eacute;todos est&amp;aacute;ticos de la clase Storyboard para establecer en cada una de las animaciones el objeto y la propiedad del mismo con la que trabajaran. Con SetTargetName indicamos que ambas animaciones trabajaran sobre la transformaci&amp;oacute;n que registramos antes, y con SetTargetProperty hacemos que cada una de ellas trabaje con el eje correspondiente.&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre class="code"&gt;&lt;span style="color:#2b91af;"&gt;Storyboard&lt;/span&gt;.SetTargetName(x, &lt;span style="color:#a31515;"&gt;&amp;quot;Translate&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#2b91af;"&gt;Storyboard&lt;/span&gt;.SetTargetProperty(x, &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;PropertyPath&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;TranslateTransform&lt;/span&gt;.XProperty));&lt;br /&gt;&lt;span style="color:#2b91af;"&gt;Storyboard&lt;/span&gt;.SetTargetName(y, &lt;span style="color:#a31515;"&gt;&amp;quot;Translate&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#2b91af;"&gt;Storyboard&lt;/span&gt;.SetTargetProperty(y, &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;PropertyPath&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;TranslateTransform&lt;/span&gt;.YProperty));&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;Despu&amp;eacute;s, a&amp;ntilde;adimos a cada una de las animaciones el path que creamos anteriormente, y les indicamos que tendr&amp;aacute;n que utilizar como fuente el eje que les toque.&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre class="code"&gt;x.PathGeometry = geometry;&lt;br /&gt;y.PathGeometry = geometry;&lt;br /&gt;&lt;br /&gt;x.Source = &lt;span style="color:#2b91af;"&gt;PathAnimationSource&lt;/span&gt;.X;&lt;br /&gt;y.Source = &lt;span style="color:#2b91af;"&gt;PathAnimationSource&lt;/span&gt;.Y;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Por &amp;uacute;ltimo, a&amp;ntilde;adimos una serie de atributos, m&amp;aacute;s o menos esenciales, para dar forma a nuestra animaci&amp;oacute;n. Establecemos la duraci&amp;oacute;n de la misma en un segundo, hacemos que se repita indefinidamente para poder observar el efecto, y establecemos un ratio de deceleraci&amp;oacute;n de 0&amp;rsquo;3. Esto sirve para indicarle a la animaci&amp;oacute;n que el primer 70% del tiempo debe mantener una velocidad constante, y el 30% final debe decelerar, d&amp;aacute;ndole un aspecto m&amp;aacute;s real.&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre class="code"&gt;y.Duration = &lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;.FromMilliseconds(1000);&lt;br /&gt;x.Duration = &lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;.FromMilliseconds(1000);&lt;br /&gt;&lt;br /&gt;y.DecelerationRatio = 0.3;&lt;br /&gt;x.DecelerationRatio = 0.3;&lt;br /&gt;&lt;br /&gt;motion.RepeatBehavior = &lt;span style="color:#2b91af;"&gt;RepeatBehavior&lt;/span&gt;.Forever;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;Con esto tenemos ya nuestra animaci&amp;oacute;n lista (pod&amp;eacute;is verla en el proyecto adjunto), y con el mismo m&amp;eacute;todo podemos crear todo tipo de animaciones para aplicar a nuestros objetos, sin necesidad de depender de Blend para nada.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Rock Tip. Ya que en el anterior habl&amp;aacute;bamos de Heavy Metal cl&amp;aacute;sico, que mejor que traer hoy a los que son a juicio de muchos los m&amp;aacute;s grandes del g&amp;eacute;nero, Manowar. Desde luego, tienen el honor de ser los que m&amp;aacute;s ruido hacen encima de un escenario. De su &amp;uacute;ltimo disco, Gods of War, llega este &lt;a href="http://www.youtube.com/watch?v=lf9OnQDhlZA"&gt;King of Kings&lt;/a&gt; para cerrar este post. Enjoy!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=146024" width="1" height="1"&gt;</content><author><name>fmartinez</name><uri>http://geeks.ms/members/fmartinez/default.aspx</uri></author><category term="WPF" scheme="http://geeks.ms/blogs/fmartinez/archive/tags/WPF/default.aspx" /></entry><entry><title>Creando un Motion Path desde Blend</title><link rel="alternate" type="text/html" href="/blogs/fmartinez/archive/2009/03/25/creando-un-motion-path-desde-blend.aspx" /><id>/blogs/fmartinez/archive/2009/03/25/creando-un-motion-path-desde-blend.aspx</id><published>2009-03-25T21:43:00Z</published><updated>2009-03-25T21:43:00Z</updated><content type="html">&lt;p&gt;Reconozc&amp;aacute;moslo. No tengamos miedo. Sabemos que es algo para lo que no estamos preparados, pero es as&amp;iacute;: a veces tendremos que hacer trabajo de dise&amp;ntilde;adores. No hay mas que hablar, llegara un momento en el que tendremos que remangarnos y abrir Expression Blend, y no queda bien que un programador hecho y derecho se ponga a llorar como un bebe al verlo. Paletas de colores, elementos visuales...yuyu may&amp;uacute;sculo. Hoy haremos algo tremendamente sencillo, tanto que casi nos dar&amp;aacute; verg&amp;uuml;enza al verlo.&lt;/p&gt;
&lt;p&gt;Utilizaremos la opci&amp;oacute;n &amp;ldquo;Convert to Motion Path&amp;rdquo; para crear una asociaci&amp;oacute;n entre un UIElement y un Path, de tal manera que el primero se desplace de forma autom&amp;aacute;gica siguiendo la ruta marcada por el segundo. Empezamos creando un horrible rect&amp;aacute;ngulo rojo, que llamaremos rect, y un sencillo path que sigue una l&amp;iacute;nea recta.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/fmartinez/canvas_5F00_034AE937.jpg"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:block;float:none;margin-left:auto;border-top:0px;margin-right:auto;border-right:0px;" title="canvas" alt="canvas" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/fmartinez/canvas_5F00_thumb_5F00_08B959DB.jpg" border="0" height="435" width="582" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Despues, seleccionamos el path y elegimos en el men&amp;uacute; de Blend la opci&amp;oacute;n Object &amp;ndash;&amp;gt; Path &amp;ndash;&amp;gt; Convert to Motion Path.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/fmartinez/menu_5F00_27239AC4.jpg"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:block;float:none;margin-left:auto;border-top:0px;margin-right:auto;border-right:0px;" title="menu" alt="menu" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/fmartinez/menu_5F00_thumb_5F00_631FB6AC.jpg" border="0" height="432" width="603" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;F&amp;aacute;cil, sencillo y para toda la familia. Vamos a echarle un ojo al XAML que genera, a ver si vemos algo interesante.&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Storyboard &lt;/span&gt;&lt;span style="color:red;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;Key&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;MotionPath&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;DoubleAnimationUsingPath &lt;/span&gt;&lt;span style="color:red;"&gt;BeginTime&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;00:00:00&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Duration&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;00:00:02&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Storyboard.TargetName&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;rect&amp;quot; &lt;br /&gt;                              &lt;/span&gt;&lt;span style="color:red;"&gt;Storyboard.TargetProperty&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)&amp;quot; &lt;br /&gt;                              &lt;/span&gt;&lt;span style="color:red;"&gt;Source&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;X&amp;quot;&amp;gt;&lt;br /&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;DoubleAnimationUsingPath.PathGeometry&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;            &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;PathGeometry &lt;/span&gt;&lt;span style="color:red;"&gt;Figures&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;M25.5,166.5 L171,40 361,181 499,166.5&amp;quot;/&amp;gt;&lt;br /&gt;        &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;DoubleAnimationUsingPath.PathGeometry&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;    &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;DoubleAnimationUsingPath&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;DoubleAnimationUsingPath &lt;/span&gt;&lt;span style="color:red;"&gt;BeginTime&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;00:00:00&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Duration&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;00:00:02&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Storyboard.TargetName&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;rect&amp;quot; &lt;br /&gt;                              &lt;/span&gt;&lt;span style="color:red;"&gt;Storyboard.TargetProperty&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)&amp;quot; &lt;br /&gt;                              &lt;/span&gt;&lt;span style="color:red;"&gt;Source&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;Y&amp;quot;&amp;gt;&lt;br /&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;DoubleAnimationUsingPath.PathGeometry&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;            &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;PathGeometry &lt;/span&gt;&lt;span style="color:red;"&gt;Figures&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;M25.5,166.5 L171,40 361,181 499,166.5&amp;quot;/&amp;gt;&lt;br /&gt;        &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;DoubleAnimationUsingPath.PathGeometry&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;    &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;DoubleAnimationUsingPath&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Storyboard&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Como vemos, la opci&amp;oacute;n Convert to Motion Path nos crea autom&amp;aacute;gicamente un Storyboard, con una duraci&amp;oacute;n de dos segundos, y dos DoubleAnimationUsingPath, que actuaran respectivamente sobre TranslateTransform.X y TranslateTransform.Y del objeto rect (el rect&amp;aacute;ngulo rojo que queremos desplazar). Lo m&amp;aacute;s interesante es que una vez creado el Storyboard, el Path que seleccionamos para crearlo se copia en ambas animaciones, y ya no es necesario que lo mantengamos en el &amp;aacute;rbol visual. Esto tambi&amp;eacute;n conlleva que, si queremos modificar la ruta que seguir&amp;aacute; nuestro elemento, tendremos que modificar la animaci&amp;oacute;n, no el path original. Para ello no tenemos mas que abrir la animaci&amp;oacute;n y seleccionar el elemento animado.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/fmartinez/animation_5F00_1F1BD295.jpg"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:block;float:none;margin-left:auto;border-top:0px;margin-right:auto;border-right:0px;" title="animation" alt="animation" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/fmartinez/animation_5F00_thumb_5F00_032A9D9D.jpg" border="0" height="379" width="476" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Vemos como tenemos una animaci&amp;oacute;n de traslaci&amp;oacute;n, que podemos extender en el tiempo si queremos, y como tenemos tambi&amp;eacute;n una l&amp;iacute;nea punteada que nos indica el path que se esta siguiendo actualmente. Si quisi&amp;eacute;ramos modificarlo, ser&amp;iacute;a tan sencillo como utilizar la herramienta Pen y a&amp;ntilde;adirle un par de nodos, para posteriormente desplazarlos con la herramienta de selecci&amp;oacute;n directa.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/fmartinez/animation2_5F00_1F77DFBD.jpg"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:block;float:none;margin-left:auto;border-top:0px;margin-right:auto;border-right:0px;" title="animation2" alt="animation2" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/fmartinez/animation2_5F00_thumb_5F00_502AE768.jpg" border="0" height="224" width="469" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Y con esto, ya hemos aprendido a hacer&amp;hellip;una tonter&amp;iacute;a. Tonter&amp;iacute;a que, sin embargo, os servir&amp;aacute; a vosotros para construir de manera sencilla animaciones mucho mas complejas, y a m&amp;iacute; para poder hacer otro post explicando como hacer lo mismo desde Visual Studio 2008, con mucho mas texto, muchas menos im&amp;aacute;genes y mucha mas diversi&amp;oacute;n ;)&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Rock Tip. Mis compa&amp;ntilde;eros &lt;a href="http://geeks.ms/blogs/palvarez/"&gt;Pablo &amp;Aacute;lvarez&lt;/a&gt; y &lt;a href="http://geeks.ms/blogs/ohernandez/default.aspx"&gt;Octavio Hern&amp;aacute;ndez&lt;/a&gt; tienen la buena costumbre de cerrar sus (magn&amp;iacute;ficos) posts con un (no menos magn&amp;iacute;fico) Rock Tip, recomendando grandes temas a menudo olvidados. Como yo no puedo ser menos, aqu&amp;iacute; va el de hoy. No nos vamos a remontar muy atr&amp;aacute;s en el tiempo, con un disco de este mismo a&amp;ntilde;o, aunque parezca salido de los 80&amp;hellip;heavy metal cl&amp;aacute;sico, venido de Polonia, y cantado por una mujer, &lt;a href="http://en.wikipedia.org/wiki/Doro_(band)"&gt;Doro&lt;/a&gt; style. &lt;a href="http://www.myspace.com/crystalviperofficial"&gt;Crystal Viper&lt;/a&gt;, con su &lt;a href="http://www.youtube.com/watch?v=xg2F6RSJlDc"&gt;&amp;ldquo;The Anvil of Hate&amp;rdquo;&lt;/a&gt; cierran el post de hoy. Enjoy!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=145668" width="1" height="1"&gt;</content><author><name>fmartinez</name><uri>http://geeks.ms/members/fmartinez/default.aspx</uri></author><category term="WPF" scheme="http://geeks.ms/blogs/fmartinez/archive/tags/WPF/default.aspx" /><category term="Blend" scheme="http://geeks.ms/blogs/fmartinez/archive/tags/Blend/default.aspx" /></entry><entry><title>Search Connectors en Windows 7</title><link rel="alternate" type="text/html" href="/blogs/fmartinez/archive/2009/03/18/search-connectors-en-windows-7.aspx" /><link rel="enclosure" type="application/zip" length="392" href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.00.14.51.70/geeks-Search-Connector.zip" /><id>/blogs/fmartinez/archive/2009/03/18/search-connectors-en-windows-7.aspx</id><published>2009-03-18T16:03:00Z</published><updated>2009-03-18T16:03:00Z</updated><content type="html">&lt;p&gt;Una de las nuevas caracter&amp;iacute;sticas de Windows 7 es el soporte a la denominada &lt;a href="http://en.wikipedia.org/wiki/Federated_search"&gt;Federated Search &lt;/a&gt;que nos permite, por ejemplo, agregar proveedores de busqueda a Windows Explorer para realizar consultas sobre sitios web (Search Connectors). Gracias a esta caracter&amp;iacute;stica, podemos integrar en Windows Explorer nuestras busquedas en servicios tan diversos como Google, flickr, Wikipedia, etc. sin falta de abrir una ventana de nuestro navegador web. Es m&amp;aacute;s, una vez realizada la busqueda podemos no solo consultar los resultados, sino abrirlos, imprimirlos y demas operaciones b&amp;aacute;sicas. Podr&amp;iacute;amos, por ejemplo, buscar &amp;quot;Las Meninas&amp;quot; en la p&amp;aacute;gina web de la Wikipedia e imprimir el resultado sin falta de abrir nuestro navegador en ning&amp;uacute;n momento!&lt;/p&gt;
&lt;p&gt;Microsoft ha publicado una &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=c709a596-a9e9-49e7-bcd4-319664929317&amp;amp;displaylang=en&amp;amp;tm"&gt;guia para implementar Search Connectors&lt;/a&gt;, eso si, en ingles, que nos ayudara a crear los nuestros sin mucha dificultad, ya que en el fondo no son mas que un archivo xml de pocas lineas. Para que veais lo sencillo que es, he creado uno para realizar busquedas aqui, en &lt;a&gt;geeks.ms&lt;/a&gt;. Si lo descomprimis y abris el archivo .osdx con cualquier editor de texto os dareis cuenta de lo sencillo que es ;)&lt;/p&gt;
&lt;p&gt;Y recordad, esto solo funciona en Windows 7! Enjoy!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=145170" width="1" height="1"&gt;</content><author><name>fmartinez</name><uri>http://geeks.ms/members/fmartinez/default.aspx</uri></author><category term="Windows 7" scheme="http://geeks.ms/blogs/fmartinez/archive/tags/Windows+7/default.aspx" /></entry><entry><title>Drag and drop en WPF (I)</title><link rel="alternate" type="text/html" href="/blogs/fmartinez/archive/2008/05/12/drag-and-drop-en-wpf-i.aspx" /><id>/blogs/fmartinez/archive/2008/05/12/drag-and-drop-en-wpf-i.aspx</id><published>2008-05-12T10:53:00Z</published><updated>2008-05-12T10:53:00Z</updated><content type="html">&lt;p&gt;&lt;font color="#000000"&gt;Un
req&lt;/font&gt;uisito relativamente común en las aplicaciones actuales es la posibilidad de
realizar un &lt;i&gt;drag and drop&lt;/i&gt; (arrastrar y soltar) entre
elementos. Nos permite representar fácilmente dos situaciones de la vida real,
como son el desplazamiento de objetos (en el caso de arrastrar un elemento y
soltarlo en su nueva posición) y el establecimiento de una relación entre
objetos (en el caso de arrastrar un elemento y soltarlo sobre el elemento al
que queremos enlazarlo). &lt;/p&gt;

&lt;p&gt;Trabajando
en WPF tenemos disponible un método muy útil como es &lt;i&gt;UIElement.CaptureMouse&lt;/i&gt;. Mediante este método podemos hacer que
cualquier &lt;i&gt;UIElement&lt;/i&gt; se haga con el control exclusivo del ratón, y
cualquier evento generado por el ratón en otro elemento será ignorado. Esto nos
permite gestionar funcionalidad como el &lt;i&gt;drag and
drop&lt;/i&gt; sin interferir
en otros elementos de la interfaz. Veamos un ejemplo de cómo gestionar el
desplazamiento de un elemento sobre un canvas:&lt;/p&gt;

&lt;p&gt;Primero
escribimos un manejador para el evento de &lt;i&gt;MouseLeftButtonDown&lt;/i&gt; del elemento que
queremos arrastrar (en este caso una elipse):&lt;/p&gt;

&lt;div style="background:white none repeat scroll 0% 50%;font-family:Consolas;font-size:10pt;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; Ellipse_MouseLeftButtonDown(&lt;span style="color:blue;"&gt;object&lt;/span&gt; sender, &lt;span style="color:LightSeaGreen;"&gt;MouseButtonEventArgs&lt;/span&gt; e)&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:LightSeaGreen;"&gt;Ellipse&lt;/span&gt; ellipse = sender &lt;span style="color:blue;"&gt;as&lt;/span&gt; &lt;span style="color:LightSeaGreen;"&gt;Ellipse&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (ellipse != &lt;span style="color:blue;"&gt;null&lt;/span&gt;)&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ellipse.CaptureMouse();&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;En este
manejador nos limitamos a capturar el ratón cuando el usuario hace click sobre
nuestra elipse. Posteriormente, escribimos un manejador para el evento MouseLeftButtonUp, que hará el proceso inverso, es decir, liberar el ratón:&lt;/p&gt;

&lt;div style="background:white none repeat scroll 0% 50%;font-family:Consolas;font-size:10pt;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; Ellipse_MouseLeftButtonUp(&lt;span style="color:blue;"&gt;object&lt;/span&gt; sender, &lt;span style="color:LightSeaGreen;"&gt;MouseButtonEventArgs&lt;/span&gt; e)&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:LightSeaGreen;"&gt;Ellipse&lt;/span&gt; ellipse = sender &lt;span style="color:blue;"&gt;as&lt;/span&gt; &lt;span style="color:LightSeaGreen;"&gt;Ellipse&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (ellipse != &lt;span style="color:blue;"&gt;null&lt;/span&gt;)&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ellipse.ReleaseMouseCapture();&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Ahora
la única tarea que nos queda es gestionar el movimiento de la elipse cuando
movamos el ratón. Dado que tenemos capturados los eventos del ratón, únicamente
tenemos que preocuparnos de mover la elipse cuando este se mueva, para lo que
aprovechamos el evento MouseMove:&lt;/p&gt;

&lt;div style="background:white none repeat scroll 0% 50%;font-family:Consolas;font-size:10pt;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;
&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; private&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; Ellipse_MouseMove(&lt;span style="color:blue;"&gt;object&lt;/span&gt; sender, &lt;span style="color:LightSeaGreen;"&gt;MouseEventArgs&lt;/span&gt; e)&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:LightSeaGreen;"&gt;Ellipse&lt;/span&gt; ellipse = sender &lt;span style="color:blue;"&gt;as&lt;/span&gt; &lt;span style="color:LightSeaGreen;"&gt;Ellipse&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (ellipse != &lt;span style="color:blue;"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; ellipse.IsMouseCaptured)&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:LightSeaGreen;"&gt;Canvas&lt;/span&gt;.SetLeft(ellipse, e.GetPosition(MovementCanvas).X);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:LightSeaGreen;"&gt;Canvas&lt;/span&gt;.SetTop(ellipse, e.GetPosition(MovementCanvas).Y);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;/div&gt;&lt;p&gt;
Con
este código tan sencillo hemos conseguido desplazar una elipse mediante una
operación de drag and drop.
Pese a que faltan multitud de comprobaciones para que el código sea optimo (la
elipse puede salirse de los bordes del canvas,
por ejemplo), sí que nos sirve para ilustrar nuestro primer ejemplo de drag
and drop.
En la segunda parte de este artículo, veremos cómo realizar un drag
and drop
que establezca una relación entre dos objetos.&lt;/p&gt;&lt;p&gt;&lt;a href="http://geeks.ms/blogs/fmartinez/DragAndDropMoving.zip"&gt;Descarga el código completo&lt;br /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt; &lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=85392" width="1" height="1"&gt;</content><author><name>fmartinez</name><uri>http://geeks.ms/members/fmartinez/default.aspx</uri></author><category term="WPF" scheme="http://geeks.ms/blogs/fmartinez/archive/tags/WPF/default.aspx" /></entry><entry><title>Dreamland / AJAX y la accesibilidad web. Tips &amp; tricks</title><link rel="alternate" type="text/html" href="/blogs/fmartinez/archive/2007/01/16/dreamland-ajax-y-la-accesibilidad-web-tips-tricks.aspx" /><id>/blogs/fmartinez/archive/2007/01/16/dreamland-ajax-y-la-accesibilidad-web-tips-tricks.aspx</id><published>2007-01-16T10:28:00Z</published><updated>2007-01-16T10:28:00Z</updated><content type="html">&lt;p&gt;En el anterior post os comentaba los principales problemas que tiene AJAX a la hora de desarrollar aplicaciones accesibles. Ahora vamos a ver un par de pequeños consejos que, si bien no resuelven estos problemas en su totalidad, al menos disminuyen su impacto. &lt;/p&gt;&lt;p&gt;Deciamos que el primer problema era la dependencia que tienen las aplicaciones AJAX de JavaScript, y como este no se lleva bien con los lectores de pantalla. Pues bien, el primer consejo no podria ser mas simple: hacer que nuestras paginas sean capaces de funcionar con JavaScript deshabilitado. Tan simple (y tan complejo) como eso. Si somos capaces de ofrecer a nuestros usuarios la experiencia mejorada de AJAX solo si ellos la reclaman, cualquier persona podra elegir la manera que prefiera para acceder a nuestra aplicacion. Evidentemente, esto conlleva un trabajo extra para el desarrollador, y muchas veces se piensa que nadie estara interesado en ver una version "antigua" de nuestra web. pero...y si la version anterior es la unica que pueden utilizar?&lt;/p&gt;&lt;p&gt;Otro problema que teniamos era el hecho de que los lectores de pantalla no se dan por aludidos ante una actualizacion parcial de la pagina. De hecho, este problema no es exclusivo de los lectores de pantalla, sino que muchisimas personas no se dan cuenta de estos cambios al ser sumamente pequeños en ocasiones. Para esto, de nuevo, la mejor solucion es informar al usuario, Por una parte, deberiamos comunicarle que la informacion de la pagina se actualizara de forma dinamica, y tambien deberiamos darle la opcion de recibir una alerta (algo tan simple como un popup es mas que suficiente) cuando se produzca esta actualizacion. Y por otra parte esta la denominada &lt;a href="http://www.37signals.com/svn/archives/000558.php" target="_blank"&gt;"Yellow Fade Technique"&lt;/a&gt;, popularizada por los chicos de &lt;a href="http://www.37signals.com/" target="_blank"&gt;37signals&lt;/a&gt;, que no es mas que aplicar algun efecto a la zona modificada de manera que esta "resalte", y sea mucho mas sencillo para el usuario darse cuenta de las modificaciones.&lt;/p&gt;&lt;p&gt;En fin, no son mas que un par de consejos que nos permitiran, con mas o menos esfuerzo, seguir desarrollando con AJAX, pero teniendo en cuenta la accesibilidad. Pronto os colgare algun ejemplo practico de como llevar esto a cabo.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=8714" width="1" height="1"&gt;</content><author><name>fmartinez</name><uri>http://geeks.ms/members/fmartinez/default.aspx</uri></author><category term="AJAX" scheme="http://geeks.ms/blogs/fmartinez/archive/tags/AJAX/default.aspx" /><category term="Accesibilidad" scheme="http://geeks.ms/blogs/fmartinez/archive/tags/Accesibilidad/default.aspx" /><category term="ASP.NET" scheme="http://geeks.ms/blogs/fmartinez/archive/tags/ASP.NET/default.aspx" /></entry><entry><title>Chainsaw Buffet / AJAX y la accesibilidad web</title><link rel="alternate" type="text/html" href="/blogs/fmartinez/archive/2007/01/15/chainsaw-buffet-ajax-y-la-accesibilidad-web.aspx" /><id>/blogs/fmartinez/archive/2007/01/15/chainsaw-buffet-ajax-y-la-accesibilidad-web.aspx</id><published>2007-01-15T09:47:00Z</published><updated>2007-01-15T09:47:00Z</updated><content type="html">&lt;p&gt;Actualmente estamos viviendo el auge de la llamada "web 2.0", que se nos vende como una web mucho mas rica en contenidos, mas dinamica, y basada en aplicaciones web mas que en webs tradicionales. AJAX no es mas que una parte (importante, eso si) en todo este lio de tecnologias que engloba la "web 2.0", y es simplemente un conjunto de estandares (JavaScript, XML, HTML, CSS...). AJAX es a dia de hoy muy popular entre los desarrolladores, y Microsoft, evidentemente, no lo ignora y lanza su propia vision del asunto, a la que llama ASP.NET/AJAX, y que nos permite añadir a nuestras aplicaciones ASP.NET "de toda la vida" el dinamismo de AJAX sin necesidad de mancharnos las manos con sucio JavaScript (al cual no fui el unico en dar por muerto, verdad &lt;a href="http://geeks.ms/blogs/dsalgado/archive/2006/12/05/voy-a-desempolvar-el-libro-de-latin-aka-ida-de-olla.aspx" target="_blank"&gt;Salgado&lt;/a&gt;?). La pregunta es, hasta que punto este dinamismo, sin cuestionar ya su utilidad, llega a todo el mundo? O preguntando de forma mas tecnica...es AJAX accesible?&lt;/p&gt;&lt;p&gt;La respuesta es no...por el momento. Y las razones son bien sencillas, y no son mas que la absoluta dependencia que tiene AJAX de JavaScript y el refresco parcial de las paginas, y la mala relacion que tienen ambas cosas con los lectores de pantalla. La mayoria de los discapacitados que necesitan ayuda para acceder a la web utilizan un lector de pantalla, que se limita a leer lo que el navegador esta mostrando en pantalla. De ahi la insistencia en el uso de texto alternativo en las imagenes, al ser uno de los elementos que un lector de pantalla no puede interpretar. Vamos a ver un poco en detalle en que consisten estos dos problemas:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Dependencia de JavaScript. Browsers como Lynx o Links, no soportan JavaScript. Muchos lectores de pantalla (por suerte, cada vez menos), funcionan sobre Lynx. Y aunque funcionen sobre un browser que si soporte JavaScript, no lo interpretan, sino que intentan extraer algo con el suficiente sentido como para ser leido a un usuario, lo cual no es facil. Cuanto menos JavaScript haya en una web, mas sencillo sera leerla con un lector de pantalla, y AJAX tiende a aumentar cada vez mas el uso de JavaScript.&lt;/li&gt;&lt;li&gt;El refresco parcial de las paginas. Los lectores de pantalla, simplemente, no saben cuando una pagina ha sido actualizada "parcialmente". Para ellos, o se produce una actualizacion (y entonces leeran de nuevo la pantalla al usuario), o no se produce (y entonces no haran nada). Esto supone que una de las principales ventajas de AJAX (si no la mayor) sea no solo inutil, sino contraproducente.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;En resumen, AJAX no se lleva bien con la accesibilidad web. Podemos solucionarlo? Pues parcialmente si, y lo veremos en un proximo post ;)&lt;br&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=8676" width="1" height="1"&gt;</content><author><name>fmartinez</name><uri>http://geeks.ms/members/fmartinez/default.aspx</uri></author><category term="AJAX" scheme="http://geeks.ms/blogs/fmartinez/archive/tags/AJAX/default.aspx" /><category term="Accesibilidad" scheme="http://geeks.ms/blogs/fmartinez/archive/tags/Accesibilidad/default.aspx" /><category term="ASP.NET" scheme="http://geeks.ms/blogs/fmartinez/archive/tags/ASP.NET/default.aspx" /></entry><entry><title>I Don't Feel Like Dancin' / Networking con Virtual PC</title><link rel="alternate" type="text/html" href="/blogs/fmartinez/archive/2007/01/12/i-don-t-feel-like-dancin-networking-con-virtual-pc.aspx" /><id>/blogs/fmartinez/archive/2007/01/12/i-don-t-feel-like-dancin-networking-con-virtual-pc.aspx</id><published>2007-01-12T15:06:00Z</published><updated>2007-01-12T15:06:00Z</updated><content type="html">&lt;p&gt;Aunque no lo parezca, conseguir tener en un mismo PC mas de uno y de dos Sistemas Operativos no es en absoluto dificil. Basta instalarte cualquier software de gestion de maquinas virtuales (&lt;a href="http://www.vmware.com/es/" target="_blank"&gt;VMWare&lt;/a&gt; o &lt;a href="http://www.microsoft.com/spain/windows/virtualpc/default.mspx" target="_blank"&gt;Virtual PC&lt;/a&gt;, por ejemplo), y puedes disponer, ademas de lo que hayas instalado en la maquina host (la unica maquina fisicamente visible, el cacharraco de encima de la mesa), un 2003 Server y un Windows XP donde instalar todas las betas, alphas y RC's que quieras sin miedo a cargarte nada.&lt;/p&gt;&lt;p&gt;La cosa se pone un poco mas peliaguda cuando lo que queremos es que esa maquina se conecte a internet, ya sea para descargar actualizaciones o ficheros de video de los servidores mas concurridos de la red...Aqui os muestro la manera mas sencilla que he encontrado yo para conseguirlo, y es hacer que la maquina virtual salga a internet compartiendo la conexion del host mediante el Microsoft Loopback Adapter. Partiendo de una maquina host con Windows Vista, y una maquina virtual con el sistema operativo X, en Virtual PC...&lt;br&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Nos vamos al Control Panel&lt;/li&gt;&lt;li&gt;Pulsamos sobre "Add Hardware"&lt;/li&gt;&lt;li&gt;Elegimos la opcion "Advanced", que nos permitira seleccionar el hardware en una lista&lt;/li&gt;&lt;li&gt;Nos vamos a "Network adapters", y elegimos como fabricante Microsoft, y como producto el Microsoft Loopback Adapter&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Con esto ya tenemos hecha la primera parte del asunto, y es tener montado el Loopback. Ahora lo que necesitamos es decir que vamos a compartir nuestra conexion de red con otros equipos a traves de el. Para esto, hacemos lo siguiente...&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Nos vamos al Network and Sharing Center&lt;/li&gt;&lt;li&gt;Pulsamos sobre la opcion "View Status" de nuestra conexion de Internet, NO SOBRE LA CONEXION DE LOOPBACK,&amp;nbsp; y pulsamos sobre "Properties"&lt;/li&gt;&lt;li&gt;Seleccionamos la pestaña "Sharing"&lt;/li&gt;&lt;li&gt;Marcamos la opcion de "Allow other network users to connect through...", y en el desplegable seleccionamos Loopback&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Y con esto ya tenemos la segunda parte, que es compartir nuestra conexion de internet a traves del Loopback. Acabar con el asunto es tan sencillo como arrancar Virtual PC y decirle en las propiedades de la maquina virtual que utilice como adaptador de red primario el Microsoft Loopback Adapter. Y listo para la conexion :)&lt;br&gt;&lt;/p&gt;&lt;p&gt;Espero que os sea util&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=8616" width="1" height="1"&gt;</content><author><name>fmartinez</name><uri>http://geeks.ms/members/fmartinez/default.aspx</uri></author><category term="Virtual PC" scheme="http://geeks.ms/blogs/fmartinez/archive/tags/Virtual+PC/default.aspx" /></entry><entry><title>Copycat / He sido taggeado</title><link rel="alternate" type="text/html" href="/blogs/fmartinez/archive/2007/01/05/copycat-he-sido-taggeado.aspx" /><id>/blogs/fmartinez/archive/2007/01/05/copycat-he-sido-taggeado.aspx</id><published>2007-01-05T15:39:00Z</published><updated>2007-01-05T15:39:00Z</updated><content type="html">&lt;p&gt;Pues eso, que se supone que ahora deberia contar cinco cosas de mi que sepa poca o muy poca gente. O nadie. Y como parece que hay interes, porque no me han taggeado ni uno ni dos (sino tres, &lt;a href="http://blogs.msdn.com/ethelcilla/archive/2007/01/04/que-siga-la-marca-por-la-red.aspx" target="_blank"&gt;Ethel&lt;/a&gt;, &lt;a href="http://geeks.ms/blogs/jorge/archive/2007/01/05/touch.aspx" target="_blank"&gt;Jorge&lt;/a&gt; y &lt;a href="http://geeks.ms/blogs/palvarez/archive/2007/01/05/bang-bang-marcado.aspx" target="_blank"&gt;Doval&lt;/a&gt;), pues alla van. Luego no os quejeis :P&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Me chiflan los RPG's. Ya sea en un PC, con dados, con cartas, o con muñecajos, tengo un vicio que no me aguanto. Juego a &lt;a href="http://es.wikipedia.org/wiki/Warhammer_40.000" target="_blank"&gt;Warhammer 40K&lt;/a&gt; desde hace unos 8 años, he coleccionado cartas de &lt;a href="http://es.wikipedia.org/wiki/Magic" target="_blank"&gt;Magic&lt;/a&gt; (&lt;font color="#cc0000"&gt;Mentira, no eran de Magic, eran de Pokemon!!&lt;/font&gt; Da lo mismo, a callar!!!), he estado un año y medio enganchado a &lt;a href="http://en.wikipedia.org/wiki/Ultima_Online" target="_blank"&gt;Ultima Online&lt;/a&gt; y ahora juego al &lt;a href="http://es.wikipedia.org/wiki/World_of_Warcraft" target="_blank"&gt;WoW&lt;/a&gt;, he jugado a n RPG's en un PC y he disfrutado de muchisimos juegos de rol "clasico",con sus dados y sus fichas de personaje. Mucho mucho vicio, mucho mucho dinero y, eso si, mucha mucha diversion.&lt;/li&gt;&lt;li&gt;Durante 4 años hice Judo, hasta que me cambie de colegio. Llegue a ser cinturon naranja-verde, si no me equivoco. Hace ya bastante tiempo de eso :P Despues estuve un par de años practicando Tenis de Mesa, y ahora me (nos, verdad Doval) ha dado por la Esgrima. A ver lo que sale. Eso si, siempre he jugado al futbol de manera irregular, y siempre me han gustado deportes como el Kick-Boxing, o el Muay-Thai, pero mi fragilidiad fisica no me ayuda a animarme :P&lt;/li&gt;&lt;li&gt;Leo regularmente (vease a diario) un buen puñado de webcomics que, curiosamente, poca gente encuentra divertidos. Asi que me ahorrare el poner los links y tener que escuchar por n-esima vez eso de: "No le veo la gracia..."&lt;/li&gt;&lt;li&gt;Aunque pueda parecer lo contrario, de niño nunca me llamaron los ordenadores ni la informatica. Es decir, no mas alla de "Papa monta el Spectrum", o "Papa dejame jugar al &lt;a href="http://en.wikipedia.org/wiki/Atic_Atac" target="_blank"&gt;Atic Atac&lt;/a&gt;". Sin embargo, si que me gustaba jugar con muñecas, y en el colegio en vez de jugar al futbol en el recreo me dedicaba a jugar con niñas y Barbies. Dios, esto empieza a ser humillante...&lt;/li&gt;&lt;li&gt;Me encanta el dulce. Gominolas, chocolate, bombones...todo menos pasteles y tartas. Eso no :( Y aunque no lo parezca dado mi esbelto fisico, como MUCHO. Preguntad si no os fiais :P&lt;/li&gt;&lt;/ol&gt;Y ya esta, 5 cosas contadas. Ahora a ver lo que vais a acabar pensando de mi. Y como ya hay mucha gente taggeada que aun no ha respondido, se lo recuerdo yo. &lt;a href="http://geeks.ms/blogs/cjcachero/default.aspx" target="_blank"&gt;Cachero&lt;/a&gt;, &lt;a href="http://geeks.ms/blogs/programancia101/default.aspx" target="_blank"&gt;Ricardo&lt;/a&gt;, &lt;a href="http://geeks.ms/blogs/fpeula/default.aspx" target="_blank"&gt;Fran&lt;/a&gt;, &lt;a href="http://geeks.ms/blogs/mllopis/default.aspx" target="_blank"&gt;Llopis&lt;/a&gt; y los compañeros de Plain que aun no se han animado...tardando estais :) &lt;br&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=8298" width="1" height="1"&gt;</content><author><name>fmartinez</name><uri>http://geeks.ms/members/fmartinez/default.aspx</uri></author><category term="General" scheme="http://geeks.ms/blogs/fmartinez/archive/tags/General/default.aspx" /></entry><entry><title>Wake the Snake / WPF y su UX</title><link rel="alternate" type="text/html" href="/blogs/fmartinez/archive/2006/12/10/wake-the-snake-wpf-y-su-ux.aspx" /><id>/blogs/fmartinez/archive/2006/12/10/wake-the-snake-wpf-y-su-ux.aspx</id><published>2006-12-10T16:46:00Z</published><updated>2006-12-10T16:46:00Z</updated><content type="html">&lt;P&gt;Ahhh, WPF...el Santo Grial de la programacion de interfaces de usuario, el nuevo paradigma de la presentacion grafica, el summum de los colores el pantalla, el...el...el que??&lt;/P&gt;
&lt;P&gt;Empecemos pues por el principio.&amp;nbsp;WPF es el nuevo susbistema de presentacion grafica incluido en&amp;nbsp;el .NET Framework 3.0, centrando en la&amp;nbsp;tan cacareada &lt;EM&gt;user experience&lt;/EM&gt;. Bien. Y el Madrid que, otra vez campeon de Liga? Que es esto de &lt;EM&gt;user experience&lt;/EM&gt;, o experiencia de usario? Pues no es mas que un esfuerzo por conseguir que los usuarios disfruten de aplicaciones que les permitan hacer las cosas de manera mas &lt;STRONG&gt;facil&lt;/STRONG&gt; y mas &lt;STRONG&gt;atractiva&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;Por que mas facil? Todos estamos hartos de aplicaciones de gestion de &amp;lt;inserteSuCosaAGestionar&amp;gt; que te obligan a pulsar 7 botones en 4 formularios distintos para cambiar de nombre a un usuario. Seamos serios, la mayoria de las interfaces de usuario de hoy en dia son simplemente malas. Son malas porque fallan en su principal objetivo, que es permitir al usuario hacer lo que quiere de la manera mas indolora posible. Eso es lo que pretende el concepto de UX, interfaces simples y efectivas. Ni mas, ni menos.&lt;/P&gt;
&lt;P&gt;Por que mas atractiva? A todo amante de los coches le gustan los Ferraris. Ahora bien, si colocasemos a un F40 un chasis de 600...no seria lo mismo verdad? Tan importante como la funcionalidad de nuestra aplicacion es su aspecto. Es lo primero que va a ver el usuario, lo que marcara la primera impresion que se llevara de nuestra aplicacion. Y puede llegar a ser determinante en la manera que tenga de usarla...o de tirarla a la basura.&lt;/P&gt;
&lt;P&gt;En resumen, UX es la calidad de la experiencia del usuario cuando interactua con nuestra aplicacion. Y nuestro objetivo, al menos el mio a dia de hoy,&amp;nbsp;es hacer que tienda a infinito, utilizando WPF. Os interesa echarme una mano?&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=7357" width="1" height="1"&gt;</content><author><name>fmartinez</name><uri>http://geeks.ms/members/fmartinez/default.aspx</uri></author><category term="WPF" scheme="http://geeks.ms/blogs/fmartinez/archive/tags/WPF/default.aspx" /><category term="UX" scheme="http://geeks.ms/blogs/fmartinez/archive/tags/UX/default.aspx" /></entry></feed>