tag:blogger.com,1999:blog-225297812008-10-11T11:12:13.900-06:00Diario de un DotneteroUn blog para tratar temas de desarrollo de software con .NET y tecnología en general. Lo pocho de este espacio es un feature, no un bug.Carlos Rubalcavahttp://www.blogger.com/profile/10848793413989996197noreply@blogger.comBlogger118125tag:blogger.com,1999:blog-22529781.post-31072337733272352982008-10-01T12:06:00.001-06:002008-10-01T12:08:58.683-06:00Microsoft anuncia Visual Studio 2010 y .NET Framework 4.0<p>Ayer Microsoft se adelantó al PDC y <a href="http://www.microsoft.com/presspass/press/2008/sep08/09-29VS10PR.mspx?rss_fdn=Press%20Releases">anunció</a> que Visual Studio 2010 (también conocido por Visual Studio 10 o “Rosario”) y el .NET Framework 4.0 estarían disponibles a finales del 2009 o principios del 2010—seguramente para coincidir con el lanzamiento de Windows 7, tal como lo hicieron con .NET 3.0 y Windows Vista.</p> <p>Lo curioso, sin embargo es que no dió muchos detalles al respecto.&#160; <a href="http://msdn.microsoft.com/en-us/vstudio/products/cc948977.aspx">Según esta página en MSDN</a>, los “pilares” de esa versión son [interpretación mía]:</p> <ul> <li><strong>Democratizar el ciclo de desarrollo.&#160; </strong>Que en términos prácticos parece que se trata de incorporar aún más modelación en Visual Studio, incluyendo—finalmente—diagramación en UML.&#160; <a href="http://channel9.msdn.com/posts/VisualStudio/Top-down-design-with-Visual-Studio-Team-System-2010/">Checa este video en Channel 9 al respecto</a>. Parece que también van a mejorar algunas de las herramientas de pruebas y documentación, sobre todo para poder reproducir <em>pulgas</em> elusivas.</li> <li><strong>Facilitar las tecnologías emergentes.</strong>&#160; No sé exactamente a qué se refieran, ¿quizá soporte nativo a Silverlight 2 y cosas así? ¿Facilitar cosas de cloud computing? ¿Desarrollo para mulitprocesadores/<em>multicore</em>?</li> <li><strong>Inspirar deleite en los desarrolladores.</strong>&#160; Esto me suena a puro <em>marketingspeak</em> <img title=":)" alt=":)" src="http://spaces.live.com/rte/emoticons/smile_teeth.gif" /></li> <li><strong>Seguir la ola de plataformas de próxima generación.</strong>&#160; Esto pudiera referirse a tecnologías asociadas con Windows 7 o Server 2008 R2, o a cosas relacionadas con <a href="https://www.mesh.com/Welcome/Welcome.aspx">Live Mesh</a>—parte de la iniciativa de <em>cloud computing </em>de Microsoft—que estoy seguro también tendrán algo de integración.</li> <li><strong>Aplicaciones departamentales avanzadas.</strong>&#160; Supongo que se enfocarán a facilitar el desarrollo no solo de “aplicacionzotas” sino también “aplicacioncitas”—que luego crecen como monstruos y luego las quieren usar en todos lados.&#160; ¿Significa que integrarán algunos pricipios de Access? <img title="[eek]" alt="[eek]" src="http://spaces.live.com/rte/emoticons/smile_confused.gif" /></li> </ul> <p>Hay una serie de <a href="http://channel9.msdn.com/tags/Visual+Studio+2010/">videos ya en Channel 9 acerca de VS 2010</a>.&#160; El blog de Arturo también <a href="http://team.intellekt.ws/blogs/arturo/archive/2008/09/30/microsoft-anuncia-visual-studio-2010-y-net-framework-4-0.aspx">tiene algo más de información en español al respecto</a>.</p> Enjoy <img title="cool" alt="cool" src="http://spaces.live.com/rte/emoticons/smile_shades.gif" /> Carlos Rubalcavahttp://www.blogger.com/profile/10848793413989996197noreply@blogger.comtag:blogger.com,1999:blog-22529781.post-23549418058759337392008-10-01T11:27:00.001-06:002008-10-01T11:27:57.498-06:00Videos en español de Visual Studio 2008 y más por Channel 9<p>Para los que no lo conocen, <a href="http://channel9.msdn.com/">Channel 9</a> es un sitio de Microsoft para desarrolladores donde puedes encontrar un montonal de videos—y más importante creo—opinar sobre muchas de las tecnologías que maneja la compañía.&#160; </p> <p>La mayoría de los videos están en inglés, pero hoy descubrí que si juegas con los <em>tags</em> puedes obtener un listado de los videos que está en español.&#160; Este enlace te da dicho listado:</p> <p><a title="http://channel9.msdn.com/tags/Spanish/" href="http://channel9.msdn.com/tags/Spanish/">http://channel9.msdn.com/tags/Spanish/</a></p> <p>Ahí encontrarás videos sobre Visual Studio 2008, Expression Web, incluso uno que otro sobre Silverlight y Expression Blend.</p> <p>Por ejemplo, parece que acaban de sacar <a href="http://channel9.msdn.com/tags/Expression+web/">una serie de cinco partes sobre Expression Web</a>—uno de los productos de la familia Expression diseñados para hacer desde sitios HTML hasta sitios con páginas ASP.NET.</p> <p>Enjoy <img alt="smile_shades" src="http://spaces.live.com/rte/emoticons/smile_shades.gif" /></p> Carlos Rubalcavahttp://www.blogger.com/profile/10848793413989996197noreply@blogger.comtag:blogger.com,1999:blog-22529781.post-89478122540219531542008-09-04T00:01:00.000-06:002008-09-05T15:42:37.018-06:00Cómo transformar XML sin usar XSLT<p>El otro día, una compañía externa hizo un una auditoría de seguridad a un sistema grande que manejamos.&#160; Parte de la auditoría consistió en correr la herramienta <a href="http://msdn.microsoft.com/en-us/library/bb429476(VS.80).aspx">FxCop</a> contra las DLLs para buscar—entre otras cosas—posibles <a href="http://es.wikipedia.org/wiki/Inyecci%C3%B3n_SQL">vulnerabilidades de inyección de SQL</a>.&#160; FxCop produce dichos reportes en XML y eso fue lo que nos entregaron.&#160; </p> <p>Estos reportes eran enormes y en un formato no muy amigable, así que necesitábamos de alguna forma extraer los datos de ahí para enfocar los esfuerzos de los desarrolladores (qué corregir y en dónde), y también para tabular los datos (número de <em>issues </em>por namespace, DLL, etc.) de manera que se les pudieran presentar a los gerentoides.&#160; </p> <p>Este es un ejemplo de uno de esos archivos—no te preocupes, todas estas vulnerabilidades ya fueron parchadas, este es un extracto de esos reportes <img alt="smile_wink" src="http://spaces.live.com/rte/emoticons/smile_wink.gif" />. </p> <p>(Da clic a la imagen para ver un tamaño más grande)</p> <p align="center"><a href="http://lh5.ggpht.com/carlos.rubalcava/SL9cIymutNI/AAAAAAAAAXM/tN60IiXwjy8/s1600-h/sampleFxCopReport16.png"><img title="ejemplo de reporte FxCop" height="480" alt="ejemplo de reporte FxCop" src="http://lh4.ggpht.com/carlos.rubalcava/SL9cJ-lJBDI/AAAAAAAAAXQ/Na1AU556YaE/sampleFxCopReport_thumb14.png?imgmax=800" width="511" /></a> </p> <p>Ahora, se me ocurrió que estos archivos se podían transformar a algo más “plano”—como otro archivo de XML o un CSV—de manera que pudiera ser importado a Excel fácilmente.&#160; Algo así como lo siguiente:</p> <div style="border-right: #cccccc 1pt dashed; padding-right: 5pt; border-top: #cccccc 1pt dashed; padding-left: 5pt; font-size: 10pt; background: #f5f5f5; padding-bottom: 5pt; overflow: auto; border-left: #cccccc 1pt dashed; width: 95%; color: black; max-height: 400px; padding-top: 5pt; border-bottom: #cccccc 1pt dashed; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"><span style="color: blue">&lt;?</span><span style="color: #a31515">xml</span><span style="color: blue"> </span><span style="color: red">version</span><span style="color: blue">=</span>&quot;<span style="color: blue">1.0</span>&quot;<span style="color: blue"> </span><span style="color: red">encoding</span><span style="color: blue">=</span>&quot;<span style="color: blue">utf-8</span>&quot;<span style="color: blue"> </span><span style="color: red">standalone</span><span style="color: blue">=</span>&quot;<span style="color: blue">yes</span>&quot;<span style="color: blue">?&gt;</span></pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"><span style="color: blue">&lt;</span><span style="color: #a31515">Vulnerabilities</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"><span style="color: blue">&#160; &lt;</span><span style="color: #a31515">Vulnerability</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">Module</span><span style="color: blue">&gt;&lt;/</span><span style="color: #a31515">Module</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">Namespace</span><span style="color: blue">&gt;&lt;/</span><span style="color: #a31515">Namespace</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">Type</span><span style="color: blue">&gt;&lt;/</span><span style="color: #a31515">Type</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">Method</span><span style="color: blue">&gt;&lt;/</span><span style="color: #a31515">Method</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">Issue</span><span style="color: blue">&gt;&lt;/</span><span style="color: #a31515">Issue</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"><span style="color: blue">&#160; &lt;/</span><span style="color: #a31515">Vulnerability</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"><span style="color: blue">&#160; &lt;</span><span style="color: #a31515">Vulnerability</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">Module</span><span style="color: blue">&gt;&lt;/</span><span style="color: #a31515">Module</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">Namespace</span><span style="color: blue">&gt;&lt;/</span><span style="color: #a31515">Namespace</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">Type</span><span style="color: blue">&gt;&lt;/</span><span style="color: #a31515">Type</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">Method</span><span style="color: blue">&gt;&lt;/</span><span style="color: #a31515">Method</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"><span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">Issue</span><span style="color: blue">&gt;&lt;/</span><span style="color: #a31515">Issue</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"><span style="color: blue">&#160; &lt;/</span><span style="color: #a31515">Vulnerability</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"><span style="color: blue">&lt;/</span><span style="color: #a31515">Vulnerabilities</span><span style="color: blue">&gt;</span></pre> </div> <p>La sola idea de hacer una hoja de estilos XSL para transformar eso me daba escalofríos, así que fue una buena oportunidad para practicar mi LINQ-Fu.&#160; Para ello me ayudé de <a href="http://www.linqpad.net/">LINQPad</a>—una excelente herramienta para probar snippets de LINQ.</p> <h3>Armando el query</h3> <p>Mi primer query fue este:</p> <div style="border-right: #cccccc 1pt dashed; padding-right: 5pt; border-top: #cccccc 1pt dashed; padding-left: 5pt; font-size: 10pt; background: #f5f5f5; padding-bottom: 5pt; overflow: auto; border-left: #cccccc 1pt dashed; width: 95%; color: black; max-height: 400px; padding-top: 5pt; border-bottom: #cccccc 1pt dashed; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"><span style="color: #2b91af">XElement</span> xml = <span style="color: #2b91af">XElement</span>.Load(<span style="color: #a31515">@&quot;C:\Users\Carlos\Desktop\sampleFxCopReport.xml&quot;</span>);</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"><span style="color: blue">var</span> query =</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160; <span style="color: blue">from</span> e <span style="color: blue">in</span> xml.Descendants(<span style="color: #a31515">&quot;Issue&quot;</span>)</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160; <span style="color: blue">where</span> e.Ancestors(<span style="color: #a31515">&quot;Message&quot;</span>).Attributes(<span style="color: #a31515">&quot;TypeName&quot;</span>).First().Value == <span style="color: #a31515">&quot;ReviewSqlQueriesForSecurityVulnerabilities&quot;</span></pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160; <span style="color: blue">select</span> <span style="color: blue">new</span></pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160; {</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160; Module = e.Ancestors(<span style="color: #a31515">&quot;Module&quot;</span>).Attributes(<span style="color: #a31515">&quot;Name&quot;</span>).First().Value,</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160; Namespace = e.Ancestors(<span style="color: #a31515">&quot;Namespace&quot;</span>).Attributes(<span style="color: #a31515">&quot;Name&quot;</span>).First().Value,</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160; Type = e.Ancestors(<span style="color: #a31515">&quot;Type&quot;</span>).Attributes(<span style="color: #a31515">&quot;Name&quot;</span>).First().Value,</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160; Method = e.Ancestors(<span style="color: #a31515">&quot;Member&quot;</span>).Attributes(<span style="color: #a31515">&quot;Name&quot;</span>).First().Value,</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160; Issue = e.Value</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160; };</pre> </div> <p>Como puedes ver, cargar el archivo es trivial.&#160; Puedes hacerlo a través del método <strong>Load()</strong> de la clase <strong>XElement</strong> o <strong>XDocument</strong>.</p> <p>Luego, declaré una variable de tipo <strong>var </strong>porque no estaba seguro exactamente del tipo de los objetos que regresaría mi query—utilicé un tipo anónimo, el cual explicaré en un minuto.</p> <p>Si no estás muy familiarizado con queries de LINQ, solo recuerda que en su nivel <em>más básico</em>, tienes un <strong>from</strong>/<strong>where</strong>/<strong>select</strong>.&#160; </p> <ul> <li>Primero le dices a qué objetos quieres hacerle query (<strong>from</strong>), </li> <li>luego especificas un filtro que deje solo los que te interesen (<strong>where</strong>) y </li> <li>finalmente le indicas una expresión de cómo quieres <strong><em>proyectar</em></strong> tus datos en la salida (<strong>select</strong>). </li> </ul> <p>En este caso, se me hizo más fácil elegir primero todos los elementos <em>&lt;Issue&gt;</em> dentro del documento XML, ya que a partir de ellos puedo obtener el resto de la información viendo los nodos ancestros.&#160; Logré hacer esto con una sola línea en el <strong>from</strong> gracias al método <strong>Descendants()</strong> de la clase <strong>XElement</strong>.&#160; En otras palabras estoy diciendo “selecciona los elementos <em>&lt;Issue&gt;</em> en el documento, y por cada uno de ellos dame una variable <em>e</em> de donde extraer más información”.&#160; Puedes pensarlo como algo <em>parecido </em>a un <strong>foreach</strong>.</p> <p>Luego, indiqué en el filtro <strong>where </strong>que únicamente deseo los <em>&lt;Issue&gt; </em>donde el mensaje (<em>&lt;Message&gt;</em>) sea de tipo vulnerabilidad de SQL (<em>TypeName=”ReviewSqlQueriesForSecurityVulnerabilities”).</em>&#160; Como los elementos <em>&lt;Message&gt; </em>son ancestros de <em>&lt;Issue&gt;</em>, utilicé <strong>Ancestors()</strong> para acceder a ese elemento y luego <strong>Attributes()</strong> para obtener el valor de atributo <em>TypeName</em> y poder hacer la comparación.</p> <p>Finalmente, en la proyección el <strong>select new </strong>crea un tipo (una clase pues) sin nombre con 5 propiedades, que son inicializadas con los valores de las expresiones.&#160; Esto crea una collección de tipo <strong>IEnumerable&lt;T&gt;</strong> donde<strong> T</strong> es el tipo anónimo—¿ves por qué fue necesaria la variable <strong>var</strong>?</p> <p>El resultado del query es este (da clic para ver la imagen más grande):</p> <p align="center"><a href="http://lh4.ggpht.com/carlos.rubalcava/SL9cKyPJkaI/AAAAAAAAAXU/hk4PfmxdszA/s1600-h/query1results2.png"><img title="resultados del primer query" height="109" alt="resultados del primer query" src="http://lh3.ggpht.com/carlos.rubalcava/SL9cLleBZZI/AAAAAAAAAXY/RbAUWOtPNR0/query1results_thumb2.png?imgmax=800" width="600" /></a></p> <p>Pero, ¿qué tal si quisiera ordenar mis resultados primero por <em>Module</em>, luego por <em>Namespace</em>, <em>Type</em> y <em>Method </em>sucesivamente?&#160; Sencillo.&#160; Puedo agregar una cadena de <strong>OrderBy</strong>’s a mi query original o puedo agarrar el resultado del query y ordenarlo así:</p> <div style="border-right: #cccccc 1pt dashed; padding-right: 5pt; border-top: #cccccc 1pt dashed; padding-left: 5pt; font-size: 10pt; background: #f5f5f5; padding-bottom: 5pt; overflow: auto; border-left: #cccccc 1pt dashed; width: 95%; color: black; max-height: 400px; padding-top: 5pt; border-bottom: #cccccc 1pt dashed; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"><span style="color: blue">var</span> ordered =</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160; query.OrderBy(x =&gt; x.Method).OrderBy(x =&gt; x.Type)</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160; .OrderBy(x =&gt; x.Namespace).OrderBy(x =&gt; x.Module);</pre> </div> <p>Esta manera de hacerlo involucra las famosas expresiones lamda, pero no me quiero desviar en explicarlas.&#160; Por ahora sólo tómalas como ejemplo y nota que puedes encadenar las cláusulas.</p> <p>Esto es un buen comienzo, pero ahora quiero esos datos en algo que se le parezca a un documento XML.</p> <p>Entonces agregué esto después de mi query:</p> <div style="border-right: #cccccc 1pt dashed; padding-right: 5pt; border-top: #cccccc 1pt dashed; padding-left: 5pt; font-size: 10pt; background: #f5f5f5; padding-bottom: 5pt; overflow: auto; border-left: #cccccc 1pt dashed; width: 95%; color: black; max-height: 400px; padding-top: 5pt; border-bottom: #cccccc 1pt dashed; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"><span style="color: #2b91af">XDocument</span> xdoc = <span style="color: blue">new</span> <span style="color: #2b91af">XDocument</span>();</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">xdoc.AddFirst(<span style="color: blue">new</span> <span style="color: #2b91af">XElement</span>(<span style="color: #a31515">&quot;Vulnerabilities&quot;</span>));</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"><span style="color: blue">foreach</span> (<span style="color: blue">var</span> element <span style="color: blue">in</span> query)</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">{</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160; xdoc.Root.Add(</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> <span style="color: #2b91af">XElement</span>(<span style="color: #a31515">&quot;Vulnerability&quot;</span>, <span style="color: blue">new</span> <span style="color: #2b91af">XElement</span>(<span style="color: #a31515">&quot;Module&quot;</span>, element.Module)</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , <span style="color: blue">new</span> <span style="color: #2b91af">XElement</span>(<span style="color: #a31515">&quot;Namespace&quot;</span>, element.Namespace)</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , <span style="color: blue">new</span> <span style="color: #2b91af">XElement</span>(<span style="color: #a31515">&quot;Type&quot;</span>, element.Type)</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , <span style="color: blue">new</span> <span style="color: #2b91af">XElement</span>(<span style="color: #a31515">&quot;Method&quot;</span>, element.Method)</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; , <span style="color: blue">new</span> <span style="color: #2b91af">XElement</span>(<span style="color: #a31515">&quot;Issue&quot;</span>, element.Issue)</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ));</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">}</pre> </div> <p>Primero creo un nuevo documento XML utilizando la clase <strong>XDocument, </strong>y le agrego un elemento raíz <em>&lt;Vulnerabilities&gt;</em>.&#160; Luego por cada elemento de mi lista ordenada, agrego un elemento <em>&lt;Vulnerability&gt;</em> que contendrá cinco elementos, uno por cada propiedad que me interesó, y que tendrán el valo.&#160; Nota que los constructores “raros” de <strong>XElement</strong> facilitan enormemente la tarea, y que los métodos <strong>AddFirst()</strong> y <strong>AddNew()</strong> se encargará de cerrar los elementos adecuadamente—a diferencia de la forma en que se utiliza un <strong>XmlWriter</strong>, por ejemplo.</p> <p>El resultado:</p> <p align="center"><a href="http://lh3.ggpht.com/carlos.rubalcava/SL9cMrOlZmI/AAAAAAAAAXc/8C5Jt6WAoQo/s1600-h/query1XMLresults3.png"><img title="resultados del query" height="480" alt="resultados del query" src="http://lh6.ggpht.com/carlos.rubalcava/SL9cNlgAPFI/AAAAAAAAAXg/SCPcBg6_FSM/query1XMLresults_thumb1.png?imgmax=800" width="400" /></a> </p> <p>Esto ya es prácticamente lo que quiero.&#160; Sin embargo, mi código hasta ahorita son como 30 líneas—principalmente por el formato, en realidad solo he utilizado como 7 instrucciones—y me gustaría condensar el código más.&#160; Además descubrí que el ordenamiento en realidad no lo necesito—puedo hacerlo en Excel—y que al documento XML le falta la declaración <strong>&lt;?xml&gt;</strong> al pricipio.</p> <h3>Sintetizando el código</h3> <p>Así que decidí cambiar la proyección (el <strong>select </strong>pues) de mi query original.&#160; El total del código quedó así:</p> <div style="border-right: #cccccc 1pt dashed; padding-right: 5pt; border-top: #cccccc 1pt dashed; padding-left: 5pt; font-size: 10pt; background: #f5f5f5; padding-bottom: 5pt; overflow: auto; border-left: #cccccc 1pt dashed; width: 95%; color: black; max-height: 400px; padding-top: 5pt; border-bottom: #cccccc 1pt dashed; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"><span style="color: #2b91af">XElement</span> xml = <span style="color: #2b91af">XElement</span>.Load(<span style="color: #a31515">@&quot;C:\Users\Carlos\Desktop\sampleFxCopReport.xml&quot;</span>);</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"><span style="color: #2b91af">IEnumerable</span>&lt;<span style="color: #2b91af">XElement</span>&gt; query =</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160; <span style="color: blue">from</span> e <span style="color: blue">in</span> xml.Descendants(<span style="color: #a31515">&quot;Issue&quot;</span>)</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160; <span style="color: blue">where</span> e.Ancestors(<span style="color: #a31515">&quot;Message&quot;</span>).Attributes(<span style="color: #a31515">&quot;TypeName&quot;</span>).First().Value == <span style="color: #a31515">&quot;ReviewSqlQueriesForSecurityVulnerabilities&quot;</span></pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160; <span style="color: blue">select</span> <span style="color: blue">new</span> <span style="color: #2b91af">XElement</span>(<span style="color: #a31515">&quot;Vulnerability&quot;</span>,</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> <span style="color: #2b91af">XElement</span>(<span style="color: #a31515">&quot;Module&quot;</span>, e.Ancestors(<span style="color: #a31515">&quot;Module&quot;</span>).Attributes(<span style="color: #a31515">&quot;Name&quot;</span>).First().Value),</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> <span style="color: #2b91af">XElement</span>(<span style="color: #a31515">&quot;Namespace&quot;</span>, e.Ancestors(<span style="color: #a31515">&quot;Namespace&quot;</span>).Attributes(<span style="color: #a31515">&quot;Name&quot;</span>).First().Value),</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> <span style="color: #2b91af">XElement</span>(<span style="color: #a31515">&quot;Type&quot;</span>, e.Ancestors(<span style="color: #a31515">&quot;Type&quot;</span>).Attributes(<span style="color: #a31515">&quot;Name&quot;</span>).First().Value),</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> <span style="color: #2b91af">XElement</span>(<span style="color: #a31515">&quot;Method&quot;</span>, e.Ancestors(<span style="color: #a31515">&quot;Member&quot;</span>).Attributes(<span style="color: #a31515">&quot;Name&quot;</span>).First().Value),</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> <span style="color: #2b91af">XElement</span>(<span style="color: #a31515">&quot;Issue&quot;</span>, e.Value)</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160; );</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"><span style="color: #2b91af">XDocument</span> xDoc = <span style="color: blue">new</span> <span style="color: #2b91af">XDocument</span>(</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160; <span style="color: blue">new</span> <span style="color: #2b91af">XDeclaration</span>(<span style="color: #a31515">&quot;1.0&quot;</span>, <span style="color: #a31515">&quot;UTF-8&quot;</span>, <span style="color: #a31515">&quot;yes&quot;</span>),</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160; <span style="color: blue">new</span> <span style="color: #2b91af">XElement</span>(<span style="color: #a31515">&quot;Vulnerabilities&quot;</span>, query)</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160; );</pre> </div> <p>Nota que con solo 2 instrucciones—la instrucción de carga no cuenta—logré hacer la transformación (<strong>¡!</strong>) <img alt="smile_omg" src="http://spaces.live.com/rte/emoticons/smile_omg.gif" />.&#160;&#160; Veamos los cambios significativos al query.</p> <p>Primero, el resultado es almacenado en una variable que ya no es tipo <strong>var</strong>, sino <strong>IEnumerable&lt;T&gt;</strong> donde <strong>T</strong> es <strong>XElement</strong>.&#160; Esto es porque en la proyección (el <strong>select</strong>) ya no estoy utilizando un tipo anónimo para construir un objeto, sino los constructores de la clase <strong>XElement </strong>para obtener objetos de este tipo.</p> <p>Finalmente, a la hora de crear el nuevo documento XML, utilizo también un constructor alterno de <strong>XDocument</strong>, para primero pasarle la declaración XML, y agregarle un elemento <em>&lt;Vulnerabilities&gt;</em> que tendrá como contenido el resultado de mi query—la lista de nodos <em>&lt;Vulnerability&gt;</em> con sus respectivos elementos hijo.&#160; ¿Así o más mágico? <img alt="smile_teeth" src="http://spaces.live.com/rte/emoticons/smile_teeth.gif" /></p> <p>[<em>Pronunciarse en tono de vendedor de chuchulucos por T.V.:</em>] <strong>¡Pero aún hay más!</strong></p> <p>¿Quieres saber lo que se necesita para guardar el nuevo documento de XML a un archivo?</p> <div style="border-right: #cccccc 1pt dashed; padding-right: 5pt; border-top: #cccccc 1pt dashed; padding-left: 5pt; font-size: 10pt; background: #f5f5f5; padding-bottom: 5pt; overflow: auto; border-left: #cccccc 1pt dashed; width: 95%; color: black; max-height: 400px; padding-top: 5pt; border-bottom: #cccccc 1pt dashed; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">xDoc.Save(<span style="color: #a31515">@&quot;C:\Users\Carlos\Desktop\transformedReport.xml&quot;</span>);</pre> </div> <p>Así que con un total de 4 instrucciones logré cargar un archivo complejo de XML, transformarlo y escribir los resultados a otro más amigable.</p> <p>[<em>Pronunciarse en tono de vendedor de chuchulucos por T.V.:</em>] <strong>¡Pero aún hay más!</strong></p> <h3>Sintetizándo el código aún más</h3> <p>¿En verdad quieres ponerte quisiquilloso con el query?&#160; Puedes lograr la totalidad de la lógica con solo 3 instrucciones—una para cargar el archivo original, otra para transformarlo y una más para guardar el archivo resultante—si utilizas expresiones lambda.&#160; Este ejemplo no lo explico porque igual y te acabo confundiendo más, pero creo que ilustra el poderío de LINQ y las nuevas clases para manipular XML.</p> <div style="border-right: #cccccc 1pt dashed; padding-right: 5pt; border-top: #cccccc 1pt dashed; padding-left: 5pt; font-size: 10pt; background: #f5f5f5; padding-bottom: 5pt; overflow: auto; border-left: #cccccc 1pt dashed; width: 95%; color: black; max-height: 400px; padding-top: 5pt; border-bottom: #cccccc 1pt dashed; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"><span style="color: #2b91af">XElement</span> xml = <span style="color: #2b91af">XElement</span>.Load(<span style="color: #a31515">@&quot;C:\Users\Carlos\Desktop\sampleFxCopReport.xml&quot;</span>);</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace"><span style="color: #2b91af">XDocument</span> xDoc = <span style="color: blue">new</span> <span style="color: #2b91af">XDocument</span>(</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160; <span style="color: blue">new</span> <span style="color: #2b91af">XDeclaration</span>(<span style="color: #a31515">&quot;1.0&quot;</span>, <span style="color: #a31515">&quot;UTF-8&quot;</span>, <span style="color: #a31515">&quot;yes&quot;</span>),</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160; <span style="color: blue">new</span> <span style="color: #2b91af">XElement</span>(<span style="color: #a31515">&quot;Vulnerabilities&quot;</span>,</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160; xml.Descendants(<span style="color: #a31515">&quot;Issue&quot;</span>)</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160; .Where(i =&gt; i.Ancestors(<span style="color: #a31515">&quot;Message&quot;</span>).Attributes(<span style="color: #a31515">&quot;TypeName&quot;</span>).First().Value == <span style="color: #a31515">&quot;ReviewSqlQueriesForSecurityVulnerabilities&quot;</span>)</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160; .Select(e =&gt; <span style="color: blue">new</span> <span style="color: #2b91af">XElement</span>(<span style="color: #a31515">&quot;Vulnerability&quot;</span>,</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> <span style="color: #2b91af">XElement</span>(<span style="color: #a31515">&quot;Module&quot;</span>, e.Ancestors(<span style="color: #a31515">&quot;Module&quot;</span>).Attributes(<span style="color: #a31515">&quot;Name&quot;</span>).First().Value),</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> <span style="color: #2b91af">XElement</span>(<span style="color: #a31515">&quot;Namespace&quot;</span>, e.Ancestors(<span style="color: #a31515">&quot;Namespace&quot;</span>).Attributes(<span style="color: #a31515">&quot;Name&quot;</span>).First().Value),</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> <span style="color: #2b91af">XElement</span>(<span style="color: #a31515">&quot;Type&quot;</span>, e.Ancestors(<span style="color: #a31515">&quot;Type&quot;</span>).Attributes(<span style="color: #a31515">&quot;Name&quot;</span>).First().Value),</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> <span style="color: #2b91af">XElement</span>(<span style="color: #a31515">&quot;Method&quot;</span>, e.Ancestors(<span style="color: #a31515">&quot;Member&quot;</span>).Attributes(<span style="color: #a31515">&quot;Name&quot;</span>).First().Value),</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> <span style="color: #2b91af">XElement</span>(<span style="color: #a31515">&quot;Issue&quot;</span>, e.Value)</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; )</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; )</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160; )</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160; );</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">&#160;</pre> <pre style="margin: 0px; font-family: &#39;Consolas&#39;, &#39;Courier New&#39;, courier, monospace">xDoc.Save(<span style="color: #a31515">@&quot;c:\users\Carlos\Desktop\transformedReport.xml&quot;</span>);</pre> </div> <p>¿Qué tal, eh? <img alt="smile_nerd" src="http://spaces.live.com/rte/emoticons/smile_nerd.gif" /></p> <h3>Conclusión</h3> <p>Este artículo mostró un ejemplo de cómo transformar un documento XML utilizando LINQ to XML.&#160; También mostró de manera práctica qué son los tipos anónimos (“clases sin nombres”), cómo cargar y escribir archivos XML con las clases <strong>XElement</strong> y <strong>XDocument </strong>incluidas en el .NET Framework 3.5, e ilustró brevemente el uso de expresiones lambda.&#160; La mayoría de los conceptos—excepto quizá las expresiones lambda—aplican también si estás utilizando Visual Basic como tu lenguaje de desarrollo para .NET.</p> <p>Enjoy. <img alt="smile_shades" src="http://spaces.live.com/rte/emoticons/smile_shades.gif" /></p> <hr /> <p><font color="#0000ff">[Actualización 04-sept-2008, 3:00 p.m.]</font> Para aquellos que son bien <em>técnicos</em>, los tipos anónimos sí tienen un nombre, solo que este no es elegido por el desarrollador, sino por el compilador, <a href="http://geeks.ms/blogs/fhualpa/archive/2008/07/09/tipos-an-243-nimos-qui-233-n-se-hace-cargo.aspx">como lo mostró Fernik en su excelente artrículo</a>.&#160; En términos <em>prácticos</em> no importa porque normalmente no se ofrece saber cuál es ese nombre.&#160; La palabra clave <strong>var</strong> permite que interactuemos con ellos como si fueran tipos comúnes y corrientes.</p> Carlos Rubalcavahttp://www.blogger.com/profile/10848793413989996197noreply@blogger.comtag:blogger.com,1999:blog-22529781.post-73210958571295812812008-09-03T13:30:00.003-06:002008-09-03T13:48:30.790-06:00Google Chrome beta tampoco me impresiona<p>Todo mundo y su abuelita para ahora se ha de haber enterado que <a href="http://www.google.com/chrome">Google lanzó su propio browser</a>—<em>Wired </em>tiene <a href="http://www.wired.com/techbiz/it/magazine/16-10/mf_chrome?currentPage=all">un artículo interesante</a> de por qué se tardaron tanto para lanzarlo, cuando para muchas personas era una evolución lógica.</p> <p>Bajo riesgo repetir <a href="http://www.dotnetero.com/2008/03/apple-libera-safari-para-windows-ie8.html">artículos anteriores</a>, tengo que admitir que cuando comencé a ver <a href="http://www.google.com/chrome/intl/es/features.html">la lista de características</a> “inovadoras” me sorprendió lo <strong>no</strong> inovadoras que en realidad son:</p> <ul> <li><strong>Omnibox.</strong> Básicamente una versión del <em>Awesomebar</em> (Firefox 3) o del <em>Smart Address Bar</em> de IE8 beta2, pero con búsqueda integrada. Moderadamente interesante. Se parece también al search box que trae Flock—y el cual espero fusionen con el <em>Awesomebar</em> para Flock 2 final. </li> <li><strong>Pestañas independientes.</strong> Rara vez se me ha ofrecido que una pestaña haga que truene el navegador. De las pocas veces que me ha sucedido es cuando corro IETab dentro de Firefox, e incluso en esas instancias FF hace buen trabajo en recuperar mi sesión. Pero, la idea es interesante. Tanto que al parecer <a href="http://www.winsupersite.com/reviews/ie8_beta2.asp">se le ocurrió lo mismo al equipo de Internet Explorer 8.</a> </li> <li><strong>Acceso directo a aplicaciones.</strong> Un concepto que se me hizo bastante útil, desde que el equipo de Mozilla comenzó con el <a href="http://developer.mozilla.org/en/Prism">proyecto Prism</a> hace casi un año (¿?)—y del cual, naturalmente <a href="https://addons.mozilla.org/en-US/firefox/addon/6665">hay una extensión para Firefox</a>. </li> <li><strong>Pestañas dinámicas.</strong> Yo suelo mantener una sola ventana de navegador abierta—si no ¿pa’ qué quiero las pestañas, verdad?—pero si les gusta esta característica, también pueden encontrarla en Safari. </li> <li><strong>Modo incógnito</strong>. O como dijo un amigo mío, modo “p0rn” jejeje—y no que <em>yo </em>lo use, ¿verdad? Hmm… ¿dónde he visto eso? ¡Ah! Qué tal en Safari (conocido como <em>Private Browsing) </em>y en IE 8 beta 2 (conocido como <em>InPrivate</em>). </li> <li><strong>Marcadores instantáneos.</strong> Ver Flock, y FF 3. No digo más. </li> </ul> <p>De lo único que en verdad puedo ver inovador es el motor de JavaScript que le pusieron, V8, que al parecer <a href="http://news.cnet.com/8301-1001_3-10030888-92.html?part=rss">patea traseros en desempeño</a>. Y aunque algunos autores han argumentado que JavaScript es “solo una parte mínima del Web”, yo les digo: ¿Alguna vez has intentado correr Gmail, Slashdot o Facebook en IE7 o previos contra <em>cualquier</em> otro navegador moderno? JavaScript sí importa, y mucho.</p> <p>Tratando de no tirar mucho rollo—demasiado tarde, lo sé—sí hubo cosas que me gustaron:</p> <ul> <li><strong>Desempeño. </strong>Jala hecho la mater <strong>cuando no está detrás de un proxy</strong>—lean un poco más abajo<strong>.</strong> </li> <li><strong>Google Gears integrado. </strong>No tienes que instalar esto por separado para utilizar, por ejemplo, Google Reader en modo <em>offline.</em> No sorprendente, dado que otro producto de Google, pero es útil que lo traiga integrado. </li> <li><strong>Interfaz minimalista. </strong>De las primeras cosas que le hago a Firefox es quitarle todos los botones y cosas extra y si vieran mi pantalla verían que mi arreglo quedó prácticamente idéntico al que usaron en Chrome. Safari también viene de cajón así. </li> <li><strong>Herramientas de desarrollo Web incluidas.</strong> Al igual que Safari, puedes seleccionar un elemento y dar “Inspect Element” para obtener información de CSS, etc. </li> <li><strong>Búsqueda en la página amigable.</strong> Casi igual que la de Safari—¿comienzan a ver un patrón? </li> </ul> <p align="center"><a href="http://lh5.ggpht.com/carlos.rubalcava/SL7lznqk6tI/AAAAAAAAAVg/MYOqvefxoTw/s1600-h/image%5B8%5D.png"><img title="image" alt="image" src="http://lh6.ggpht.com/carlos.rubalcava/SL7l8eW6ILI/AAAAAAAAAVk/hpsh1n1pkq4/image_thumb%5B6%5D.png?imgmax=800" width="604" height="480" /></a> </p> <p>Si quisiera resumir “lo bueno” diría que en muchos sentidos, Chrome es como Safari, pero sin el rendereo borroso de fonts en Windows y con Gears integrado.</p> <p>Lo que de plano no me gusto, y de hecho impide que lo use de tiempo completo:</p> <ul> <li><strong>No le gustan los proxies</strong>, sobretodo los que te piden username y password. Ni siquiera puedes instalarlo si estás detrás de un proxy de este tipo. Y el desempeño se va por el caño, con muchas páginas que no se llegan a cargarse completas—no pude correr Gmail, lo cual es el colmo. Esto quizá es de esperarse de un beta—Safari tuvo problemas similares que resolvieron en la versión final—pero por ahora es un <em>dealbreaker</em> para mi. </li> <li><strong>Fallas de compatibilidad con sitios sociales.</strong> Algunas cosas en Facebook y MySpace no funcionan aún con Chrome. Unas simplemente hacen una experiencia menos agradable y otras de plano hacen que no puedas utilizar funcionalidad de estos sitios. MySpace puede irse a chiflar alpistle—es el sitio del demonio en lo que a mi concierne—pero Facebook está bastante bien armado hasta donde sé. Pero si el navegador no jala bien en estos sitios, ¿cuántos chavalos de 12 a 17 años que se la pasan viviendo ahí lo usarían? </li><li><strong>No trae soporte para RSS.</strong> Solo muestra el XML del feed. ¿Cómo se supone que voy a leer mis noticias? </li> </ul> <p>¿Matará Chrome a IE? Lo dudo. Habrá que ver lo que sucede. En mi opinión esto tomaría tiempo, aunque es interesante que algunos ya le <a href="http://tech.slashdot.org/tech/08/09/03/1343226.shtml">achacan el 3% del mercado</a> después de su lanzamiento. Google es una compañía a la par con los recursos y reputación de Microsoft, lo cual introduce una dinámica interesante, sobretodo para los que desarrollamos aplicaciones Web. Antes probablemente te preocupabas por que tus sitios jalaran en IE o Firefox, si mucho—al pobre de Opera nunca lo han pelado y mucho menos a Konqueror et.al. Ahora que tienes Safari y Chrome en el mercado, creo que finalmente comenzaremos una era donde los estándares en el desarrollo del Web cobren la importancia que debieron tener desde el principio. *Cruzando los dedos para que suceda*</p> <p>Enjoy.</p>Carlos Rubalcavahttp://www.blogger.com/profile/10848793413989996197noreply@blogger.comtag:blogger.com,1999:blog-22529781.post-73361995281984352212008-08-12T05:43:00.001-06:002008-08-12T05:58:54.726-06:00Visual Studio 2008 Service Pack 1 ya está disponible<p>Al menos para suscriptores de MSDN.</p> <p><a href="http://blogs.msdn.com/msdnsubscriptions/archive/2008/08/11/visual-studio-2008-service-pack-1-files-are-also-now-available.aspx">Official MSDN Subscriptions Blog : Visual Studio 2008 Service Pack 1 files are also now available</a></p> <p>Oh, y también ya soltaron la versión RTM de SQL Server 2008.</p> <p>¿Qué es lo que agrega?</p> <blockquote> <p><strong>Visual Studio 2008 SP1 delivers: </strong></p> <ul> <li>Improved WPF designers </li> <li><strong>SQL Server 2008 support</strong> </li> <li><strong>ADO.NET Entity Designer</strong> </li> <li>Visual Basic and Visual C++ components and tools (including an MFC-based Office 2007 style ‘Ribbon’) </li> <li>Visual Studio Team System Team Foundation Server (TFS) addresses customer feedback on version control usability and performance, email integration with work item tracking and full support for hosting on SQL Server 2008 </li> <li>Richer JavaScript support, enhanced AJAX and data tools, and Web site deployment improvements</li> </ul> <p><strong>The .NET Framework 3.5 SP1 delivers:</strong></p> <ul> <li>Performance increases between 20-45% for WPF-based applications – without having to change any code </li> <li>WCF improvements that give developers more control over the way they access data and services </li> <li>Streamlined installation experience for client applications </li> <li>Improvements in the area of data platform, such as the ADO.NET Entity Framework, ADO.NET Data Services and support for SQL Server 2008’s new features</li> </ul> </blockquote> <p>[Tomado de <a href="http://msdn.microsoft.com/en-us/vstudio/products/cc533447.aspx">esta página</a>, énfasis mía]</p> <p>Enjoy</p> Carlos Rubalcavahttp://www.blogger.com/profile/10848793413989996197noreply@blogger.comtag:blogger.com,1999:blog-22529781.post-15013197564293529322008-06-10T19:45:00.001-06:002008-06-10T19:45:31.669-06:00Reseña del Lanzamiento de Visual Studio 2008<p>Alex Briseño puso una muy buena <a href="http://alexbriseno.blogspot.com/2008/06/ahora-si-llego-el-dia.html">reseña del evento que tuvimos el pasado martes 27 de mayo</a>, repleto de fotografías, pa’ que vayan a leerla.&#160; </p> <p>La verdad yo me divertí un chorro, a pesar de que quedé exhausto porque me tocó dar 3 pláticas—lo cual implica hablar casi tres horas—me dió mucho gusto ver tanta gente.&#160; También se sintió bien padre que que ahora sí tuvimos bastantes cosas que regalar como todos esos paquetes de desarrollador con Visual Studio 2008, SQL Server 2008 y Windows Server 2008, así como los discos de Windows Vista y las suscripciones de TechNet. </p> <p>Pero lo más chido creo que fue definitivamente el final, cuando nos pusimos a jugar—o a hacer el intento de jugar—boliche y a echarnos unas chelas con toda la raza <em>hardcore </em>que se quedó hasta esa hora.&#160; </p> <p>El momento <i>priceless</i> se lo llevó Sergio, después de ganarle a Alex: “No pos si es la primera vez que juego”... ajá... sí cómo no... jejeje</p> Carlos Rubalcavahttp://www.blogger.com/profile/10848793413989996197noreply@blogger.comtag:blogger.com,1999:blog-22529781.post-82490547828919127532008-06-03T13:07:00.001-06:002008-06-03T13:13:37.097-06:00Cómo acceder a controles dentro de un GridView<p>Esta entrada sali&#243; como resultado de <a href="http://comunidadnetjuarez.org/forums/thread/1436.aspx">una pregunta que hicieron en el Foro de la Comunidad .NET</a>.&#160; La pregunta, esencialmente, es: <em>&#191;C&#243;mo accedo a un control que tengo en una columna templeteada </em><em>dentro de un </em><strong>GridView</strong> <em>de ASP.NET?</em></p> <p>Me pareci&#243; buena la pregunta, as&#237; que hice un peque&#241;o ejemplo para ilustrarlo.&#160;&#160; Una columna templeteada (<strong>TemplateField</strong>) es distinta a una normal (<strong>BoundField</strong>) en que tienes m&#225;s control sobre los controles que aparecen en la columna.&#160; En otras palabras, t&#250; especificas qu&#233; quieres que se muestre cuando el rengl&#243;n est&#225; en modo &quot;normal&quot; (<strong>ItemTemplate</strong>) o cuando est&#225; en modo &quot;edici&#243;n&quot; (<strong>EditItemTemplate</strong>).&#160; Puedes tener m&#250;ltiples controles dentro de la columna, en lugar de solo uno que represente el dato.</p> <p>La siguiente p&#225;gina contiene un GridView con tres columnas que vienen de un SqlDataSource.&#160; Los datos provienen de la cl&#225;sica base de datos Northwind.&#160;&#160; En este caso estoy recuperando datos de la tabla de productos:</p> <div style="border-right: #cccccc 1pt dashed; padding-right: 5pt; border-top: #cccccc 1pt dashed; padding-left: 5pt; font-size: 10pt; background: #f5f5f5; padding-bottom: 5pt; overflow: auto; border-left: #cccccc 1pt dashed; width: 95%; color: black; max-height: 400px; padding-top: 5pt; border-bottom: #cccccc 1pt dashed; font-family: consolas, &#39;Courier New&#39;, courier, monospace"> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace"><span style="background: #ffee62">&lt;%</span><span style="color: blue">@</span> <span style="color: #a31515">Page</span> <span style="color: red">Language</span><span style="color: blue">=&quot;VB&quot;</span> <span style="color: red">AutoEventWireup</span><span style="color: blue">=&quot;false&quot;</span> <span style="color: red">CodeFile</span><span style="color: blue">=&quot;Default.aspx.vb&quot;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160; <span style="color: red">Inherits</span><span style="color: blue">=&quot;_Default&quot;</span> <span style="background: #ffee62">%&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;</pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace"><span style="color: blue">&lt;!</span><span style="color: #a31515">DOCTYPE</span> <span style="color: red">html</span> <span style="color: red">PUBLIC</span> <span style="color: blue">&quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;</span> </pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160; <span style="color: blue">&quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace"><span style="color: blue">&lt;</span><span style="color: #a31515">html</span> <span style="color: red">xmlns</span><span style="color: blue">=&quot;http://www.w3.org/1999/xhtml&quot;&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace"><span style="color: blue">&lt;</span><span style="color: #a31515">head</span> <span style="color: red">id</span><span style="color: blue">=&quot;Head1&quot;</span> <span style="color: red">runat</span><span style="color: blue">=&quot;server&quot;&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">title</span><span style="color: blue">&gt;</span>Accediendo a Elementos en un GridView<span style="color: blue">&lt;/</span><span style="color: #a31515">title</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">style</span> <span style="color: red">type</span><span style="color: blue">=&quot;text/css&quot;&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160; <span style="color: #a31515">#miGrid</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160; {</pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160; <span style="color: red">width</span>: <span style="color: blue">450px</span>;</pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160; <span style="color: red">float</span>: <span style="color: blue">left</span>;</pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160; }</pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160; <span style="color: blue">&lt;/</span><span style="color: #a31515">style</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace"><span style="color: blue">&lt;/</span><span style="color: #a31515">head</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace"><span style="color: blue">&lt;</span><span style="color: #a31515">body</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">form</span> <span style="color: red">id</span><span style="color: blue">=&quot;form1&quot;</span> <span style="color: red">runat</span><span style="color: blue">=&quot;server&quot;&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">asp</span><span style="color: blue">:</span><span style="color: #a31515">Button</span> <span style="color: red">runat</span><span style="color: blue">=&quot;server&quot;</span> <span style="color: red">ID</span><span style="color: blue">=&quot;leerElementosButton&quot;</span> <span style="color: red">Text</span><span style="color: blue">=&quot;Leer elementos&quot;</span> <span style="color: blue">/&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">div</span> <span style="color: red">id</span><span style="color: blue">=&quot;miGrid&quot;&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">asp</span><span style="color: blue">:</span><span style="color: #a31515">GridView</span> <span style="color: red">ID</span><span style="color: blue">=&quot;GridView1&quot;</span> <span style="color: red">runat</span><span style="color: blue">=&quot;server&quot;</span> <span style="color: red">AutoGenerateColumns</span><span style="color: blue">=&quot;False&quot;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160; <span style="color: red">DataKeyNames</span><span style="color: blue">=&quot;ProductID&quot;</span> <span style="color: red">DataSourceID</span><span style="color: blue">=&quot;SqlDataSource1&quot;</span> </pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160; <span style="color: red">EmptyDataText</span><span style="color: blue">=&quot;No hay registros que mostrar.&quot;&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">Columns</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">asp</span><span style="color: blue">:</span><span style="color: #a31515">BoundField</span> <span style="color: red">DataField</span><span style="color: blue">=&quot;ProductID&quot;</span> <span style="color: red">HeaderText</span><span style="color: blue">=&quot;ID Producto&quot;</span> </pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: red">InsertVisible</span><span style="color: blue">=&quot;False&quot;</span> <span style="color: red">ReadOnly</span><span style="color: blue">=&quot;True&quot;</span> <span style="color: blue">/&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">asp</span><span style="color: blue">:</span><span style="color: #a31515">BoundField</span> <span style="color: red">DataField</span><span style="color: blue">=&quot;ProductName&quot;</span> <span style="color: red">HeaderText</span><span style="color: blue">=&quot;Nombre Producto&quot;</span> <span style="color: blue">/&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">asp</span><span style="color: blue">:</span><span style="color: #a31515">TemplateField</span> <span style="color: red">HeaderText</span><span style="color: blue">=&quot;Descontinuado&quot;&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">EditItemTemplate</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">asp</span><span style="color: blue">:</span><span style="color: #a31515">CheckBox</span> <span style="color: red">ID</span><span style="color: blue">=&quot;CheckBox1&quot;</span> <span style="color: red">runat</span><span style="color: blue">=&quot;server&quot;</span> </pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: red">Checked</span><span style="color: blue">='</span><span style="background: #ffee62">&lt;%</span># Bind(&quot;Discontinued&quot;) <span style="background: #ffee62">%&gt;</span><span style="color: blue">'</span> <span style="color: blue">/&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">&lt;/</span><span style="color: #a31515">EditItemTemplate</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">ItemTemplate</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">asp</span><span style="color: blue">:</span><span style="color: #a31515">CheckBox</span> <span style="color: red">ID</span><span style="color: blue">=&quot;CheckBox1&quot;</span> <span style="color: red">runat</span><span style="color: blue">=&quot;server&quot;</span> </pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: red">Checked</span><span style="color: blue">='</span><span style="background: #ffee62">&lt;%</span># Bind(&quot;Discontinued&quot;) <span style="background: #ffee62">%&gt;</span><span style="color: blue">'</span> <span style="color: red">Enabled</span><span style="color: blue">=&quot;false&quot;</span> <span style="color: blue">/&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">&lt;/</span><span style="color: #a31515">ItemTemplate</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">&lt;/</span><span style="color: #a31515">asp</span><span style="color: blue">:</span><span style="color: #a31515">TemplateField</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160; <span style="color: blue">&lt;/</span><span style="color: #a31515">Columns</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160; <span style="color: blue">&lt;/</span><span style="color: #a31515">asp</span><span style="color: blue">:</span><span style="color: #a31515">GridView</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">asp</span><span style="color: blue">:</span><span style="color: #a31515">SqlDataSource</span> <span style="color: red">ID</span><span style="color: blue">=&quot;SqlDataSource1&quot;</span> <span style="color: red">runat</span><span style="color: blue">=&quot;server&quot;</span> </pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160; <span style="color: red">ConnectionString</span><span style="color: blue">=&quot;</span><span style="background: #ffee62">&lt;%</span>$ ConnectionStrings:NorthwindConnectionString <span style="background: #ffee62">%&gt;</span><span style="color: blue">&quot;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160; <span style="color: red">ProviderName</span><span style="color: blue">=&quot;</span><span style="background: #ffee62">&lt;%</span>$ ConnectionStrings:NorthwindConnectionString.ProviderName <span style="background: #ffee62">%&gt;</span><span style="color: blue">&quot;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160; <span style="color: red">SelectCommand</span><span style="color: blue">=&quot;SELECT [ProductID], [ProductName], [Discontinued] FROM [Products]&quot;&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160; <span style="color: blue">&lt;/</span><span style="color: #a31515">asp</span><span style="color: blue">:</span><span style="color: #a31515">SqlDataSource</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160; <span style="color: blue">&lt;/</span><span style="color: #a31515">div</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">div</span> <span style="color: red">id</span><span style="color: blue">=&quot;resultados&quot;&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">asp</span><span style="color: blue">:</span><span style="color: #a31515">Label</span> <span style="color: red">runat</span><span style="color: blue">=&quot;server&quot;</span> <span style="color: red">ID</span><span style="color: blue">=&quot;resultadosLabel&quot;</span> <span style="color: blue">/&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160; <span style="color: blue">&lt;/</span><span style="color: #a31515">div</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160; <span style="color: blue">&lt;/</span><span style="color: #a31515">form</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace"><span style="color: blue">&lt;/</span><span style="color: #a31515">body</span><span style="color: blue">&gt;</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace"><span style="color: blue">&lt;/</span><span style="color: #a31515">html</span><span style="color: blue">&gt;</span></pre> </div> <p>Para acceder, por ejemplo, al CheckBox que est&#225; dentro de la columna templeteada, primero necesitas una referencia al rengl&#243;n, ya que el ID del control se repetir&#225; <em>n</em> veces (una por cada rengl&#243;n del Grid).&#160; </p> <p>Esto se puede hacer de varias formas, por ejemplo, si tienes un manejador para un evento clic en alguno de los controles dentro del rengl&#243;n pues en ese caso el <em>sender</em> viene siendo el rengl&#243;n en s&#237;, entonces &#250;nicamente te falta encontrar el CheckBox de ese rengl&#243;n para leer sus propiedades.&#160;&#160; Otra forma de hacerlo, como en el siguiente ejemplo, es leer todos los renglones y por cada uno encontrar el CheckBox que le corresponde al rengl&#243;n:</p> <div style="border-right: #cccccc 1pt dashed; padding-right: 5pt; border-top: #cccccc 1pt dashed; padding-left: 5pt; font-size: 10pt; background: #f5f5f5; padding-bottom: 5pt; overflow: auto; border-left: #cccccc 1pt dashed; width: 95%; color: black; max-height: 400px; padding-top: 5pt; border-bottom: #cccccc 1pt dashed; font-family: consolas, &#39;Courier New&#39;, courier, monospace"> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace"><span style="color: blue">Partial</span> <span style="color: blue">Class</span> _Default</pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160; <span style="color: blue">Inherits</span> System.Web.UI.Page</pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;</pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160; <span style="color: blue">Protected</span> <span style="color: blue">Sub</span> leerElementosButton_Click(<span style="color: blue">ByVal</span> sender <span style="color: blue">As</span> <span style="color: blue">Object</span>, _</pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160; <span style="color: blue">ByVal</span> e <span style="color: blue">As</span> System.EventArgs) <span style="color: blue">Handles</span> leerElementosButton.Click</pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;</pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160; <span style="color: blue">Dim</span> grid <span style="color: blue">As</span> GridView = <span style="color: blue">Me</span>.GridView1</pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160; <span style="color: blue">Dim</span> checkBox <span style="color: blue">As</span> CheckBox</pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160; <span style="color: blue">Dim</span> resultado <span style="color: blue">As</span> <span style="color: blue">New</span> StringBuilder</pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;</pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160; <span style="color: blue">For</span> <span style="color: blue">Each</span> renglon <span style="color: blue">As</span> GridViewRow <span style="color: blue">In</span> grid.Rows</pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160; checkBox = <span style="color: blue">CType</span>(renglon.FindControl(<span style="color: #a31515">&quot;CheckBox1&quot;</span>), CheckBox)</pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160; <span style="color: blue">If</span> checkBox.Checked <span style="color: blue">Then</span>&#160; <span style="color: green">'Hacer algo con esta informaci&#243;n</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160; resultado.Append(<span style="color: blue">String</span>.Format( _</pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515">&quot;El rengl&#243;n {0} est&#225; descontinuado &lt;br /&gt;&quot;</span>, renglon.DataItemIndex))</pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160;&#160;&#160; <span style="color: blue">End</span> <span style="color: blue">If</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160; <span style="color: blue">Next</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;</pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;&#160;&#160; resultadosLabel.Text = resultado.ToString()</pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160;</pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace">&#160; <span style="color: blue">End</span> <span style="color: blue">Sub</span></pre> <pre style="margin: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace"><span style="color: blue">End</span> <span style="color: blue">Class</span></pre> </div> <p>En res&#250;men, la idea clave aqu&#237; es que el <strong>GridView</strong> tiene una colecci&#243;n de renglones (de tipo <strong>GridViewRow</strong>) y cada uno de estos renglones tiene su correspondiente colecci&#243;n de controles que est&#225;n dentro de ese rengl&#243;n.&#160; El <strong>GridViewRow </strong>tambi&#233;n te da acceso al <strong>DataItem </strong>que contiene los datos asociados al rengl&#243;n, en caso de que lo requirieras.</p> <p>El resultado de correr el c&#243;digo anterior (dando clic al bot&#243;n) es el siguiente:</p> <p align="center"><img src="http://i110.photobucket.com/albums/n109/carlosrubalcava/screenshots/AccediendoAElementosEnGridView.jpg" /> </p> <p>Espero les ayude.</p> <p>Enjoy <img alt="smile_shades" src="http://spaces.live.com/rte/emoticons/smile_shades.gif" /></p> Carlos Rubalcavahttp://www.blogger.com/profile/10848793413989996197noreply@blogger.comtag:blogger.com,1999:blog-22529781.post-40955769283427241002008-05-15T12:28:00.001-06:002008-05-15T12:28:09.239-06:00Creo que he estado trabajando mucho...<p>Me sali&#243; esto hoy.&#160; Creo que Visual Studio est&#225; tratando de decirme algo...</p> <p align="center"><img src="http://i110.photobucket.com/albums/n109/carlosrubalcava/screenshots/OutOfMemory.png" /></p> Carlos Rubalcavahttp://www.blogger.com/profile/10848793413989996197noreply@blogger.comtag:blogger.com,1999:blog-22529781.post-31665067814312639462008-04-20T15:42:00.002-06:002008-04-20T16:36:05.680-06:00Domina los atajos de teclado para Visual Studio<p>Una de las maneras m&#225;s f&#225;ciles de incrementar tu productividad cuando utilizas casi cualquier programa es aprenderte los atajos de teclado&#8212;los mentaos <em>keyboard shortcuts</em>, pues.&#160; De hecho tengo amigos que <strong>odian </strong>levantar las manos del teclado cuando est&#225;n programando.&#160; Si alguna vez has usado alg&#250;n editor de texto como <em><strong>vi</strong></em>, quiz&#225; hayas apreciado que una vez que dominas la complejidad de los comandos, en realidad se siente como si estuvieras &quot;platicando&quot; con el editor. Y aunque yo no llegar&#237;a al extremo de recomendar que <a href="http://www.viemu.com/">manejes Visual Studio con los comandos de vi</a>, s&#237; recomiendo enormemente que te aprendas algunos de los m&#225;s com&#250;nes que ya vienen de caj&#243;n con el <abbr title="Integrated Development Environment">IDE</abbr>. </p> <p>El problema es que Visual Studio tiene 8 millones 557,934 comandos.&#160; Bueno, quiz&#225; algunos menos, pero a&#250;n as&#237; son un titipuchal.&#160; Y lo que es peor, los atajos de teclado cambian de acuerdo a la configuraci&#243;n general de Visual Studio.&#160; Esta es la configuraci&#243;n que te pregunta la primer vez que arrancas el IDE o si das <strong>Tools&gt;Import and Export Settings...&gt;Reset all settings</strong>.</p> <p align="center"><img alt="Ventana de di&#225;logo de configuraci&#243;n general de Visual Studio" src="http://i110.photobucket.com/albums/n109/carlosrubalcava/screenshots/visualstudiosettings.png" /> </p> <p>Aqu&#237; es donde ayudan algunos documentos de referencia r&#225;pida.&#160; Si primordialmente desarrollas en Visual Basic, y utilizas esa configuraci&#243;n <strong><em>(Visual Basic Development Settings)</em></strong>, <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=6bb41456-9378-4746-b502-b4c5f7182203&amp;DisplayLang=en">aqu&#237; hay un PDF de Microsoft</a> que los resume.&#160; </p> <p>Si usas la configuraci&#243;n de <em><strong>Visual C# Development Settings</strong></em>, para desarrollar primordialmente en C#, est&#225;n este <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=c15d210d-a926-46a8-a586-31f8a2e576fe&amp;DisplayLang=en">para Visual Studio 2005</a> y este otro <a href="http://www.microsoft.com/downloads/details.aspx?familyid=E5F902A8-5BB5-4CC6-907E-472809749973&amp;displaylang=en">para Visual Studio 2008</a>.</p> <p>Sin embargo, yo utilizo la configuraci&#243;n para desarrollo general <em><strong>(General Development Settings)</strong></em> porque desarrollo tanto aplicaciones Web como Windows, a veces en C# y a veces en Visual Basic, aparte que ya me hab&#237;a aprendido algunos atajos desde versiones anteriores de Visual Studio.&#160; Como no encontr&#233; ninguna referencia r&#225;pida para esta configuraci&#243;n, cre&#233; mi propio documento.&#160; Puedes <a href="http://comunidadnetjuarez.org/files/folders/varios/entry1325.aspx">descargarlo del sitio de la Comunidad</a>.</p> <p>Mi recomendaci&#243;n personal es, no intentes aprenderlos todos de un zopet&#243;n.&#160; Dice un proverbio: &quot;&#191;C&#243;mo te comes un elefante? Un bocado a la vez&quot;.&#160; As&#237; que mejor escoge un grupo de comandos y practica cada uno por separado, repiti&#233;ndolo al menos 20 veces.&#160; Lo que yo hice fue agarrar una archivo con c&#243;digo y practicar un comando a la vez en diferentes partes del archivo mientras lo &quot;vocalizaba mentalmente&quot; hasta que quedaba grabado en mi memoria muscular.&#160; Luego practicaba el siguiente comando hasta terminar el grupo.&#160; Al d&#237;a siguiente me enfocaba en un grupo distinto, y as&#237; sucesivamente.</p> <h3>C&#243;mo crear tus propios atajos</h3> <p>Por supuesto, tambi&#233;n puedes definir tus propios atajos.&#160; Estos atajos pueden ejecutar un comando del IDE o alguna macro que hayas creado para alguna tarea espec&#237;fica.&#160; Por ejemplo, hay dos atajos que a mi me ha sido &#250;til definir: uno para comparar el archivo actual contra la versi&#243;n en el controlador de c&#243;digo y otro para obtener el historial del archivo actual en el controlador de c&#243;digo.</p> <p>Para definirlos, primero ve a <strong>Tools&gt;Options... </strong>y luego <strong>Environment&gt;Keyboard</strong>.&#160; Al hacerlo ver&#225;s la siguiente ventana:</p> <p align="center"><img src="http://i110.photobucket.com/albums/n109/carlosrubalcava/screenshots/visualstudiokeyboardoptions.png" /> </p> <p>En la parte donde dice <em><strong>Show commands containing</strong></em>, teclea parte del comando, p. ej. &quot;compare&quot;.&#160; Esto traer&#225; una lista de posibles comandos.&#160; En este caso, el que busco es <strong>File.Compare</strong>.&#160; Luego, selecciona el comando adecuado de la lista y pon el cursor en la parte donde dice <em><strong>Press shortcut keys</strong>.</em> Presiona la combinaci&#243;n que desees utilizar.&#160; Si la combinaci&#243;n ya est&#225; siendo utilizada por alg&#250;n otro comando, esta informaci&#243;n ser&#225; mostrada en la parte de abajo donde dice <strong><em>Shortcut currently used by.</em></strong>&#160; En mi caso escog&#237; la combinaci&#243;n <strong>Ctrl+Alt+F,C</strong> para finalmente darle clic en el bot&#243;n <em><strong>Assign</strong></em>.&#160; </p> <p align="center"><img src="http://i110.photobucket.com/albums/n109/carlosrubalcava/screenshots/visualstudiokeyboardoptions_filecom.png" /> </p> <p>Repite los mismos pasos para el comando <strong>File.ViewHistory </strong>y utiliza el atajo <strong>Ctrl+Alt+F,H&#8212;</strong>o cualquier otra combinaci&#243;n que m&#225;s te guste.</p> En fin, creo que esto da la idea.&#160; Enjoy <img alt="smile_shades" src="http://spaces.live.com/rte/emoticons/smile_shades.gif" />Carlos Rubalcavahttp://www.blogger.com/profile/10848793413989996197noreply@blogger.comtag:blogger.com,1999:blog-22529781.post-27477541599938545072008-04-11T19:51:00.001-06:002008-04-11T19:51:54.598-06:00La Generación M: Al borde del un nuevo cambio<p>Hoy me toc&#243; dar una pl&#225;tica bastante diferente a la que estoy acostumbrado.&#160; Resulta que los chavos de la carrera de Tecnolog&#237;as Computacionales del Tec de Monterrey Campus Ju&#225;rez (mi &quot;alma mater&quot;) hicieron un evento llamado <strong>El Congreso</strong> con la finalidad de atraer a m&#225;s chavos (y chavas, claro, si no qu&#233; chiste) de las prepas y secundarias locales hacia las carreras de &quot;sistemas&quot;.</p> <p>Aparentemente algunos de ellos hab&#237;an le&#237;do mi blog y me enviaron un correo para invitarme a participar como expositor, lo cual se me hizo un honor.&#160; Se siente medio raro regresar a la escuela de donde te graduaste para &quot;ense&#241;ar algo&quot;.&#160; Pero cuando me dijeron que la audiencia ser&#237;an principalmente <em>lepes</em> de preparatoria comenc&#233; a ponerme un poco nervioso.&#160; Despu&#233;s de todo, han pasado casi 10 a&#241;os&#8212;a ver d&#237;aganlo: &quot;uuuuuuuuuuuuu!&quot;&#8212;desde que dej&#233; de dar clases, y no me paraba a hablar enfrente de un grupo de esa edad.&#160; Mi mente inmediatamente comenz&#243; a dar vueltas: &quot;Demonios, &#191;de qu&#233; les puedo hablar? &#191;De qu&#233; manera puedo encontrar un tema donde tengamos algo en com&#250;n, y que hable de tecnolog&#237;a?&quot;&#160; </p> <p>Pens&#225;ndola un poco m&#225;s ca&#237; en cuenta que muchos de estos chicos, son <em>modelo 90</em> o m&#225;s reciente&#8212;osea que nacieron despu&#233;s de 1990&#8212;lo cual me hizo sentir <em>m&#225;s </em>ruco todav&#237;a porque yo soy setentayqu&#237;h&#250;bole.&#160; Mientras m&#225;s lo pensaba m&#225;s me era evidente que hay un a brecha entre esta generaci&#243;n y la m&#237;a.&#160; Comenc&#233; a recordar c&#243;mo era el mundo cuando <em>yo</em> ten&#237;a la edad de ellos&#8212;hace 15 a&#241;os m&#225;s o menos&#8212;y c&#243;mo hab&#237;a cambiado el mundo desde entonces hasta ahora, hasta que me cay&#243; el veinte: &quot;&#191;y por qu&#233; no hablar precisamente sobre eso?&quot;.</p> <p>As&#237; que ech&#233; un poco de alucine este fue el resultado. </p> <h3>Generaci&#243;n i</h3> <p>La i es de internet.&#160; Esta es la generaci&#243;n a la que creo que pertenezco.&#160; En ella incluyo a las personas que eran adolescentes durante los pricipios de la d&#233;cada de 1990 y que nos toc&#243;, por un lado, ver el nacimiento del internet&#8212;s&#237; ya s&#233; que el <em>intern&#233;</em> exist&#237;a desde los 70s y 80s pero no fue sino hasta los 90s que el Web lo trajo a las masas &#191;verdad?&#8212;y por otro lado presenciar cambios hist&#243;ricos a nivel mundial como la ca&#237;da del comunismo.</p> <p align="center">&#160;<img src="http://i110.photobucket.com/albums/n109/carlosrubalcava/screenshots/generacion_i.jpg" /> </p> <p>A&#250;n recuerdo ver en la televisi&#243;n c&#243;mo derribaban el muro de Berl&#237;n.&#160; Recuerdo ver tambi&#233;n en la T.V. los tanques en Rusia mientras intentaron el golpe de estado contra Gorbachev y sentirme triste porque le&#237; su libro sobre la <em>perestroika </em>y el <em>glasnost</em>.&#160; Recuerdo la ca&#237;da, pa&#237;s por pa&#237;s, de la cortina de hierro en Europa y tambi&#233;n la <em>primera</em> Guerra del Golfo P&#233;rsico donde <em>una coalici&#243;n de pa&#237;ses</em> decidi&#243; luchar contra Saddam Hussein.</p> <p>Para cuando tuve edad de entrar en a la carrera en 1994, el mundo entero parec&#237;a enamorado de nuevo con el capitalismo y la apertura de mercados.&#160; M&#233;xico llevaba poco que hab&#237;a firmado el TLC y en el Tec hasta inventaron carreras nuevas como la de Lic. en Comercio Internacional.&#160; Tambi&#233;n por aquellos tiempos el internet comenzaba a salir de las escuelas y a entrar a los hogares.&#160; El Tec, que hasta entonces hab&#237;a sido el &#250;nico ISP de Cd. Ju&#225;rez, le dej&#243; eso a compa&#241;&#237;as como Infolink (si mal no recuerdo)&#8212;&#191;se acuerdan cuando ten&#237;an que pagarle a alguien y marcarles por tel&#233;fono con su m&#243;dem para estar &quot;en l&#237;nea&quot;? &#191;No? <em>Chin.</em></p> <p>El caso es que se respiraba un ambiente de apertura.&#160; En el lado tecnol&#243;gico esa actitud comenz&#243; a reflejarse en movimientos como el de Open Source.&#160; Las personas comenzaron a colaborar a pesar de las grandes distancias gracias a la red que ahora cobraba vida.&#160; Est&#225;bamos en plena &quot;globalizaci&#243;n 1.0&quot;, como lo describe <a href="http://www.amazon.com/World-Flat-3-0-History-Twenty-first/dp/0312425074/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1207952544&amp;sr=8-1">Thomas Friedman</a> y el mundo se estaba aplanando.&#160; El internet hab&#237;a fomentado la globalizaci&#243;n y la globalizaci&#243;n ayud&#243; al crecimiento de la red.&#160; <a href="http://www.dotnetero.com/2007/01/el-carlos-en-un-mundo-plano.html">Por supuesto que ese momento no me d&#237; cuenta de lo que ocurr&#237;a porque estaba inmerso en &#233;l</a>.&#160; Para cuando me gradu&#233; de la carrera en 1998, &quot;eso del e-mail&quot; y de trabajar a distancia se hab&#237;a vuelto bastante com&#250;n.&#160; </p> <h3>Generaci&#243;n M</h3> <p>La M es de m&#243;bil, es decir un <em>pochismo deformado </em>m&#237;o de <em>mobile phones, </em>tambi&#233;n conocidos como tel&#233;fonos celulares.&#160; Esta es la generaci&#243;n que <em>en estos momentos </em>est&#225; en la adolescencia.</p> <p>Cuando comenc&#233; mi pl&#225;tica, abr&#237; con una pregunta: &quot;&#191;C&#243;mo ser&#237;a tu vida... sin tu celular?&quot;&#160; Hubieran visto la reacci&#243;n.&#160; Fue una exclamaci&#243;n colectiva de aut&#233;ntico horror: &quot;&#161;Ay NOOoooo!&quot;, jejeje. &quot;&#191;...sin Google? &#191;...sin el Internet? &#191;Qu&#233; m&#250;sica escuchar&#237;as? &#191;Qu&#233; ser&#237;a diferente?&quot;&#160; Y ya cuando hab&#237;an parado la oreja puse una diapositiva que dec&#237;a: &quot;As&#237; era el mundo hace apenas 15 a&#241;os&quot;.</p> <p>A veces creo que no se le ha dado cr&#233;dito a la impacto que han tenido los celulares&#8212;y s&#237;, yo tambi&#233;n considero que son odiosos y ojal&#225; no los hubieran inventado, pero pues ni modo ya ganaron.&#160; &quot;En mis tiempos...&quot;&#8212;como dicen los viejitos&#8212;los &#250;nicos que tra&#237;an celulares eran los narcos y la gente de muuuucha lana.&#160; Eran esos horrendos ladrillos Motorola que les duraba la pila una hora y pod&#237;an se utilizados como arma de defensa personal.</p> <p align="center"><img src="http://i110.photobucket.com/albums/n109/carlosrubalcava/screenshots/generacion_m_1.jpg" />&#160; </p> <p>Hoy en d&#237;a parece que los chavitos nacen con el celular en la mano.&#160; He visto ni&#241;os de 7 y 8 a&#241;os&#8212;entre ellos algunos de mis sobrinos&#8212;con celular propio, lo cual me parece absurdo, pero es la realidad.&#160; Todo tipo de vagancias y mal comportamiento es videograbado con su tel&#233;fono para subirlo a YouTube.&#160; Para ellos se ha convertido en una extensi&#243;n de su persona.&#160; Algunos de ellos incluso <em>se identifican </em>con su celular, lo cual es en verdad preocupante.&#160; </p> <p>Esto est&#225; ocasionando cambios interesantes.&#160; Por ejemplo, todos esos mensajitos de texto&#8212;y la flojera que causa tener que teclearlos, supongo&#8212;est&#225;n ocasionando cambios informales y deformaciones al espa&#241;ol escrito.&#160; Una conversaci&#243;n t&#237;pica podr&#237;a ser:</p> <p><em>&#8212;Ke rollo? <br />&#8212;No ps nada <br />&#8212;Vas a ir al cine vdd?</em></p> <p>Este tipo de deformaciones tambi&#233;n est&#225;n creciendo por el uso de mensajer&#237;a instant&#225;nea (Messenger, Google Chat, Skype, etc.).&#160; Cuando intento platicar con una de mis sobrinas por Messenger, a veces me dan ganas de darle un <em>sape</em> virtual y decirle: &quot;&#161;escriba bien, no sea payasa!&quot;, pero me las aguanto.&#160; Estos programas, tambi&#233;n los est&#225;n acostumbrando a que ahora se puede tener conversaciones de video o voz internacionales gratis o a muy bajo costo.&#160; En otras palabras, la dimensi&#243;n de la distancia comienza a cambiar.&#160; El mundo no solo es plano sino que comienza a encogerse.</p> <p>Una caracter&#237;stica m&#225;s que se me ocurre sobre la generaci&#243;n M es que, los chicos de ahora est&#225;n (&#191;mal?)acostumbrados a tener las cosas <em>on-demand,</em> es decir, cuando ellos quieren y como ellos quieren.&#160; Si quieren m&#250;sica, se van a iTunes, o BitTorrent o <em>&lt;inserte aqu&#237; la herramienta de pirater&#237;a de moda&gt;</em>, la bajan y listo; ya no est&#225;n limitados por la m&#250;sica de la radio o los discos en la tienda del <em>mall</em>.&#160; Si quieren un libro es cuesti&#243;n de pedirlo por Amazon o similares y obtenerlo.&#160; &#191;Aburrido? Solo &quot;prende&quot; YouTube y puedes perder horas enteras viendo todo tipo de tarugadas; ya no est&#225;n limitados a lo que ofrece la tele.&#160; La palabra clave, supongo, es opci&#243;n.&#160; Ahora tienen m&#225;s opciones que nunca.&#160; Lo cual quiz&#225; es bueno y malo a la vez.</p> <p align="center"><img src="http://i110.photobucket.com/albums/n109/carlosrubalcava/screenshots/generacion_m_2.jpg" /> </p> <p>Por otro lado tambi&#233;n se pueden observar una serie de cambios y situaciones sociales interesantes.&#160; Una de ellas me la apunt&#243; <a href="http://pelosbriseno.blogspot.com">Alex Brise&#241;o</a>: los hijos de los due&#241;os de muchas empresas est&#225;n comenzando a tomar las riendas.&#160; Es decir, un empresario que hoy tiene 50-60 a&#241;os y que puso su negocio propio ahora est&#225; d&#225;ndole el control a su hijos para que se hagan cargo.&#160; Estos &quot;hijos de due&#241;os&quot; son de la generaci&#243;n i, y no se sienten intimidados por la tecnolog&#237;a, lo que es m&#225;s, lo ven como algo favorable, algo que trae un valor agregado.&#160; Si alguna vez se han dedicado al negocio de vender &quot;sistemas&quot; se habr&#225;n quiz&#225; dado cuenta que con excepci&#243;n de empresarios con mucha visi&#243;n, la mayor&#237;a de la generaciones anteriores percib&#237;an esto como un costo, no como algo que les pudiera ayudar a ganar dinero.&#160; Los &quot;hijos de due&#241;o&quot;, sin embargo, no solo no tienen problema con esto, sino que <em>te buscan</em> para que les hagas un sistema.&#160; Eso a su vez comienza a cambiar la din&#225;mica de la competencia en muchos &#225;mbitos.</p> <p>Combinado con la maduraci&#243;n de la globalizaci&#243;n 2.0, el inicio de la 3.0 esto est&#225; permitiendo que los David comiencen a competir con los Goliat.&#160; <a href="http://www.wired.com/wired/archive/12.10/tail.html">La Cola Larga</a> est&#225; comenzando a esparcirse.&#160; Dos ejemplos locales son que en Cd. Ju&#225;rez, en los &#250;ltimos 6 u 8 meses, Cablem&#225;s comenz&#243; a competir con Telmex en telefon&#237;a; Volaris e InterJet, dos aerol&#237;neas de bajo costo comenzaron a competir con Aerom&#233;xico.</p> <p>Pero con todas las maravillas de la tecnolog&#237;a hay otra cosa que est&#225; ocurriendo: est&#225; creciendo la brecha digital, el <em><a href="http://en.wikipedia.org/wiki/Digital_divide">digital divide</a></em>.&#160; Es decir despu&#233;s de darte cuenta que el internet es maravilloso y que el acceso a la informaci&#243;n es una necesidad porque uno como <strong>individuo</strong> est&#225; compitiendo con personas de todo el mundo, la siguiente pregunta inevitablemente es &quot;&#191;y qu&#233; hay de los <u>millones</u> de mexicanos que a&#250;n viven en extrema pobreza? &#191;C&#243;mo sobreviviran en este nuevo mundo?&quot;</p> <p>Desgraciadamente no hay respuestas alentadoras.&#160; La &#250;nica manera de competir es a trav&#233;s de la educaci&#243;n <strong>y</strong> de ofrecer algo m&#225;s.&#160; En otras palabras, no competir en la maquilada de las cosas o de la informaci&#243;n&#8212;siempre habr&#225; mano de obra m&#225;s barata en un pa&#237;s m&#225;s desesperado&#8212;sino competir ofreciendo las cosas que requieren de m&#225;s coco, de m&#225;s intelecto. Seguro, un ingeniero hind&#250; o chino de sistemas promedio sale m&#225;s barato que yo, pero ninguno, de todos los que conozco y con los que he trabajado tiene la misma capacidad que yo.&#160; Y no es por ser arrogante, simplemente les ha faltado cayo y colmillo.&#160; No significa que no haya ingenieros competentes en otros pa&#237;ses, significa que esos ingenieros no son de bajo costo.&#160; Incluso eso est&#225; cambiando claro, al punto que <a href="http://www.eds.com/sites/cs/blogs/eds_next_big_thing_blog/archive/2008/04/07/will-india-be-still-viable-option-for-it-outsourcing-in-10-years.aspx">en 10 a&#241;os quiz&#225; estemos hablando de otros pa&#237;ses</a>.</p> <p>Esta es una realidad dif&#237;cil de aceptar.&#160; Aunque hay que mencionar que s&#237; hay algunas personas haciendo algo concreto al respecto.&#160; Proyectos como el de <a href="http://laptop.org/index.es.html">Una Laptop Por Ni&#241;o (OLPC)</a> est&#225;n tratando de atacar este tipo de problemas, pero la tecnolog&#237;a en s&#237; es una soluci&#243;n insuficiente.</p> <h3>Generaci&#243;n W</h3> <p>La W es de <em>wireless</em>.&#160; Esta generaci&#243;n ser&#237;an los hijos de la generaci&#243;n M, nacidos quiz&#225; unos 15 o 20 a&#24