<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://geeks.ms/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Luis Guerrero - Dot Net World : WPF -&amp;gt; Windows Forms</title><link>http://geeks.ms/blogs/luisguerrero/archive/tags/WPF+-_2600_gt_3B00_+Windows+Forms/default.aspx</link><description>Etiquetas: WPF -&amp;gt; Windows Forms</description><dc:language /><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>[Curso] WPF para programadores de Windows Forms 9 : Templates</title><link>http://geeks.ms/blogs/luisguerrero/archive/2009/06/29/curso-wpf-para-programadores-de-windows-forms-9-templates.aspx</link><pubDate>Mon, 29 Jun 2009 12:08:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:151468</guid><dc:creator>Luis Guerrero</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/luisguerrero/rsscomments.aspx?PostID=151468</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/luisguerrero/commentapi.aspx?PostID=151468</wfw:comment><comments>http://geeks.ms/blogs/luisguerrero/archive/2009/06/29/curso-wpf-para-programadores-de-windows-forms-9-templates.aspx#comments</comments><description>&lt;p&gt;[Curso] WPF para programadores de Windows Forms 9 : Templates&lt;/p&gt;
&lt;p&gt;En el post anterior coment&amp;aacute;bamos como en WPF existen el &amp;aacute;rbol visual y el &amp;aacute;rbol l&amp;oacute;gico que nos permite definir como un control se comporta y como se dibuja en la pantalla, pues bien lo que vamos a ver ahora es como se pueden modificar el &amp;aacute;rbol visual y c&amp;oacute;mo podemos crear un &amp;aacute;rbol visual para una clase que no tiene &amp;aacute;rbol visual.&lt;/p&gt;
&lt;p&gt;Todas los tipos de plantillas heredan de la misma clase, FrameworkTemplate que permite definir plantillas para diferentes tipos de controles.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/luisguerrero/image_5F00_2550548C.png"&gt;&lt;img height="232" width="404" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/luisguerrero/image_5F00_thumb_5F00_3BC2F313.png" alt="image" border="0" title="image" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Si nos fijamos en el diagrama, tenemos tres tipos de plantillas que definir:&lt;/p&gt;
&lt;p&gt;&amp;middot; &lt;b&gt;DataTemplate&lt;/b&gt;: permite definir una plantilla de datos, es decir asociar un &amp;aacute;rbol visual a una clase o tipo. Podemos definir c&amp;oacute;mo se va a visualizar la clase Employee.&lt;/p&gt;
&lt;p&gt;&amp;middot; &lt;b&gt;ControlTemplate&lt;/b&gt;: permite cambiar la plantilla visual de un control de WPF.&lt;/p&gt;
&lt;p&gt;&amp;middot; &lt;b&gt;ItemsPanelTemplate&lt;/b&gt;: permite cambiar la platilla de un control que es una lista de elementos, como por ejemplo un ListBox.&lt;/p&gt;
&lt;p&gt;&amp;middot; &lt;b&gt;HierarchicalDataTemplate&lt;/b&gt;: permite definir una plantilla de datos para una estructura jer&amp;aacute;rquica, como por ejemplo un &amp;aacute;rbol y asociar este a un TreeView.&lt;/p&gt;
&lt;h3&gt;DataTemplate&lt;/h3&gt;
&lt;p&gt;La clase DataTemplate permite definir una plantilla visual para un tipo cualquiera. Normalmente las plantillas se definen en XAML. Si tenemos un tipo como este:&lt;/p&gt;
&lt;div style="line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;width:97.5%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;max-height:200px;font-size:8pt;overflow:auto;cursor:text;border:gray 1px solid;padding:4px;"&gt;
&lt;pre style="line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Employee
{
    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Name { get; set; }
    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; Age { get; set; }
    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Company { get; set; }
}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Si lo establecemos como contenido de alg&amp;uacute;n control WPF lo que har&amp;aacute; ser&amp;aacute; llamar al ToString() de este objeto para dibujarlo, podemos sobrescribir ToString() para darle otro sentido pero no podemos personalizar como el objeto se dibuja en pantalla.&lt;/p&gt;
&lt;p&gt;Lo que podemos hacer es definir su plantilla visual mediante la clase DataTemplate en xaml, normalmente vamos a tener que definir nuestra DataTemplate en un diccionario de recursos o podemos hacerlo directamente en la propiedad ItemTemplate de algunos controles.&lt;/p&gt;
&lt;div style="line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;width:97.5%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;max-height:200px;font-size:8pt;overflow:auto;cursor:text;border:gray 1px solid;padding:4px;"&gt;
&lt;pre style="line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;DataTemplate&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;DataType&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;{x:Type local:Employee}&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
   &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;StackPanel&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
       &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;TextBlock&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Text&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;{Binding Path=Name}&amp;quot;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;
   &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;StackPanel&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;DataTemplate&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Como se puede observar en este ejemplo hemos definido un DataTemplate dentro del diccionario de recursos de Window, pero no hemos establecido la propiedad x:Key necesaria para poder acceder a ese valor en el diccionario, sino que lo &amp;uacute;nico que hemos hecho es definir la propiedad DataType de la clase DataTemplate. Al hacer esto WPF autom&amp;aacute;ticamente utilizar&amp;aacute; esta plantilla para dibujar el tipo Employee cuando se lo encuentre dentro del &amp;aacute;mbito de la ventana. Esto es extremadamente &amp;uacute;til, porque podemos definir esta plantilla en un ResourceDiccionary a nivel de Application y hacer que est&amp;eacute; disponible para toda la aplicaci&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;Para asociar propiedades de la clase para mostrarla se realiza con un binding como se puede ver en el TextBlock, no quiero centrarme en eso ahora sino simplemente mostrar cuales son las capacidades de personalizaci&amp;oacute;n de la DataTemplate.&lt;/p&gt;
&lt;p&gt;Si hubi&amp;eacute;ramos utilizado un ContentControl para dibujar nuestro objeto Employe podr&amp;iacute;amos haber definido la plantilla directamente en la propiedad ContentTemplate, sin necesidad de asociar el DataType o establecer el x:Key.&lt;/p&gt;
&lt;div style="line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;width:97.5%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;max-height:200px;font-size:8pt;overflow:auto;cursor:text;border:gray 1px solid;padding:4px;"&gt;
&lt;pre style="line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;ContentControl&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;ContentControl.ContentTemplate&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
        &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;DataTemplate&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
            &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;StackPanel&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
                &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;TextBlock&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Text&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;{Binding Path=Name}&amp;quot;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;StackPanel&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
        &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;DataTemplate&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;ContentControl.ContentTemplate&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;ContentControl&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;ControlTemplate&lt;/h3&gt;
&lt;p&gt;ControlTemplate nos permite definir o redefinir la plantilla de un control, es decir de cualquier control que herede de Control, que es donde est&amp;aacute; definida la propiedad Template. La manera de proceder es igual, para un Button tenemos:&lt;/p&gt;
&lt;div style="line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;width:97.5%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;max-height:200px;font-size:8pt;overflow:auto;cursor:text;border:gray 1px solid;padding:4px;"&gt;
&lt;pre style="line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;ControlTemplate&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;TargetType&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;{x:Type Button}&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;x:Key&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;ButtonControlTemplate&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Microsoft_Windows_Themes:ButtonChrome&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;x:Name&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;Chrome&amp;quot;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
        &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Border&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;BorderThickness&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;3&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;BorderBrush&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;red&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
            &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;ContentPresenter&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Border&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Microsoft_Windows_Themes:ButtonChrome&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;ControlTemplate&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Lo que hemos hecho en este ejemplo es redefinir la plantilla de Button para tener esto:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/luisguerrero/clip_5F00_image004_5F00_28359372.jpg"&gt;&lt;img height="170" width="169" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/luisguerrero/clip_5F00_image004_5F00_thumb_5F00_5954CE12.jpg" alt="clip_image004" border="0" title="clip_image004" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Como se puede observar lo que tenemos en pantalla no se parece a un bot&amp;oacute;n, no tiene el aspecto que esperamos de un bot&amp;oacute;n, pero si preguntamos su tipo es un Button, as&amp;iacute; que lo que hemos conseguido es modificar su &amp;aacute;rbol visual sin necesidad de heredad de Button y generar un tipo nuevo, simplemente cambiado su plantilla.&lt;/p&gt;
&lt;p&gt;Este cambio de plantilla normalmente viene integrado en un estilo (Style) pero eso lo veremos en otro post.&lt;/p&gt;
&lt;h3&gt;ItemsPanelTemplate&lt;/h3&gt;
&lt;p&gt;Esta clase permite definir la plantilla para un control de tipo ItemsControl, como por ejemplo TreeView, TabControl, etc. En este ejemplo vamos a cambiar la plantilla del ListBox para hacerlo con UniformGrid.&lt;/p&gt;
&lt;div style="line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;width:97.5%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;max-height:200px;font-size:8pt;overflow:auto;cursor:text;border:gray 1px solid;padding:4px;"&gt;
&lt;pre style="line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;ItemsPanelTemplate&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;x:Key&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;ItemsPanel&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;UniformGrid&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;IsItemsHost&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;True&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;UniformGrid&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;ItemsPanelTemplate&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Aqu&amp;iacute; podemos ver el resultado:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/luisguerrero/clip_5F00_image006_5F00_4D52DDDE.jpg"&gt;&lt;img height="170" width="169" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/luisguerrero/clip_5F00_image006_5F00_thumb_5F00_7752DC06.jpg" alt="clip_image006" border="0" title="clip_image006" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/luisguerrero/clip_5F00_image008_5F00_36445CA2.jpg"&gt;&lt;img height="170" width="169" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/luisguerrero/clip_5F00_image008_5F00_thumb_5F00_3C1F003B.jpg" alt="clip_image008" border="0" title="clip_image008" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Las posibilidades son infinitas, pues podemos personalizar cualquier control como nosotros queramos sin necesidad de tener que tocar una sola l&amp;iacute;nea de c&amp;oacute;digo simplemente con un poco de xaml.&lt;/p&gt;
&lt;h3&gt;HierarchicalDataTemplate&lt;/h3&gt;
&lt;p&gt;Esta plantilla basada en un DataTemplate permite generar plantillas jer&amp;aacute;rquicas para nuestros tipos de datos, como est&amp;aacute; pensada para usarse con un tipo de datos, primero vamos a definir un tipo de dato en &amp;aacute;rbol y generar algunos elementos.&lt;/p&gt;
&lt;div style="line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;width:97.5%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;max-height:200px;font-size:8pt;overflow:auto;cursor:text;border:gray 1px solid;padding:4px;"&gt;
&lt;pre style="line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Node
{
    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Name { get; set; }
    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; ObservableCollection&amp;lt;Node&amp;gt; Items { get; set; }

    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; Node()
    {
        Items = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ObservableCollection&amp;lt;Node&amp;gt;();
    }
}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Esta clase Node contiene un nombre una colecci&amp;oacute;n de elementos y una colecci&amp;oacute;n de elementos del mismo tipo en Items. Podemos definir una plantilla jer&amp;aacute;rquica como esta:&lt;/p&gt;
&lt;div style="line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;width:97.5%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;max-height:200px;font-size:8pt;overflow:auto;cursor:text;border:gray 1px solid;padding:4px;"&gt;
&lt;pre style="line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;HierarchicalDataTemplate&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;ItemsSource&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;{Binding Path=Items}&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;x:Key&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;NodeTemplate&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;TextBlock&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Text&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;{Binding Path=Name}&amp;quot;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;
&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;HierarchicalDataTemplate&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Tenemos que definir cu&amp;aacute;l va a ser la propiedad que se va a usar como origen de datos para los Items que se van a generar, la propiedad ItemsSource nos permite definir mediante un Binding que la propiedad Items, de nuestra clase Node, ser&amp;aacute; la encargada de generar los elementos hijos. Por cada uno de las clases Node que nos encontremos vamos a generar un TextBlock en el que vamos a asociar la propiedad Text del control, con un Binding, a la propiedad Name de nuestra clase Node.&lt;/p&gt;
&lt;p&gt;Ahora tenemos que generar algunos elementos de ejemplo:&lt;/p&gt;
&lt;div style="line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;width:97.5%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;max-height:200px;font-size:8pt;overflow:auto;cursor:text;border:gray 1px solid;padding:4px;"&gt;
&lt;pre style="line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; Node GenerateRandomNodes()
{
    Node n = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Node();
    n.Name = &lt;span style="color:#006080;"&gt;&amp;quot;Raiz&amp;quot;&lt;/span&gt;;
    &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; i = 0; i &amp;lt; 20; i++)
    {
        Node tmp = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Node();
        tmp.Name = i.ToString();
        n.Items.Add(tmp);
        &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; x = 0; x &amp;lt; 10; x++)
        {
            Node tmp2 = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Node();
            tmp2.Name = &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#006080;"&gt;&amp;quot;{0} - {1}&amp;quot;&lt;/span&gt;, i, x);
            tmp.Items.Add(tmp2);
        }
    }
    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; n;
}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Una vez ejecutado este es el resultado:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/luisguerrero/clip_5F00_image010_5F00_140C511C.jpg"&gt;&lt;img height="244" width="217" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/luisguerrero/clip_5F00_image010_5F00_thumb_5F00_52919EC2.jpg" alt="clip_image010" border="0" title="clip_image010" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Resumiendo&lt;/h3&gt;
&lt;p&gt;Como se puede observar una de las cosas buenas de tener un &amp;aacute;rbol visual y un l&amp;oacute;gico es que podemos redefinir como nuestro control o clase se visualiza en pantalla simplemente generando una plantilla. Las plantillas son el mecanismo natural por el cual se pueden personalizar los controles en WPF y son la principal herramienta de los dise&amp;ntilde;adores para personalizar.&lt;/p&gt;
&lt;h3&gt;Avanzado&lt;/h3&gt;
&lt;p&gt;Para terminar el art&amp;iacute;culo me gustar&amp;iacute;a hablar sobre un tema que a todos se nos plantea en alg&amp;uacute;n momento, generar plantillas de manera din&amp;aacute;mica, por c&amp;oacute;digo. En WPF, &lt;i&gt;se pueden&lt;/i&gt; generar plantillas din&amp;aacute;micamente, pero el tema es algo complicado y abstracto. Veamos un ejemplo.&lt;/p&gt;
&lt;p&gt;Vamos a intentar definir una plantilla din&amp;aacute;mica para nuestro tipo de dato Employee por c&amp;oacute;digo, si empezamos a generar c&amp;oacute;digo vemos que podemos generar una instancia de la clase DataTemplate pasando por parametro el tipo del objeto al que queremos generar la plantilla, la propiedad VisualTree de tipo FrameworkElementFactory nos permite definir como queremos que sea nuestra plantilla. &lt;/p&gt;
&lt;p&gt;Todo el trabajo est&amp;aacute; en esta clase FrameworkElementFactory, para definir los elementos tenemos que especificar c&amp;oacute;mo se construir&amp;aacute;n, as&amp;iacute; que siguiendo nuestro ejemplo de DataTemplate, en el que tenemos un StackPanel y dentro un TextBlock as&amp;iacute; es como se definir&amp;iacute;a en c&amp;oacute;digo:&lt;/p&gt;
&lt;div style="line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;width:97.5%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;max-height:200px;font-size:8pt;overflow:auto;cursor:text;border:gray 1px solid;padding:4px;"&gt;
&lt;div style="line-height:12pt;background-color:#f4f4f4;width:100%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#606060;"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; DataTemplate GenerateDataTemplate()&lt;/pre&gt;
&lt;pre style="line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#606060;"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#606060;"&gt;   3:&lt;/span&gt;     DataTemplate dt = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; DataTemplate(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(Employee));&lt;/pre&gt;
&lt;pre style="line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#606060;"&gt;   4:&lt;/span&gt;     FrameworkElementFactory stackPanel = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; FrameworkElementFactory();&lt;/pre&gt;
&lt;pre style="line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#606060;"&gt;   5:&lt;/span&gt;     stackPanel.Type = &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(StackPanel);&lt;/pre&gt;
&lt;pre style="line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#606060;"&gt;   6:&lt;/span&gt;     stackPanel.SetValue(StackPanel.BackgroundProperty, &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; SolidColorBrush(Colors.Yellow));&lt;/pre&gt;
&lt;pre style="line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#606060;"&gt;   7:&lt;/span&gt;     FrameworkElementFactory text = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; FrameworkElementFactory(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(TextBlock));&lt;/pre&gt;
&lt;pre style="line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#606060;"&gt;   8:&lt;/span&gt;     text.SetBinding(TextBlock.TextProperty, &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Binding(&lt;span style="color:#006080;"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;));&lt;/pre&gt;
&lt;pre style="line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#606060;"&gt;   9:&lt;/span&gt;     stackPanel.AppendChild(text);&lt;/pre&gt;
&lt;pre style="line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#606060;"&gt;  10:&lt;/span&gt;     text = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; FrameworkElementFactory(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(TextBlock));&lt;/pre&gt;
&lt;pre style="line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#606060;"&gt;  11:&lt;/span&gt;     text.SetBinding(TextBlock.TextProperty, &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Binding(&lt;span style="color:#006080;"&gt;&amp;quot;Company&amp;quot;&lt;/span&gt;));&lt;/pre&gt;
&lt;pre style="line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#606060;"&gt;  12:&lt;/span&gt;     stackPanel.AppendChild(text);&lt;/pre&gt;
&lt;pre style="line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#606060;"&gt;  13:&lt;/span&gt;     text = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; FrameworkElementFactory(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(TextBlock));&lt;/pre&gt;
&lt;pre style="line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#606060;"&gt;  14:&lt;/span&gt;     text.SetBinding(TextBlock.TextProperty, &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Binding(&lt;span style="color:#006080;"&gt;&amp;quot;Age&amp;quot;&lt;/span&gt;));&lt;/pre&gt;
&lt;pre style="line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#606060;"&gt;  15:&lt;/span&gt;     stackPanel.AppendChild(text);&lt;/pre&gt;
&lt;pre style="line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#606060;"&gt;  16:&lt;/span&gt;     dt.VisualTree = stackPanel;&lt;/pre&gt;
&lt;pre style="line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#606060;"&gt;  17:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; dt;&lt;/pre&gt;
&lt;pre style="line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#606060;"&gt;  18:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;La idea es establecer en cada uno de los FrameworkElementFactory las DependencyProperties, Bindings y Childrens que definen a un control.&lt;/p&gt;
&lt;p&gt;El c&amp;oacute;digo fuente lo pod&amp;eacute;is descargar de aqu&amp;iacute; &lt;a href="http://www.luisguerrero.net/downloads/templates.zip"&gt;http://www.luisguerrero.net/downloads/templates.zip&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Saludos. Luis.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=151468" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/luisguerrero/archive/tags/silverlight/default.aspx">silverlight</category><category domain="http://geeks.ms/blogs/luisguerrero/archive/tags/WPF+-_2600_gt_3B00_+Windows+Forms/default.aspx">WPF -&amp;gt; Windows Forms</category></item><item><title>[Curso] WPF para programadores de Windows Forms 8</title><link>http://geeks.ms/blogs/luisguerrero/archive/2009/06/28/curso-wpf-para-programadores-de-windows-forms-8.aspx</link><pubDate>Sun, 28 Jun 2009 18:01:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:151423</guid><dc:creator>Luis Guerrero</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/luisguerrero/rsscomments.aspx?PostID=151423</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/luisguerrero/commentapi.aspx?PostID=151423</wfw:comment><comments>http://geeks.ms/blogs/luisguerrero/archive/2009/06/28/curso-wpf-para-programadores-de-windows-forms-8.aspx#comments</comments><description>&lt;p&gt;Ha pasado mucho tiempo desde mi &amp;uacute;ltimo post de esta serie, el trabajo y haberme mudado de casa no me han permitido escribir este tipo de posts. Ahora un poco m&amp;aacute;s relajado podemos continuar con esta serie de post sobre como programar WPF para los programadores de Windows Forms.&lt;/p&gt;
&lt;p&gt;En este post vamos a hablar sobre los dos tipos de arboles de controles que hay que WPF: el &amp;aacute;rbol visual (Visual Tree) y el &amp;aacute;rbol l&amp;oacute;gico (Logical Tree). Estos dos conceptos son muy importantes para un programador de WPF porque permite conocer muy bien c&amp;oacute;mo trabaja WPF con los controles y c&amp;oacute;mo podemos personalizar los nuestros. En WF solamente tenemos el &amp;aacute;rbol l&amp;oacute;gico, siendo este la relaci&amp;oacute;n entre los controles que son contenedores con sus hijos. &lt;/p&gt;
&lt;p&gt;En WF podemos tener un Panel y dentro de este podemos tener un bot&amp;oacute;n o podemos tener un TabPage y dentro de este podemos tener otro panel y dentro un label. Las relaciones entre los padres e hijos forman un &amp;aacute;rbol de controles.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/luisguerrero/image_5F00_7F049301.png"&gt;&lt;img height="206" width="404" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/luisguerrero/image_5F00_thumb_5F00_69C6678C.png" alt="image" border="0" title="image" style="border-right-width:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;margin-left:auto;border-left-width:0px;margin-right:auto;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;En este grafico podemos ver cu&amp;aacute;l es el &amp;aacute;rbol de controles de un formulario cualquiera de Windows Forms. Con este &amp;aacute;rbol lo &amp;uacute;nico que estamos especificando es que control est&amp;aacute; dentro de cual y por tanto cual ser&amp;aacute; su espacio de dibujado.&lt;/p&gt;
&lt;p&gt;En WF para especificar el rect&amp;aacute;ngulo de dibujado de un control tenemos la propiedad Location (Size) y tenemos Size (Size), dentro de ese rect&amp;aacute;ngulo podemos dibujar con GDI lo que queramos que despu&amp;eacute;s ser&amp;aacute; compuesto formando la imagen final del formulario. La manera en la que se definen visualmente los objetos en Windows Forms es a trav&amp;eacute;s del c&amp;oacute;digo que se ejecuta en OnRender pero no tenemos ninguna otra manera de definir el aspecto de un control, es decir si queremos cambiar el aspecto del control tenemos que sobreescribir el m&amp;eacute;todo OnRender teniendo as&amp;iacute; que cambiar c&amp;oacute;digo del control y generando un tipo nuevo, puesto que la &amp;uacute;nica manera de sobrescribir un m&amp;eacute;todo virtual es heredando. Esto tiene una serie de problemas puesto que tenemos que modificar el c&amp;oacute;digo de nuestro control y desde la perspectiva de un dise&amp;ntilde;ador gr&amp;aacute;fico es inviable sentarlo con el Visual Studio a dibujar con GDI.&lt;/p&gt;
&lt;p&gt;En WPF la cosa cambia mucho. Ahora, como ya he comentado antes, tenemos dos arboles el visual y el l&amp;oacute;gico. El &amp;aacute;rbol visual, como su nombre indica, se encarga de definir cu&amp;aacute;les son las clases que se encargan de definir como un control se visualiza en pantalla y el &amp;aacute;rbol l&amp;oacute;gico es como el control se comporta.&lt;/p&gt;
&lt;p&gt;Para explicar este concepto vamos a escoger el bot&amp;oacute;n de WPF para ver cu&amp;aacute;les son su &amp;aacute;rbol visual y l&amp;oacute;gico.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/luisguerrero/clip_5F00_image004_5F00_2E2658CC.jpg"&gt;&lt;img height="134" width="161" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/luisguerrero/clip_5F00_image004_5F00_thumb_5F00_2D4DF2E2.jpg" alt="clip_image004" border="0" title="clip_image004" style="border-right-width:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;margin-left:auto;border-left-width:0px;margin-right:auto;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h5&gt;&amp;Aacute;rbol L&amp;oacute;gico:&lt;/h5&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/luisguerrero/image_5F00_735EAFF5.png"&gt;&lt;img height="156" width="404" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/luisguerrero/image_5F00_thumb_5F00_540BE355.png" alt="image" border="0" title="image" style="border-right-width:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;margin-left:auto;border-left-width:0px;margin-right:auto;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h5&gt;&amp;Aacute;rbol Visual:&lt;/h5&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/luisguerrero/image_5F00_1E16C86E.png"&gt;&lt;img height="334" width="404" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/luisguerrero/image_5F00_thumb_5F00_21D46D3E.png" alt="image" border="0" title="image" style="border-right-width:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;margin-left:auto;border-left-width:0px;margin-right:auto;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Como podeos observar la cosa cambia mucho porque, del &amp;aacute;rbol l&amp;oacute;gico, que es al que estamos todos acostumbrados, cambia mucho con respecto al &amp;aacute;rbol visual. Pero vayamos por partes.&lt;/p&gt;
&lt;p&gt;Button es un caso especial porque este control hereda de ContentControl lo que significa que podemos establecer como contenido lo que queramos (object) en este caso un string. Esto est&amp;aacute; relacionado con el &amp;aacute;rbol l&amp;oacute;gico porque como vemos, el &amp;uacute;nico hijo del bot&amp;oacute;n es el contenido (Content) lo que desde luego tiene sentido porque en WPF podemos establecer como hijo de un bot&amp;oacute;n lo que queramos como por ejemplo un checkbox.&lt;/p&gt;
&lt;p&gt;Vayamos ahora a por el &amp;aacute;rbol visual: si nos fijamos el &amp;aacute;rbol visual tiene 3 elementos, un ButtonChrome, un ContentPresenter y un TextBlock. Vamos a identificar esos elementos en la imagen del bot&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/luisguerrero/clip_5F00_image010_5F00_0B321EF7.jpg"&gt;&lt;img height="296" width="404" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/luisguerrero/clip_5F00_image010_5F00_thumb_5F00_3D494974.jpg" alt="clip_image010" border="0" title="clip_image010" style="border-right-width:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;margin-left:auto;border-left-width:0px;margin-right:auto;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;middot; ButtonChrome: corresponde el borde m&amp;aacute;s el degradado del bot&amp;oacute;n&lt;/p&gt;
&lt;p&gt;&amp;middot; ContentPresenter: es el hueco donde se dibujar&amp;aacute; el contenido del control&lt;/p&gt;
&lt;p&gt;&amp;middot; TextBlock: es el control en WPF para dibujar texto&lt;/p&gt;
&lt;p&gt;Podemos modificar el contenido del bot&amp;oacute;n haciendo que en vez de que contenga un string que contenga un checkbox y este tenga un texto asignado.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/luisguerrero/clip_5F00_image012_5F00_0B21F92A.jpg"&gt;&lt;img height="127" width="163" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/luisguerrero/clip_5F00_image012_5F00_thumb_5F00_5132B63D.jpg" alt="clip_image012" border="0" title="clip_image012" style="border-right-width:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;margin-left:auto;border-left-width:0px;margin-right:auto;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h5&gt;&amp;Aacute;rbol L&amp;oacute;gico:&lt;/h5&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/luisguerrero/image_5F00_69562098.png"&gt;&lt;img height="237" width="404" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/luisguerrero/image_5F00_thumb_5F00_0E073810.png" alt="image" border="0" title="image" style="border-right-width:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;margin-left:auto;border-left-width:0px;margin-right:auto;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h5&gt;&amp;Aacute;rbol Visual:&lt;/h5&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/luisguerrero/image_5F00_05A362B9.png"&gt;&lt;img height="411" width="404" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/luisguerrero/image_5F00_thumb_5F00_4277E48B.png" alt="image" border="0" title="image" style="border-right-width:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;margin-left:auto;border-left-width:0px;margin-right:auto;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Ahora como hijo del &lt;a href="http://msdn2.microsoft.com/ms609804.aspx" title="ContentPresenter Class"&gt;ContentPresenter&lt;/a&gt; tenemos al &lt;a href="http://msdn2.microsoft.com/ms609112.aspx" title="CheckBox Class"&gt;CheckBox&lt;/a&gt; que a su vez tiene su &amp;aacute;rbol visual.&lt;/p&gt;
&lt;p&gt;Como se puede observar para un ejemplo peque&amp;ntilde;o, el &amp;aacute;rbol visual contiene 7 elementos as&amp;iacute; que conforme se a&amp;ntilde;aden nuevos elementos el &amp;aacute;rbol visual crece muy r&amp;aacute;pidamente.&lt;/p&gt;
&lt;p&gt;Lo bueno que tiene los arboles visuales es que definen la manera en que el control se dibuja a s&amp;iacute; mismo separando el aspecto del comportamiento. Ahora podemos modificar el aspecto del bot&amp;oacute;n de WPF sin cambiar su comportamiento, como hac&amp;iacute;amos en WF. Esto permite que se pueda definir el &amp;aacute;rbol visual de un control con XAML permitiendo esto que dise&amp;ntilde;adores puedan generar estilos o temas de los controles desde herramientas como Expression Blend.&lt;/p&gt;
&lt;p&gt;La siguiente pregunta es c&amp;oacute;mo se modifican o generan estos tipos de plantillas visuales, pero eso lo veremos en el siguiente post que hablar&amp;eacute; sobre las diferentes tipos de plantillas para WPF.&lt;/p&gt;
&lt;p&gt;Ah, por cierto, si programais para Silverlight decir que todo lo dicho aqu&amp;iacute; es aplicable igualmente a esta tecnolog&amp;iacute;a.&lt;/p&gt;
&lt;p&gt;Saludos. Luis.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=151423" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/luisguerrero/archive/tags/WPF+-_2600_gt_3B00_+Windows+Forms/default.aspx">WPF -&amp;gt; Windows Forms</category></item><item><title>Virtual Tech Days 09</title><link>http://geeks.ms/blogs/luisguerrero/archive/2009/04/11/virtual-tech-days-09.aspx</link><pubDate>Sat, 11 Apr 2009 13:05:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:146593</guid><dc:creator>Luis Guerrero</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/luisguerrero/rsscomments.aspx?PostID=146593</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/luisguerrero/commentapi.aspx?PostID=146593</wfw:comment><comments>http://geeks.ms/blogs/luisguerrero/archive/2009/04/11/virtual-tech-days-09.aspx#comments</comments><description>&lt;p&gt;El 1 de abril se celebro un evento mundial online en Microsoft llamado Virtual Tech Days 09, que duro 24 horas ininterrumpidamente desde diferentes localizaciones del planeta, una agenda cargada de contenidos para que pod&amp;aacute;is aprender sobre lo nuevo que viene en Microsoft. &lt;/p&gt;
&lt;p&gt;Yo particip&amp;eacute; en este evento como conferenciante hablando de WPF, en concreto de los problemas que se puede encontrar los programadores de Windows Forms cuando quieren migrar a WPF. Hay que recordar que yo mantengo una lista de post llamados &amp;ldquo;&lt;a target="_blank" href="http://www.luisguerrero.net/category/WPF-3e-Windows-Forms.aspx"&gt;WPF para programadores de WF&lt;/a&gt;&amp;rdquo; y justamente de eso hable, una casualidad que Microsoft me propusiera esa charla.&lt;/p&gt;
&lt;p&gt;Aqu&amp;iacute; ten&amp;eacute;is la grabaci&amp;oacute;n de la charla desde Msn Video, &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:a71591ab-5f4c-4f5a-bbcc-348b11efe2ca" style="margin:0px;width:1672px;display:inline;float:none;padding:0px;"&gt;
&lt;div&gt;&lt;a target="_new" href="http://video.msn.com/video.aspx?vid=a6f30a0e-9601-4162-9990-f4ce75245615&amp;amp;from=writer"&gt;&lt;img src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/luisguerrero/video8e3cec308ad1_5F00_063902A5.jpg" style="border-style:none;" alt="" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style="clear:both;font-size:.8em;"&gt;WPF para programadores de Windows Form&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;tambi&amp;eacute;n os dejo la presentaci&amp;oacute;n usada &lt;/p&gt;
&lt;p&gt;&lt;a target="_blank" href="http://www.luisguerrero.net/downloads/WPF%20for%20Windows%20forms%20programmer.pptx" title="WPF para programadores de Windows Forms [924kb]"&gt;&lt;img height="98" width="94" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/luisguerrero/image_5F00_08B20E96.png" alt="image" border="0" title="image" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;y el enlace a la web oficial.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.msfttechdays.com/public/home.aspx" title="http://www.msfttechdays.com/public/home.aspx"&gt;http://www.msfttechdays.com/public/home.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Espero que os guste. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=146593" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/luisguerrero/archive/tags/WPF+-_2600_gt_3B00_+Windows+Forms/default.aspx">WPF -&amp;gt; Windows Forms</category></item></channel></rss>