Page 1

www.dotnetmania.com

nº 47 abril 2008 6,50 €

Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows Server System

dotNetManía dedicada a los profesionales de la plataforma .NET

Silverlight 2.0 ¡Revolución! Sustituyendo el editor de celdas del control DataGridView • El Marco de trabajo de entidades de ADO.NET v3.5 (IV) • Componentes de uso general. De contadores y trazas • Visual Basic solidario. Viejas costumbres, nuevas formas

entrevista Enrique Fernández-Laguilhoat Antonio Gómez David Salgado División de Desarrollo y Plataforma Microsoft Ibérica Comunidad.NET Second Nug TodotNet@QA Asegurarse de que las técnicas son compatibles con la aplicación Laboratorio.NET Crystal Reports 2008

Eventos Microsoft Tech-Days 2008. {The Evolution Show} y MIX 2008


editorial

dotNetManía Dedicada a los profesionales de la plataforma .NET Vol. III •Número 47 • Abril 2008 Precio: 6,50 €

Silverlight 2.0

Editor Paco Marín (paco.marin@netalia.es) Redactor jefe Marino Posadas (marino.posadas@netalia.es) Editor técnico Octavio Hernández (octavio.hernandez@netalia.es) Redacción Dino Esposito, Guillermo 'Guille' Som, Luis Miguel Blanco y Miguel Katrib (Grupo Weboo) Empresas Colaboradoras Alhambra-Eidos Krasis Plain Concepts Raona Solid Quality Mentors Además colaboran en este número Daniel Seara, Miguel Jiménez y Unai Zorrilla. Ilustraciones Mascota (Clico): Yamil Hernández Portada: Javier Roldán Fotografía Roberto Mariscal Atención al suscriptor Pilar Pérez (pilar.perez@netalia.es)

Edición, suscripciones y publicidad

.netalia c/ Thomas Edison, 4 Oficina 1406 Parque empresarial Rivas Futura 28521 - Rivas Vaciamadrid (Madrid) www.dotnetmania.com

Tf. (34) 91 666 74 77 Fax (34) 91 499 13 64 Imprime Gráficas MARTE

Bienvenido al número 47, de abril de 2008, de dotNetManía. Este mes entrevistamos, con Marino Posadas de maestro de ceremonias, a tres de las cabezas visibles de Visual Studio 2008 en Microsoft Ibérica: Enrique Fernández-Laguilhoat, director de la división de Desarrollo y Plataforma, Antonio Gómez, jefe de producto de Visual Studio y David Salgado, de la división de Desarrollo y Plataforma, que nos aportan su opinión sobre Visual Studio 2008 desde el punto de vista del negocio, de los equipos de trabajo y de los desarrolladores, respectivamente. La entrevista se realizó durante la celebración del mayor evento de presentación realizado por Microsoft Ibérica hasta la fecha: Microsoft TechDays. {The Evolution Show}, que con más de 3.000 asistentes y un espectacular despliegue de medios, sirvió para presentar Visual Studio 2008, SQL Server 2008 y Windows Server 2008. Le contamos los detalles sobre ese evento en este número, junto con una magnífica crónica de Miguel Jiménez sobre el MIX ‘08, celebrado en Las Vegas. Un evento cargado de novedades, como la presentación del nuevo Internet Explorer 8 (ahora en fase beta 1), la beta de Blend 2 y toda la gama de Expression Studio 2.0 y la presentación de las primeras CTP de Blend 2.5. Y cómo no, la presentación de Silverlight 2.0, del que hacemos una extensa introducción en el artículo de portada de este mes. Braulio Díez y Reyes García se encargan de esta presentación con el

artículo “Silverlight 2.0: ¡Revolución!”. A partir de ahora seguiremos publicando sobre el tema, pero ésta será la única introducción. Legiones de desarrolladores de la plataforma .NET, aliados con diseñadores, se disponen a desarrollar espectaculares aplicaciones Web con Silverlight 2.0. Con este número, ofrecemos también un póster desplegable de referencia para los desarrolladores de Silverlight, que se entregó en MIX ‘08. Aprovecho para dar la bienvenida a Solid Quality Press, una nueva editorial especializada en tecnologías Microsoft. Este mes recomendamos su primer libro, que se edita en formato electrónico y para el que han concedido un 50% de descuento a los lectores de dotNetManía. Gracias y suerte. No quiero terminar sin destacar el gesto de Guille, que desde su Isla VB quiere apoyar a Juanma y a su familia, aportando sus honorarios y un llamamiento público a la ayuda para este niño de cuatro años que padece el Síndrome de Alexander. Pienso que en cualquier actividad, especialmente en las empresariales y profesionales, no podemos olvidarnos de quienes sufren. A veces un pequeño gesto puede cambiar vidas, y sabiendo esto, es difícil no hacer nada. Ojalá y este gesto le sirva a Juanma y anime a alguien a echar una mano y a otros autores a sumarse a las iniciativas solidarias que consideren, y que desde dotNetManía hemos apoyado desde siempre. Por supuesto, dentro hay más. Espero que le guste.

ISSN 1698-5451

Paco Marín

<< dotNetManía

Depósito Legal M-3.075-2004

3


sumario 47 Eventos

06-09

Microsoft Tech-Days 2008. {The Evolution Show}. MIX 2008.

Entrevista a Enrique Fernández-Laguilhoat,Antonio Gómez y David Salgado

10-13

Nos encontramos en una sala de prensa del Palacio de Congresos y Exposiciones de Madrid, para charlar con tres de las cabezas visibles de Visual Studio 2008 en Microsoft Ibérica, y que a su vez representan los tres enfoques de interés que pueden tener los lectores de dotNetManía en este producto: Enrique Fernández-Laguilhoat, director de la división de Desarrollo y Plataforma, que nos hablará del producto desde un punto de vista estratégico; Antonio Gómez, Jefe de producto de Visual Studio, que nos hablará sobre el impacto del nuevo producto de cara a los responsables de proyectos; y David Salgado, de la división de Desarrollo y Plataforma, quien nos dará la visión más técnica de las nuevas capacidades que presenta esta nueva versión del entorno integrado. P

Sustituyendo el editor de celdas del control DataGridView

14-20

La edición de valores alfanuméricos en las celdas de un DataGridView para Windows Forms es una operación que podemos llevar a cabo gracias a que este control, cada vez que vamos a modificar una celda, aloja en la misma un cuadro de texto para editar su valor. Sin embargo, con ciertos tipos de datos, lo deseable sería disponer de un control específico para su edición. La arquitectura del DataGridView, aunque no ofrece de modo directo esta característica, permite al programador desarrollarla, por lo que a lo largo del presente artículo desvelaremos los puntos clave a tratar para lograr este objetivo.

El Marco de trabajo de entidades de ADO.NET v3.5 (IV)

22-26

En nuestras entregas anteriores hemos venido presentando los diferentes mecanismos que ofrece el Marco de entidades de ADO.NET 3.5 para permitir la creación y subsiguiente explotación de modelos conceptuales mapeados sobre modelos relacionales de bases de datos. En esta entrega continuaremos explorando esos mecanismos.

Silverlight 2.0: ¡Revolución!

27-34

Silverlight 2.0 es la palabra de moda. Seguro que, aun estando en beta, ha escuchado algo acerca de esta tecnología en los últimos meses… En este artículo veremos qué hace de la versión 2.0 un producto tan esperado, cómo se desarrolla con él y cómo integrarlo en nuestras aplicaciones Web.

Componentes de uso general. De contadores y trazas

36-40

Siguiendo con la serie de componentes de múltiples usos, veamos cómo crear nuestros propios contadores y definir trazas, lo cual nos permitirá identificar aquellas situaciones que puedan provocar dolores de cabeza cuando toda la aplicación esté en uso.

Visual Basic solidario.Viejas costumbres, nuevas formas.

42-46

No, no es que a Microsoft le haya dado por crear una nueva versión de Visual Basic que se solidarice con la humanidad. Pero el que escribe quiere que los lectores de esta “Isla VB” sí se solidaricen, y esa solidaridad solo la pueden demostrar actuando. ¡Espero que actúen!

dnm.todotnet.qa Asegurarse de que las técnicas son compatibles con la aplicación

48-50

dnm.laboratorio.net

51-54

Crystal Reports 2008

dnm.biblioteca.net

55

Novedades de Visual Basic 9.0 C# 3.0 Cookbook

dnm.comunidad.net

56-57

Second Nug. Grupo de usuarios de .NET Online

dnm.desvan

58


eventos

eventos

Microsoft Tech-Days 2008 { The Evolution Show}

<<

Se habló de más de 3000 personas inscritas en el que ha sido el evento con mayor éxito organizado por Microsoft España en toda su historia, durante los pasados días 26 y 27 de febrero y con el lema “Nuestros protagonistas {Aquí. Y ahora}”. Los 30.000 m2 del Palacio de Congresos y Exposiciones de Madrid sirvieron de marco para una presentación de lujo de tres productos de lujo: Visual Studio 2008, SQL Server

2008 y Windows Server 2008. Microsoft cumplía además sus 20 años de implantación en España (el día 27, precisamente) y los asistentes pudimos asistir a varios tracks de presentaciones en paralelo sobre tecnologías de todo tipo que cubrieron tanto aspectos generales de las herramientas y sistemas que se presentaban, como otros bien específicos, impartidos por especialistas de Microsoft y otros conocidos evangelistas tecnológicos. Además, se impartieron laboratorios de trabajo (Hands-onLabs u HOL), donde los participantes pueden probar, de forma tutelada, las nuevas características de los productos presentados, y hubo sorteos, concursos de programación y zonas de recreo digital, que concluyeron con el concurso principal –en el Auditorio y presentado por Inma del Moral–, donde se regaló una motocicleta Harley-Davidson al afortunado ganador justo antes de dar paso una charla de Rosa Mª García, presidenta de Microsoft Ibérica, quien evaluó


<< dnm.directo.eventos –junto a los partners de platino– la situación de la tecnología en nuestros días y el impacto que se espera que estas novedades tengan en el próximo futuro. El evento concluyó con una conexión a Los Ángeles (CA-EE.UU.), para presenciar por videoconferencia la sesión en directo de un Steve Ballmer más comedido que nunca, consciente de que la audiencia no solo era norteamericana. En la zona de sponsors, se dieron cita empresas bien conocidas a nivel nacional e internacional, con más de 50 representaciones en los stands y zonas de “Pregunte a los expertos (Ask-The-Experts)”, presentaciones de productos, y una fiesta final, con grupo musical incluido, que sirvió para relajar tensiones. El interés del público en las sesiones fue más que notable, y era raro que –tras cada charla– no hubiera un rosario de preguntas añadidas para investigar más en las tecnologías, y especialmente, para pulsar las posibilidades de implantación que éstas tenían en cada caso particular. Se vieron demos espectaculares y también se habló de lo que se espera a lo largo del año en curso: Hyper-V, Silverlight 2.0, la solidez y nuevas ofertas de SQL Server 2008, y todo un rosario de tecnologías. Si el lector quiere, puede –a toro pasado– ver una gran oferta activa en el sitio Web creado para el evento: http://www.microsoft.com/spain/lanzamiento2008/default.mspx.

Texto: Marino Posadas Fotografía: Roberto Mariscal

En esta ocasión, casi 2000 personas se dieron cita en este evento de nuestro país vecino. Estructurado de forma similar al año pasado, aglutinaba, por así decirlo, dos eventos en uno: los Tech-Days y el Lanzamiento 2008, por lo que la temática y contenido de las ponencias era similar al que tuvimos ocasión de ver en Madrid a finales de febrero. Al igual que el año pasado, se alojaron en el Centro de Congresos de Lisboa hasta 9 tracks simultáneos, siguiendo un formato similar al utilizado en los Tech-Ed en todo el mundo, con la única diferencia de que aquí no se establece una separación entre los eventos de desarrollo y los de IT Pros. La mayoría de los profesionales portugueses tuvieron ocasión de impartir charlas especializadas, y encontramos muchas caras conocidas, como Paulo Morgado, Luis Silva, Eurico Soalheiro, Tiago Pascoal, Jose Antonio Silva o Miguel Caldas, quien abrió el Vista parcial de la sala durante la conferencia sobre evento con su keynote. Pero también había que destacar presencia extranjera: Stephen ForSyndicate Client Experiences con Marino Posadas. te, Bart De Smet, Beat Schwegler, Raymond Chen, Robertjan Tuit, Jan Blomquist, Rob Miles, Matt Gibbs y nuestro redactor jefe, Marino Posadas (Solid Quality Mentors), único representante español, quien en esta ocasión habló sobre las “Características arquitectónicas y prácticas del SDK de construcción de lectores de noticias”, ahora denominado Syndicate Client Experience (SCE) Starter Kit. Además de las charlas, se impartieron varios laboratorios (Hands-on-Labs) y pudimos contar con áreas de colaboración y esparcimiento, donde –como siempre– la XBOX se llevó la palma. Desde el punto de vista comercial, la zona de expositores estuvo más animada, si cabe, que el año pasado, con una completa representación portuguesa e internacional. Finalmente, queremos expresar nuestro agradecimiento a Nuno Costa y Sergio Martinho de Microsoft, por todas las atenciones para con nosotros.

<<dotNetManía

Microsoft Tech-Days 2008 en Lisboa

7


eventos

eventos

MIX 2008

<<

Es casi media noche y desde el norte de Nevada ya se vislumbra el resplandor de la ciudad del pecado. En escasas millas llegaremos, un año más, a Las Vegas para asistir a la edición de este año de 2008, donde Microsoft planea sorprendernos con los últimos bits y técnicas en el mundo de la Web, la experiencia de usuario y el diseño. Esto es lo primero que pensé mientras conducía camino al The Venetian, el hotel donde se celebra anualmente el MIX, tras un mini road-

trip por tierras americanas donde recorrimos parte de California, Nevada y Arizona. Es lunes 3 de marzo de 2008 y el show está a punto de comenzar. Al llegar al hotel nos reencontramos con el destacamento de Microsoft Ibérica, formado por Enrique Fernández-Laguilhoat y Carlos Oramas, que nos acoge en la ciudad, proporcionando la ayuda necesaria a todos los newbies que llegan desde la tierra de Cervantes. A las ocho de la mañana del martes comienzan las sesiones y las presentaciones, en esta ocasión un evento paralelo denominado Together @ MIX’08, que aúna representantes de varios países. Para una audiencia claramente europea, Hans Verbeck y Carrie Longson, representantes de DPE TimeZone (antiguo Microsoft DPE EMEA), introducen los paneles que se sucederán durante la mañana y las actividades de la tarde. Durante aproximadamente cinco horas contamos con diferentes sesiones de pre-conferencia, donde vimos las novedades en Surface, Blend, Silverlight y WPF de la mano de importantes representantes de Microsoft. Durante la tarde se organizaron diferentes actividades para conseguir que los asistentes al Together, alrededor de doscientas personas, se relacionasen, discutiesen y se crease ese ambiente especial de “mezcla” que es el MIX en sí mismo. Entre las actividades selec-


cionadas se realizaron excursiones a las montañas rusas de la Stratosphere Tower, un paseo a caballo por el desierto del oeste americano en el Red Rock Canyon, una introducción al gambling en un casino de Las Vegas y una guía de compras por las mejores tiendas de diseño de la ciudad. Sin duda, una oportunidad única de conocer al resto de asistentes.

con IE8, entre ellas Google Maps (y no porque renderice incorrectamente, sino porque muchos de los desarrolladores Web incluían en sus hojas de estilo hacks para Internet Explorer que ya no son necesarios y lo que conseguirían en este caso es romper el layout), y por ese motivo se ha incluido la opción de renderización “Compatible con IE7” de for-

IronPython como lenguajes de programación. Esto presenta un modelo de desarrollo completamente nuevo, pues el DLR (que no es más que una extensión dinámica de un subconjunto del CLR de .NET) es capaz de ejecutarse en múltiples plataformas y navegadores, incluidos OSX, Vista y Linux gracias a Moonlight.

Comienza la mañana del miércoles 5 de marzo y el jetlag nos impide dormir más tarde de las siete. Nos preparamos para desayunar en el recién inaugurado MIX’08 y buscar un buen sitio para la keynote de apertura. Un discurso de Ray Ozzie nos presenta la visión de la compañía y las cinco divisiones en las que se centran todos los esfuerzos; sin duda una buena introducción de negocio para los asistentes menos techies, que en breve quedarán eclipsados por las palabras de Scott Guthrie. Para empezar, se presenta en público por primera vez Internet Explorer 8 y se pone a disposición de los asistentes la beta 1 en el centro de descargas; las principales mejoras incluyen WebSlices, Activities y un nuevo modelo de renderización basado en los estándares publicados por el W3C junto a soporte completo de CSS 2.1 completamente reescrito. El nuevo modelo de renderización hace muchas páginas que se visualizaban correctamente en IE7 incompatibles

ma que se pueda minimizar el impacto visual hasta que se corrijan las hojas de estilo en los sitios afectados. Las otras dos novedades importantes en IE, WebSlices y Activities, presentan un nuevo paradigma de interacción online y offline en la Web junto a un pequeño SDK para poder desarrollar nuevos elementos de manera rápida con una especie de manifiestos en XML. Por otro lado, se han integrado diferentes herramientas para desarrolladores (existentes como complementos actualmente) y un depurador de JavaScript bastante interesante. Con respecto a Silverlight, se presentó la nueva versión 2.0 y el nuevo conjunto de herramientas compatibles: plug-ins para navegadores, extensiones para Visual Studio, proyectos para Blend. Entre las novedades incluidas en Silverlight 2.0 destaca por encima de todas la eliminación de JavaScript y la integración a través del Dynamic Language Runtime (DLR) de C#, VB.NET, JScript, IronRuby o

Durante la keynote se presentaron numerosas aplicaciones desarrolladas con la última versión tanto de Silverlight como de WPF, entre otras las de NetFlix y Cirque du Soleil. Pero sin duda, otro de los platos fuertes presentados durante el MIX’08 fue la entrada en beta de Blend 2 y toda la gama de Expression Studio 2.0; la presentación de las primeras CTP de Blend 2.5 y la introducción, porque fue extremadamente breve, de las novedades en cuanto a rendimiento y funcionalidad que se incluirán en la revisión 3.9 del .NET Framework. Sin duda, un evento cargado de novedades interesantes desglosadas en los 3 días de sesiones y actividades incluidas. Nos vemos el próximo 2009 en Las Vegas. Happy coding 2.0.

Texto: Miguel Jiménez Fotografía: José Carlos Palencia

<<dotNetManía

<< dnm.directo.eventos

9


entrevista

Marino Posadas

entrevista a

Enrique Fernández-Laguilhoat, Director de la división de Desarrollo y Plataforma

Antonio Gómez Jefe de producto de Visual Studio

Marino Posadas es director de tecnologías de desarrollo para España y Portugal de Solid Quality Mentors. Puedes leer su blog en http://www. elavefenix.net.

y

David Salgado División de Desarrollo y Plataforma

Nos encontramos en una sala de prensa del Palacio de Congresos y Exposiciones de Madrid, para charlar con tres de las cabezas visibles de Visual Studio 2008 en Microsoft Ibérica, y que a su vez representan los tres enfoques de interés que pueden tener los lectores de dotNetManía en este producto: Enrique Fernández-Laguilhoat, director de la división de Desarrollo y Plataforma, que nos hablará del producto desde un punto de vista estratégico; Antonio Gómez, Jefe de producto de Visual Studio, que nos hablará sobre el impacto del nuevo producto de cara a los responsables de proyectos; y David Salgado, de la división de Desarrollo y Plataforma, quien nos dará la visión más técnica de las nuevas capacidades que presenta esta nueva versión del entorno integrado. Por razones operativas, comenzamos charlando con Antonio Gómez.


Quería que nos comentaras cuál es el impacto que puede tener la salida de VS2008 haciendo, si quieres, una comparativa con lo que pasó con VS2005 y qué es lo que aporta la nueva versión (pues hay gente que opina que es un remake), fundamentalmente desde el punto de vista de las personas que toman decisiones a la hora de abordar los desarrollos y que deciden cuál es la tecnología a usar. Con Visual Studio 2005 ofrecimos una primera versión de lo que era un producto destinado a cubrir todo el ciclo de vida del desarrollo de software, empezando a identificar los distintos roles; era la primera versión de un ALM, y nuestra primera solución integral para empresas o equipos de desarrollo. Anteriormente,

(muchos no identifican ese rol, pero nosotros sí hemos visto que es importante). Visual Studio 2005 fue la primera versión, y entre esa versión y esta segunda median tres años de desarrollo intenso, que se reflejan en múltiples aspectos, desde la mejora de la cobertura a los distintos roles hasta las nuevas características incorporadas a Team Foundation Server, que nos permiten ofrecer una solución bastante más modular que con Visual Studio 2005. Pero en general Visual Studio 2008 no puede considerarse una major release en lo que a desarrollo en equipos se refiere. Eso está previsto para el año que viene (2009), en el que veremos la próxima versión de Visual Studio Team System, conocida por el momento por el nombre en código Rosario.

De izquierda a derecha: Marino Posadas, Enrique Fernández-Laguilhoat y David Salgado

los equipos de desarrollo utilizaban Visual Studio .NET 2003 con las versiones más altas que tenían, pero a la hora de trabajar en equipo no había distinción entre los diferentes roles: todos eran desarrolladores. Tal y como han evolucionado las tecnologías de desarrollo de software, los fabricantes hemos estandarizado los roles del mundo del desarrollo. Tenemos analistas, arquitectos, jefes de proyectos, testers y profesionales de bases de datos

Con relación a esa cobertura para todos los roles de la que hablas, ¿sigue estando Visual Studio 2008, en tu opinión, más enfocado al rol del developer/tester, o podríamos decir que ya cubre en un porcentaje igual a todos los personajes que intervienen en el ciclo de vida? Con cada nueva versión de Visual Studio vamos tendiendo hacia una solución que cubre más completamente cada uno

de los roles. Por supuesto, el rol de desarrollador es en el que venimos trabajando desde hace 10 años, y la cobertura para lo que hoy conocemos como team developer es excelente. Últimamente han mejorado muchísimo las posibilidades que el producto ofrece para el rol del profesional de bases de datos. Otras áreas, como la de testing o la de arquitectura, continúan madurando, y son áreas que seguramente se verán reforzadas en Rosario. La percepción que se tiene cuando se habla de Team System es que se habla como de dos propuestas: una que es la de Team System para CMMI y la otra, más centrada en las tecnologías ágiles. ¿Es eso una elección para el usuario o hay algo más detrás de esa oferta, a la hora de decidir el ciclo de vida a abordar? Nosotros nos estamos basando en los estándares definidos por el mercado; es decir, un estándar como CMMI pasa de ser una metodología o una serie de prácticas a convertirse en un estándar, en nuestro ISO del desarrollo. Sobre todo las grandes organizaciones, que acometen grandes proyectos, lo requieren. Microsoft no podía dejar de soportar las prácticas y mejoras que necesitaba ese modelo. Actualmente cubrimos CMMI hasta el nivel 3 de la especificación oficial. Por otra parte, también apoyamos las metodologías ágiles, como SCRUM, y lo que nosotros indicamos a nuestros clientes es que es cada uno quien tiene que elegir qué metodología quiere utilizar, dependiendo de las características del proyecto o de las personas de que disponga. Esto abre todo un abanico de posibilidades. ¿Sería una cuestión de envergadura de proyecto? Yo creo que es un requisito del cliente final, que “pesa” más que el proyecto en sí. Otro elemento a tener en cuenta es que muchas empresas van a empezar a exigir estos estándares, y todas las software factories que tenemos en España (se crea prácticamente una cada mes) quieren subirse al carro de CMMI 5 o tener ese nivel en cada uno de sus equipos y en cada uno de sus proyectos, porque hay software factories que pueden tener miles de per-

<<dotNetManía

<< dnm.directo.entrevista

11


<< dnm.directo.entrevista sonas en sus equipos de desarrollo. La complejidad de los proyectos por supuesto influye en la elección del cliente, pero lo que no podemos es estar nunca fuera de esa elección… El siguiente tema relacionado con esto es que, aunque el producto presenta una oferta ALM, para la adopción de esa oferta tengo que ver –si soy responsable de un equipo de desarrollo– hasta qué punto a mis empleados les va a resultar fácil de adoptar. MSDN siempre ha sido muy cuidadoso en que las ayudas de Visual Studio sean bastantes amplias, pero quizás para un aprendizaje de metodologías no baste una ayuda online…

<<dotNetManía

Antonio Gómez

12

No todo va en MSDN online; tenemos lo relacionado con MSF, que son una serie de plantillas que facilitan todo el proceso de desarrollo y que tú puedes utilizar como guías cuando desarrollas un proyecto… A casi todo el que pasa un curso serio de introducción a CMMI, cuando sale del curso después de tres o cuatro días, no le duele la cabeza: le duele el cerebro. Es decir, es algo que puede ser bastante duro a la hora de implantarlo. Por un lado, tienes la metodología y las herramientas, y por otro lado a las personas, y si éstas no siguen la metodología ni comprenden las herramientas, ahí es donde se presentan los problemas. Está claro que tenemos que tener gente preparada a nivel teórico, con unas herramientas que te permitan hacerlo (y nosotros las tenemos), y unas plantillas, en la parte de MSF, que te hagan

seguir patrones y no perderte en el devenir de una metodología compleja como puede ser CMMI. En ciertos casos, una metodología ágil puede llegar a hacerse compleja, dependiendo de qué roles intervengan y cuánta gente metamos... Bien, pues damos paso a Enrique Fernández-Laguilhoat… En la introducción decíamos que tenemos tres tipos de lectores: el jefe de proyecto, que será el que atienda al mensaje que nos ha transmitido Antonio; el que toma decisiones, que estará más interesado en el mensaje que nos des tú; y el que programa, que será el que se interese más por lo que nos comente David después. Así que si quieres pasar a introducir el tema… Desde el punto de vista del que toma decisiones, que es el que patrocina el desarrollo, el que lo está pagando, yo creo que incorporamos nuevas funcionalidades que son muy interesantes y que permiten que los equipos de desarrollo no estén desvinculados de la gente de negocio. El esfuerzo que se ha hecho en Visual Studio 2008 en la parte de reporting, por ejemplo, es extremadamente crítico, y las conexiones que estamos abriendo con productos como Project o Project Server permiten empezar a generar una serie de informes que entienden mucho mejor personas de negocio, que no son técnicos; son informes más de evolución de proyectos, de costes y demás. Y éste es un gran avance… Ahí vamos al meollo de la cuestión. Tú has dicho costes, entonces la pregunta sería: ¿cuál va a ser el ROI para la gente que empeña su palabra diciendo “vamos a usar esta tecnología” esperando que después se produzca el retorno de la inversión? Pues mira, me decía un cliente que ésta es una funcionalidad que no estamos vendiendo y que no le estamos dando la visibilidad que merece; es justamente la conexión con el concepto de Project. Cualquier empresa presente en este evento tiene gente que es capaz de manejar Project como una herramienta no solo de gestión de recursos, tiempos y demás, sino también como una herramienta de ges-

Enrique Fernández-Laguilhoat

tión económica. El hecho de que podamos trasladar el proceso de desarrollo de software a este entorno es una novedad de enorme importancia, que puede incidir en muchos aspectos como el control de costes, la gestión de los retrasos y sus implicaciones o la redistribución de los recursos. …como recomienda MSF. Efectivamente. La novedad es esta integración que antes no existía, no era nada evidente. Por primera vez ahora estamos en condiciones de dar una herramienta que entiende más gente de negocio, que habla más en términos de recursos, de dinero, etc. ¿Cuál es el nivel de implantación esperado? Supongo que tendréis cifras de esto… Mira, a nivel de ALM las cifras nos ha sorprendido gratamente. Sabes que empezamos a incorporar estos recursos en Visual Studio 2005, y en este momento, más de la mitad de nuestras ventas han pasado al concepto de desarrollo en equipo. Yo no me esperaba un despegue tan fuerte; pensé que seguiríamos vendiendo mucho la versión Professional, o sea, el entorno de desarrollo único, pero no una migración tan rápida. De hecho, las cifras apuntan en la dirección de que, sobre todo en la gran cuenta o grandes empresas de desarrollo, se está adoptando el conjunto de herramientas Visual Studio Team System y Team Foundation Server de una forma extremadamente rápida. Eso quiere decir que lo estamos haciendo bien, que el producto es muy bueno, y la ver-


dad es que muchos clientes nos lo están diciendo. Esta mañana, en mi charla, decía: “si usted tiene la suerte de ser un desarrollador único y usted es el tester, pues es una bendición”. Pero, la realidad es que hay mucha gente involucrada en los proyectos y esa es nuestra realidad… Antes de pasar al desarrollo puro con David, ¿quieres decirnos alguna cosa más? El mensaje es que yo –como persona de negocio–, por fin controlo. Y no solo controlo, sino que también puedo estar atento a ciertas alertas cuando un proyecto se está desviando, y que además se termine con esa situación “antagónica” que había antes entre el que pagaba la aplicación, la persona de negocio, y el equipo de desarrollo. Ahora somos un equipo y, como tal, tomamos decisiones juntos. Yo creo que ése es el gran cambio y en esa dirección vamos. Permíteme por último que me vaya al otro extremo, al diseñador, el que le pone la “cara bonita” a las aplicaciones, un rol muy independiente y que en el mundo Microsoft también les involucramos, porque son fundamentales. La interfaz de usuario es cada vez más importante para los clientes, y la interacción adecuada entre diseñadores y desarrolladores cada vez más necesaria. Ahora por primera vez, con una serie de tecnologías perfectamente compatibles, Visual Studio del lado del desarrollo y Expression del lado de diseño, se extiende ese concepto de equipo. Al final, el objetivo de Microsoft es que se produzca software de más calidad en menos tiempo: ése es nuestro objetivo. David, como programador, ¿qué destacarías tú? Destacaría lo mismo que han comentado tanto Enrique como Antonio, y es que apoyamos por todas las vías posibles la creación de software de calidad, no importa si se trata de un gran proyecto o de uno pequeño creado por un desarrollador individual. Al final, la herramienta te ayuda en diferentes niveles: en el caso del desarrollador individual, también vamos a tener la posibilidad de crear un código de más calidad de una manera más

productiva: mi código se podrá beneficiar del testeo unitario, de la capacidad de depuración mejorada, de la disponibilidad de ayuda Intellisense para los tipos dinámicos que se van generando… Es otra manera más operativa de generar código de calidad. Entonces yo creo que estamos alineados, en diferentes niveles. Aparte de estas mejoras que has mencionado ¿podrías decirnos más, hasta tener un top 10 de las mejoras que aporta Visual Studio 2008?

David Salgado

La cantidad de mejoras incorporadas en esta versión es enorme. Puedo mencionarte rápidamente algunas, como las mejoras en el rendimiento (tanto del propio entorno como del código generado), la integración de WPF y WF para exponer servicios, las novedades en los lenguajes de programación o la integración de la capa de gestión de datos dentro de los lenguajes, donde podemos mencionar tecnologías tan importantes como LINQ o ADO.NET Entity Framework, una de las grandes promesas de la plataforma de datos de Microsoft. Realmente tendríamos que ir viendo las mejoras para cada uno de los tipos de proyectos que podemos acometer… Bueno, y el hecho de que existen nuevos tipos de proyectos, como por ejemplo Silverlight, ASP.NET 3.5 con AJAX integrado… Efectivamente, en el mundo del desarrollo Web tenemos por un lado AJAX integrado dentro de Visual Studio, y por

otro lado unos pequeños adelantos de lo que irá sacando en el futuro inmediato el grupo de producto, como las ASP.NET 3.5 Extensions Preview. Podemos utilizar WCF en entornos de confianza parcial, XBAP sobre Firefox… Hay un montón de novedades importantes. Con respecto a las nuevas capacidades de depuración, poder depurar hebras individuales es algo fundamental en múltiples situaciones, como cuando quieres hacer animaciones en WPF. Para poner eso en contexto, ayer lo que estábamos viendo durante mi charla era una aplicación que utilizaba varios hilos de ejecución. Con esta nueva versión podemos movernos por los diferentes hilos de ejecución, ponerle un nombre a cada uno para poder identificarlos, o ver la ejecución diferencial de cada uno de los hilos por colores. A la hora de depurar aplicaciones de múltiples hilos estas posibilidades son vitales. ¿Qué puedes decirnos respecto a los lenguajes? De LINQ ya hemos hablado mucho… LINQ ha sido, hasta cierto punto, la excusa perfecta para incorporar mejoras en los lenguajes. Personalmente, soy un enamorado de var, de la inferencia de tipos a la hora de declarar una variable (además conocí al chico que lo programó y me dijo “úsalo, que es maravilloso”). Me encantan las expresiones lambda y las propiedades automáticas, que permiten reducir la cantidad de líneas de código; todos los métodos extensores de los que ahora disponemos para el manejo de colecciones; me parece genial que por fin los programadores de Visual Basic tengan herramientas para refactorizar el código... Parece que tenemos una tendencia a ir hacia lenguajes con características funcionales. Creo que vamos a seguir tendiendo hacia eso; no sé si va a haber más cambios en C# en ese sentido, o si se potenciarán lenguajes como F#, pero ahora que también estamos entrando en temas de paralelismo, concurrencia, sistemas distribuidos, creo que veremos más características de lenguajes funcionales dentro del plataforma.

<<dotNetManía

<< dnm.directo.entrevista

13


plataforma.net

Luis Miguel Blanco

Sustituyendo el editor de celdas del control

DataGridView La edición de valores alfanuméricos en las celdas de un DataGridView para Windows Forms es una operación que podemos llevar a cabo gracias a que este control, cada vez que vamos a modificar una celda, aloja en la misma un cuadro de texto para editar su valor. Sin embargo, con ciertos tipos de datos, lo deseable sería disponer de un control específico para su edición. La arquitectura del DataGridView, aunque no ofrece de modo directo esta característica, permite al programador desarrollarla, por lo que a lo largo del presente artículo desvelaremos los puntos clave a tratar para lograr este objetivo.

El uso de controles alternativos para editar celdas

Luis Miguel Blanco es redactor de dotNetManía. Es consultor en Alhambra-Eidos.Ha escrito varios libros y decenas de artículos sobre la plataforma .NET. Consulta su blog: http://geeks.ms/blogs/ lmblanco

Si el valor del campo que necesitamos modificar está basado en texto simple, la funcionalidad estándar de este control es suficiente, pero ¿qué ocurre si nos enfrentamos a números o fechas? Para estos casos, otros controles como NumericUpDown, MonthCalendar, etc. seguramente serán más adecuados para estas labores de edición, si los incluimos en las celdas del DataGridView. Para conseguir esta funcionalidad, deberemos introducirnos en la maquinaria interna del control y realizar unos “pequeños ajustes”, con los cuales lograremos editar las celdas utilizando el control de nuestra elección. El ejemplo sobre el que centraremos aquí nuestra atención consistirá en la creación de una columna cuyas celdas albergarán valores numéricos, los cuales editaremos a través de un control Nume ricUpDown ubicado en cada celda que editemos.

vamos a escribir las declaraciones de las clases que van a constituir el esqueleto básico de esta arquitectura. El lector puede encontrar el código completo del ejemplo desarrollado para este artículo en la dirección http://www.dotnetmania.com. Dado que el objeto más inmediato que manipularemos será la columna del control de cuadrícula, crearemos una clase derivada de DataGridViewColumn. A continuación, procederemos igualmente con la celda, creando una clase que herede de DataGridViewTextBoxCell. Finalmente, crearemos una tercera clase, que constituirá el núcleo del proceso de edición, para lo cual deberá heredar del control que vayamos a utilizar para editar la celda (en nuestro caso, NumericUpDown ), e implementar la interfaz IDataGridViewEditingControl, cuyos miembros proporcionarán la funcionalidad necesaria que actuará de puente entre el control de edición y la celda que lo contiene. En el listado 1 se encuentran estas declaraciones.

Punto de partida: establecer la estructura de clases

La clase NumArribaAbajoColumn

En primer lugar, crearemos un proyecto Windows al que agregaremos un archivo de clase, en el cual

Esta clase, derivada de DataGridViewColumn, será la encargada de recabar toda la información necesa-


<< dnm.plataforma.net

using System.Windows.Forms; using System.Drawing; //.... class NumArribaAbajoColumn : DataGridViewColumn { //.... } class NumArribaAbajoCell : DataGridViewTextBoxCell { //.... } class NumArribaAbajoEditingControl : NumericUpDown, IDataGridViewEditingControl { //.... }

class NumArribaAbajoColumn : DataGridViewColumn { // campos private decimal nMaximo; private decimal nIncremento; private bool bSeparadorMiles; private int nPosicionesDecimales; //.... // en el constructor establecemos el tipo de celda // que utilizará esta columna public NumArribaAbajoColumn() : base(new NumArribaAbajoCell()) { // modo de ordenación de los datos this.SortMode = DataGridViewColumnSortMode.Automatic; } //.... // propiedades para configurar la celda cuando // editemos su valor mediante el control NumericUpDown public decimal Maximo { get { return nMaximo; } set { nMaximo = value; } }

Listado 1

public bool SeparadorMiles { get { return bSeparadorMiles; } set { bSeparadorMiles = value; } } public int PosicionesDecimales { get { return nPosicionesDecimales; } set { nPosicionesDecimales = value; } } //.... }

Listado 2

propiedad SortMode el valor Automatic de la enumeración DataGridViewColumnSortMode, lo que provocará que dicha ordenación se produzca automáticamente al pulsar sobre su cabecera.

La clase NumArribaAbajoCell Tras la columna, el paso lógico será la creación de la clase que represente a las celdas, heredando de DataGrid-

ViewTextBoxCell. El funcionamiento a

desempeñar por esta clase va a consistir en devolver información acerca de los tipos utilizados para editar la celda y su valor, para lo cual reemplazaremos respectivamente las propiedades EditType y ValueType de la clase base. Utilizaremos la propiedad DefaultNewRowValue para devolver el valor de la celda cuando sea creada una nueva fila en la cuadrícula.

<<dotNetManía

ria para configurar el control que alojaremos en la celda. Puesto que la columna es el medio de que dispone el programador para configurar el control contenido en la celda, crearemos en esta clase un conjunto de propiedades que se correspondan con las propiedades del control de edición. Dada la extensión del código de las clases utilizadas, en las páginas del presente artículo se ofrecen aquellas partes más importantes de las mencionadas clases, encontrándose disponibles en su totalidad en el enlace correspondiente al material de apoyo del artículo. En el listado 2, el lector puede ver una parte del código correspondiente a la columna. Fijémonos en el constructor de esta clase. Una columna necesita conocer el tipo que tendrá que usar a la hora de construir sus celdas; por lo tanto, invocamos aquí al constructor base, que recibe como parámetro una instancia de DataGridViewCell –más concretamente, de nuestra clase NumArribaAbajoCell–, derivada de DataGridViewTextBoxCell, que utilizará como plantilla en la creación del celdas. Por otra parte, para permitir la ordenación de la columna, asignamos a su

public decimal Incremento { get { return nIncremento; } set { nIncremento = value; } }

15


<< dnm.plataforma.net

Finalmente, escribiremos el método InitializeEditingControl, que se ocupará, como su nombre indica, de obtener una instancia del control a usar para editar la celda, así como de inicializar sus propiedades a partir de los valores que hemos pasado al objeto columna, al que accedemos mediante la propiedad OwningColumn. También controlaremos posibles problemas tales como la inexistencia de valores para la celda, o que el valor no se halle en el intervalo numérico permitido. Si se cumple alguna de estas condiciones, generaremos una excepción, asignando explícitamente un valor para la celda, como puede verse en el listado 3.

La clase que implementa IDataGridViewEditingControl proporcionará la funcionalidad necesaria que actuará de puente entre el control de edición y la celda que lo contiene

<<dotNetManía

La clase NumArribaAbajoEditingControl

16

Y llegamos por fin a esta clase, que como hemos mencionado anteriormente, es la que hace posible que, al heredar del control que especifiquemos, una instancia del mismo sea alojada en la celda para editar su valor. Adicionalmente, mediante la implementación de los miembros pertenecientes a la interfaz IDataGridViewEditingControl, podremos llevar a cabo

class NumArribaAbajoCell : DataGridViewTextBoxCell { // obtener el tipo de control utilizado para editar la celda public override Type EditType { get { return typeof(NumArribaAbajoEditingControl); } } // obtener el tipo de dato que es editado en la celda public override Type ValueType { get { return typeof(Decimal); } } // establecer el valor por defecto para una nueva celda public override object DefaultNewRowValue { get { return 0; } } // crear y alojar en la celda una instancia del control // utilizado para editar el valor de la celda public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle) { base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle); // obtener el control que usaremos para editar el valor de la celda NumArribaAbajoEditingControl ctlEditorCelda = (NumArribaAbajoEditingControl)DataGridView.EditingControl; // obtener el objeto columna propietario de la celda que vamos a editar NumArribaAbajoColumn colNumArribaAbajo = (NumArribaAbajoColumn)this.OwningColumn; // asignar valor a las propiedades del control editor ctlEditorCelda.Minimum = colNumArribaAbajo.Minimo; ctlEditorCelda.Maximum = colNumArribaAbajo.Maximo == 0 ? 100 : colNumArribaAbajo.Maximo; ctlEditorCelda.Increment = colNumArribaAbajo.Incremento == 0 ? 1 : colNumArribaAbajo.Incremento; ctlEditorCelda.ThousandsSeparator = colNumArribaAbajo.SeparadorMiles; ctlEditorCelda.DecimalPlaces = colNumArribaAbajo.PosicionesDecimales; ctlEditorCelda.UpDownAlign = colNumArribaAbajo.AlineacionFlechas; ctlEditorCelda.TextAlign = colNumArribaAbajo.AlineacionTexto; ctlEditorCelda.BackColor = colNumArribaAbajo.ColorFondo; // comprobar si el valor de la celda que debemos editar // está en el rango admisible por el control NumericUpDown if (this.Value == DBNull.Value) { ctlEditorCelda.Value = 0; } else { if (((decimal)this.Value >= ctlEditorCelda.Minimum) && ((decimal)this.Value <= ctlEditorCelda.Maximum)) { ctlEditorCelda.Value = (decimal)this.Value; } else { this.RaiseDataError(new DataGridViewDataErrorEventArgs( new Exception(


<< dnm.plataforma.net

} } } }

Listado 3

class NumArribaAbajoEditingControl : NumericUpDown, IDataGridViewEditingControl { // campos private DataGridView oDGV; private int nIndiceFila; private bool bValorCambiado = false; public DataGridView EditingControlDataGridView { get { return oDGV; } set { oDGV = value; } } public int EditingControlRowIndex { get { return nIndiceFila; } set { nIndiceFila = value; } } public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey) { // establecer las pulsaciones de teclado // que el control alojado en la celda podrá utilizar switch (keyData & Keys.KeyCode) { case Keys.Up: case Keys.Down: case Keys.Left: case Keys.Right: case Keys.Home: case Keys.End: return true; default: return false; } } protected override void OnValueChanged(EventArgs e) { bValorCambiado = true; this.EditingControlDataGridView.NotifyCurrentCellDirty(true); base.OnValueChanged(e); } //....

class NumArribaAbajoColumn : DataGridViewColumn { //.... private Color clrColorFondo; public Color ColorFondo { get { return clrColorFondo; } set { clrColorFondo = value; } } //.... } class NumArribaAbajoCell : DataGridViewTextBoxCell { //.... public override void InitializeEditingControl( int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle) { //.... ctlEditorCelda.BackColor = colNumArribaAbajo.ColorFondo; } //.... }

}

Listado 4

Listado 5

<<dotNetManía

string.Format(@”Valor {0} incorrecto. Rango admisible de valores de {1} a {2}”, this.Value, ctlEditorCelda.Minimum, ctlEditorCelda.Maximum)), this.ColumnIndex, this.RowIndex, DataGridViewDataErrorContexts.Display)); this.Value = ctlEditorCelda.Minimum;

varias acciones, tales como el acceso al control DataGridView que actúa como contenedor de la celda; la fila sobre la cual se va a realizar la edición; las operaciones de teclado que deberán ser manejadas por el propio control de edición en lugar de la celda contenedora, y un largo etcétera. Veamos una muestra en el listado 4. Cabe destacar, en el apartado visual de este control, que si asignamos un estilo a la columna que lo contiene, las propiedades de dicho estilo no se aplicarán directamente al control ubicado en la celda. La solución que a priori podríamos pensar en desarrollar consistiría en la creación, dentro de la clase columna, de las propiedades necesarias que posteriormente pasaríamos a la clase de la celda; esta última se encargaría de asignar

17


<< dnm.plataforma.net

las mencionadas propiedades al control en su método InitializeEditingControl. El listado 5 muestra esta situación aplicada a la propiedad BackColor. Sin embargo, existe un medio mucho más adecuado, creado ex profeso para que el control editor de la celda pueda obtener las propiedades que necesita del estilo asignado a la columna. Consiste en implementar el método ApplyCellStyleToEditingControl de la interfaz, que recibe un parámetro conteniendo el estilo perteneciente a la columna, del cual tomaremos aquellos valores que necesitemos para asignarlos a las propiedades del NumericUpDown alojado en la celda (ver listado 6).

class NumArribaAbajoEditingControl : NumericUpDown, IDataGridViewEditingControl { //.... public void ApplyCellStyleToEditingControl( DataGridViewCellStyle dataGridViewCellStyle) { // aplicar al control de edición // de la celda las propiedades // del estilo de la celda this.Font = dataGridViewCellStyle.Font; this.BackColor = dataGridViewCellStyle.ForeColor; this.ForeColor = dataGridViewCellStyle.BackColor; } //.... }

Listado 6

private void Form1_Load(object sender, EventArgs e) { //.... // eliminar columna original this.dataGridView1.Columns.Remove(“ListPrice”); // crear columna para edición personalizada NumArribaAbajoColumn colListPrice = new NumArribaAbajoColumn(); colListPrice.Name = “colListPrice”; colListPrice.DataPropertyName = “ListPrice”; colListPrice.HeaderText = “Precio producto”; colListPrice.Maximo = 3000; colListPrice.Incremento = 2; colListPrice.SeparadorMiles = true; colListPrice.PosicionesDecimales = 3; colListPrice.AlineacionTexto = HorizontalAlignment.Right; // crear estilo para la nueva columna DataGridViewCellStyle styEstilo = new DataGridViewCellStyle(); styEstilo.Alignment = DataGridViewContentAlignment.MiddleCenter; styEstilo.BackColor = Color.LightBlue; styEstilo.SelectionBackColor = Color.GreenYellow; styEstilo.SelectionForeColor = Color.Firebrick; styEstilo.Font = new Font(“Tahoma”, 10, FontStyle.Bold); // aplicar estilo a columna colListPrice.DefaultCellStyle = styEstilo; // agregar nueva columna al grid this.dataGridView1.Columns.Add(colListPrice); // modificar una celda, introducir un valor // mayor del rango soportado por el control de edición this.dataGridView1.Rows[2].Cells[“colListPrice”].Value = 3500; } private void dataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e) { MessageBox.Show(“Columna: “ + this.dataGridView1.Columns[e.ColumnIndex].HeaderText + “\n” + “Fila: “ + (e.RowIndex + 1) + “\n” + “Mensaje de error: “ + e.Exception.Message, “Error de edición de celda”); }

<<dotNetManía

Empleando la nueva columna en el DataGridView

18

Es momento de hacer uso práctico de todo el código que hemos desarrollado. Para ello, dentro del formulario del proyecto sobre el que estamos trabajando, añadiremos un control DataGridView, que rellenaremos con algunos campos de la tabla DimProduct, perteneciente a la base de datos AdventureWorksDW. En concreto, será el campo

Listado 7 ListPrice el que editaremos mediante

nuestra columna personalizada. Debido a que la consulta SQL que pasamos al DataGridView ya contiene el campo ListPrice, en primer lugar eliminaremos de la cuadrícula la columna que por defecto crea el control para este campo. A partir de dicho punto instanciaremos un objeto de nuestra jerar-

quía de clases, configurando las propiedades intrínsecas de la columna, pero también las correspondientes al control NumericUpDown de edición. Por otra parte, crearemos un estilo para la columna, cuyos valores veremos igualmente reflejados al editarla. Como paso final, asignaremos a una de las celdas un valor superior al rango


<< dnm.plataforma.net

Figura 1. Celda del DataGridView editada mediante un NumericUpDown

Alojando controles no directamente editables En la columna que acabamos de crear, el usuario puede introducir los valores en la celda utilizando las flechas del NumericUpDown, o bien tecleándolos directamente. Habitualmente, el comportamiento del control ubicado en la celda permite que su contenido sea editado, pero también es posible utilizar controles basados la selección de un valor, sin posibilidad de editarlo. Como ejemplo, tenemos la clase DataGridViewComboBoxColumn, perteneciente al propio .NET Framework. Pero el objetivo del presente artículo es la personalización de este aspecto del control DataGridView, por lo que podemos recurrir a desarrollar una columna cuyas celdas contengan un control con estas características, como puede ser MonthCalendar, el cual ofrece un calendario donde el usuario sólo puede seleccionar fechas, no existiendo la posibilidad de escribir su valor.

public class CalendarioMensualColumn : DataGridViewColumn { //.... } public class CalendarioMensualCell : DataGridViewTextBoxCell { //.... public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle) { base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle); CalendarioMensualEditingControl ctlEditorCelda = (CalendarioMensualEditingControl)DataGridView.EditingControl; CalendarioMensualColumn colCalendarioMensual = (CalendarioMensualColumn)this.OwningColumn; // guardar las coordenadas de la celda (fila y columna) ctlEditorCelda.EditingControlRowIndex = rowIndex; ctlEditorCelda.IndiceColumna = this.OwningColumn.Index; // guardar las dimensiones originales de la celda ctlEditorCelda.AlturaCelda = this.DataGridView.Rows[rowIndex].Height; ctlEditorCelda.AnchuraCelda = this.DataGridView.Columns[this.OwningColumn.Index].Width; // establecer nueva dimensión para la celda, // de forma que visualicemos el control editor al completo this.DataGridView.Rows[rowIndex].Height = ctlEditorCelda.Size.Height; this.DataGridView.Columns[this.OwningColumn.Index].Width = ctlEditorCelda.Size.Width; // comprobar la fecha a pasar al control de edición if (this.Value == DBNull.Value) { ctlEditorCelda.SelectionEnd = DateTime.Today; } else { ctlEditorCelda.SelectionEnd = (DateTime)this.Value; } }

<<dotNetManía

permitido por el control de edición, lo que nos permitirá que nuestra clase desencadene el evento DataError de la cuadrícula de datos en el caso de que editemos dicha celda. Todo ello lo vemos en el listado 7. La figura 1 muestra el control en pleno proceso de edición.

Por cuestiones de espacio no es posible ofrecer el código al completo para esta nueva columna personalizada, aunque como ya hemos mencionado, todo el código tratado en este artículo puede ser descargado del sitio Web de la revista. Dado que MonthCalendar es un control que al ser alojado en las celdas de una columna ocupará un mayor espacio en el momento de la edición, tendremos que realizar los cálculos oportunos que nos permitan aumentar las dimensiones de la celda sobre la que se produzca la edición del valor, restaurando la celda al tamaño inicial una vez concluida la operación, como vemos en el listado 8.

19


<< dnm.plataforma.net

En la clase CalendarioMensualEditingControl declaramos un conjunto de

} public class CalendarioMensualEditingControl : MonthCalendar, IDataGridViewEditingControl { // campos //.... private int nIndiceFila; private int nIndiceColumna; private int nAlturaCelda; private int nAnchuraCelda; //.... // propiedades particulares public int IndiceColumna { get { return nIndiceColumna; } set { nIndiceColumna = value; } } public int AlturaCelda { get { return nAlturaCelda; } set { nAlturaCelda = value; } } public int AnchuraCelda { get { return nAnchuraCelda; } set { nAnchuraCelda = value; } } // métodos reemplazados //.... protected override void OnLostFocus(System.EventArgs e) { base.OnLostFocus(e); // restaurar celda a su tamaño original oDGV.Rows[nIndiceFila].Height = nAlturaCelda; oDGV.Columns[nIndiceColumna].Width = nAnchuraCelda; } //.... }

propiedades para almacenar la posición y tamaño de la celda. Estas propiedades las emplearemos en el método CalendarioMensualCell.InitializeEditingControl, cuando el control de edición sea

creado. Para detectar el momento en el que el usuario termina de editar el control, reemplazaremos el método OnLostFocus en la clase derivada de MonthCalendar, dentro del cual devolveremos la celda a su tamaño original. El listado 9 muestra la creación en el formulario de un objeto correspondiente a esta nueva columna personalizada.

// eliminar la columna previa this.dataGridView1.Columns.Remove( “EndDate”); // crear columna personalizada para // el campo EndDate CalendarioMensualColumn colEndDate = new CalendarioMensualColumn(); colEndDate.Name = “colEndDate”; colEndDate.DataPropertyName = “EndDate”; colEndDate.HeaderText = “Fecha final”; colEndDate.MostrarFechaActual = false; colEndDate.MostrarNumerosSemana = true; this.dataGridView1.Columns.Add( colEndDate);

Listado 8 Listado 9

La figura 2 muestra el control DataGridView editando este nuevo tipo de celda que acabamos de crear.

<<dotNetManía

Vamos concluyendo

20

Figura 2. Columna para editar fechas mediante un control MonthCalendar.

Esperamos que las capacidades de extensión del control DataGridView, en los aspectos de creación de columnas personalizadas expuestos en este artículo, hayan despertado el interés del lector, animándole a desarrollar sus propias columnas para resolver aquellos aspectos concretos no disponibles “de serie” en este control. Un saludo a todos.


Unai Zorrilla Octavio Hernández

plataforma.net

El Marco de trabajo de entidades de ADO.NET v3.5 (IV) En nuestras entregas anteriores hemos venido presentando los diferentes mecanismos que ofrece el Marco de entidades de ADO.NET 3.5 para permitir la creación y subsiguiente explotación de modelos conceptuales mapeados sobre modelos relacionales de bases de datos. En esta entrega continuaremos explorando esos mecanismos.

Unai Zorrilla es Development Team Leader de Plain Concepts y tutor de campusMVP. MVP desde 2004, colabora activamente con Microsoft en eventos de arquitectura y desarrollo, así como en giras de productos. Autor del libro "Modelando procesos de negocio con Workflow Foundation". Octavio Hernández es Mentoring Team Leader de Plain Concepts, editor técnico de dotNetManía y tutor de campusMVP. Es MVP de C# desde 2004, MCSD y MCT. Autor del libro "C# 3.0 y LINQ".

Si bien en entregas anteriores [2, 3] mostramos las diferentes formas de mapear en el Marco de entidades uno de los conceptos fundamentales del diseño orientado a objetos, la herencia, a partir de esta entrega presentaremos los recursos que ofrece el Marco de entidades para reflejar otra de las dependencias comunes entre clases, la agregación o composición, centrándonos inicialmente en el caso de relaciones 1:1 en las que el atributo (la parte del todo) es de un tipo complejo (compuesto). El ejemplo típico de esta situación es el de la relación entre un Cliente y su Dirección, ésta última concebida como el conjunto de elementos tales como calle, número, población, código postal, etc. En un sistema orientado a objetos, indudablemente nos interesaría tener dos entidades bien diferenciadas; en el mundo de las bases de datos relacionales, este tipo de relaciones se representa generalmente de una de dos maneras diferentes: a) “Aplanando” los datos de la dirección, y colocando sus diferentes campos al mismo nivel que otros atributos “independientes” del cliente, como el código o el nombre (figura 1). b) Situando los datos de la dirección en una tabla complementaria, a la que se añade una clave foránea (que puede servir como clave primaria también) para establecer la

relación con el cliente correspondiente (figura 2). Como mostraremos a continuación, el Marco de entidades de ADO.NET hace posible establecer los mapeos necesarios en ambos casos, de modo que podamos trabajar al nivel de modelo conceptual guiándonos siempre por la regla “un cliente tiene una dirección”. Si quiere seguir el proceso con nosotros, cree en este momento una aplicación de consola que servirá para alojar los modelos. Deberá instalar la base de datos DNM_EF4, que puede descargar del sitio Web de la revista.

Figura 1. Datos de dirección “aplanados”.


<< dnm.plataforma.net

Figura 2. Datos de dirección en tabla relacionada.

En el caso de que nuestro modelo relacional disponga las direcciones de los clientes junto con los demás datos de éstos en una única llamada Cliente1, los pasos a dar para definir el modelo serían los siguientes: 1. Agregue al proyecto un nuevo modelo de datos de ADO.NET; llámelo Modelo1. Genere el modelo a partir de la base de datos DNM_EF4, incluyendo únicamente la tabla Cliente1. Indique DNM_EF4_Modelo1 como espacio de nombres para las clases resultantes. 2. En el momento en que este artículo se escribe, el diseñador visual aún no ofrece un soporte completo para este tipo de implementación de tipos complejos. Abra el modelo de datos utilizando el editor XML, y en la sección correspondiente al modelo conceptual (CSDL) añada el elemento ComplexType del listado 1, que define el tipo complejo TipoDireccion. 3. Modifique la definición de la entidad Cliente1 para que haga uso del tipo recién definido, como se muestra en el listado 2.

<ComplexType Name=”TipoDireccion” a:Access=”Public” xmlns:a=”http://schemas.microsoft.com/ado/2006/04/ codegeneration”> <Property Name=”Direccion” Type=”String” Nullable=”false” MaxLength=”50” /> <Property Name=”Poblacion” Type=”String” MaxLength=”30” /> <Property Name=”CodigoPostal” Type=”String” MaxLength=”15” /> <Property Name=”Provincia” Type=”String” Nullable=”false” MaxLength=”30” /> </ComplexType>

Listado 1. Definición del tipo complejo TipoDireccion

<EntityType Name=”Cliente1”> <Key> <PropertyRef Name=”ID” /> </Key> <Property Name=”ID” Type=”Int32” Nullable=”false” /> <Property Name=”Nombre” Type=”String” Nullable=”false” MaxLength=”50” /> <Property Name=”Email” Type=”String” MaxLength=”50” /> <Property Name=”Direccion” Type=”DNM_EF4_Modelo1.TipoDireccion” Nullable=”false” /> </EntityType>

Listado 2. Nueva definición de Cliente1 en CSDL.

Desde nuestro lenguaje de programación accederemos a las direcciones y sus diferentes atributos mediante la notación tradicional de punto

4. Para completar el trabajo, tenemos que especificar, en la sección de mapeado C-S, cómo se corresponden las columnas físicas de la base de datos con la entidad y tipo complejo que acabamos de definir en el CSDL. Para ello, modificaremos el mapeo de la entidad Cliente1 según se muestra en el listado 3, envolviendo los diferentes elementos aso-

<<dotNetManía

Mapeo en caso de datos “aplanados”

23


<< dnm.plataforma.net

<EntityTypeMapping TypeName=”IsTypeOf(DNM_EF4_Modelo1.Cliente1)”> <MappingFragment StoreEntitySet=”Cliente1”> <ScalarProperty Name=”ID” ColumnName=”ID” /> <ScalarProperty Name=”Nombre” ColumnName=”Nombre” /> <ScalarProperty Name=”Email” ColumnName=”Email” /> <ComplexProperty Name=”Direccion” TypeName=”DNM_EF4_Modelo1.TipoDireccion” IsPartial=”true”> <ScalarProperty Name=”Direccion” ColumnName=”Direccion” /> <ScalarProperty Name=”Poblacion” ColumnName=”Poblacion” /> <ScalarProperty Name=”CodigoPostal” ColumnName=”CodigoPostal” /> <ScalarProperty Name=”Provincia” ColumnName=”Provincia” /> </ComplexProperty>

ciados a las direcciones dentro de un elemento ComplexProperty. Como ya es habitual, presentaremos ahora un pequeño ejemplo de cómo consultar con LINQ y actualizar el modelo obtenido. El listado 4 cumple ese cometido. En él se puede apreciar cómo desde nuestro lenguaje de programación accedemos a la dirección de los clientes y sus distintos atributos mediante la notación tradicional de punto, tan familiar en la programación orientada a objetos.

</MappingFragment> </EntityTypeMapping>

Listado 3. Nuevo mapeo de la entidad Cliente1.

using System; using System.Collections.Generic; using System.Linq; namespace TiposComplejos { using DNM_EF4_Modelo1; class Program { static void Main(string[] args) { using (DNM_EF4Entities1 ctx = new DNM_EF4Entities1()) { // nuevo cliente... Cliente1 c = new Cliente1(); c.ID = 0; c.Nombre = “Andrés Galarraga”; c.Email = “aglrg@terra.es”; c.Direccion.Direccion = “Arroyo Fontarrón 103, 2º”; c.Direccion.Poblacion = “Madrid”; c.Direccion.CodigoPostal = “28030”; c.Direccion.Provincia = “Madrid”; ctx.AddToCliente1(c); ctx.SaveChanges(); // grabar en BD // codigos postales de residentes en prov. Madrid var q = (from x in ctx.Cliente1 where x.Direccion.Provincia == “Madrid” select x.Direccion.CodigoPostal).Distinct(); // ejecutar la consulta foreach (var s in q) Console.WriteLine(s);

<<dotNetManía

}

24

} } }

Listado 4. Utilización del modelo DNM_EF4_Modelo1.

Mapeo en caso de tabla complementaria En el caso de que nuestro modelo relacional disponga las direcciones de los clientes en una tabla complementaria, según el diagrama de la figura 2, la secuencia de pasos a seguir sería la siguiente: 1. Agregue al proyecto un nuevo modelo de datos de ADO.NET; llámelo Modelo2. Genere el modelo a partir de la base de datos DNM_EF4, incluyendo las tablas Cliente2 y Direccion2. Indique en este caso DNM_EF4_Modelo2 como espacio de nombres para las clases resultantes. El modelo de entidades generado automáticamente se muestra en la figura 3. 2. En este caso, una parte del trabajo sí puede hacerse ya mediante el diseñador gráfico, oportunidad que aprovecharemos. Para ello, corte las propiedades Direccion, Poblacion, CodigoPostal y Provincia de la entidad Direccion2, como se muestra en la figura 4, y péguelas en la entidad Cliente2. Esto equivale a haber pasado los elementos XML que definen dichas propiedades de la definición de una entidad en el esquema CSDL a la otra. 3. Ahora debemos indicar cómo mapear cada una de estas nuevas propiedades del cliente a columnas de tablas del almacén relacional. Para ello, hay seleccionar la entidad Cliente2, abrir su ventana de Detalles de mapeo desde el menú con-


<< dnm.plataforma.net

INSERT, UPDATE y DELETE necesarias para inser-

Figura 3. Modelo conceptual inicial en caso de tabla complementaria

tar, modificar o borrar, respectivamente, un cliente. El código del listado 5 es un ejemplo de ello; en comentarios se muestran las sentencias SQL que se envían al almacén de datos en los momentos adecuados. El problema de detenernos aquí es que el concepto de Dirección como tipo complejo no estaría presente; tendríamos simplemente cuatro propiedades adicionales independientes en Cliente2. Lo más adecuado sería muy probablemente repetir los pasos que hemos dado en la sección anterior para incorporar también a este mode-

Figura 5. Detalles del mapeo de la entidad Cliente2

En este punto, ya habremos logrado combinar en una única entidad lógica datos que provienen físicamente de distintas tablas –una técnica que en los blogs del equipo de ADO.NET [4] se conoce bajo el término “Multiple Tables, Single Entity” (MTSE)–. Podríamos detenernos aquí, y ya tendríamos un modelo en el que el Marco de entidades será capaz de implementar el encuentro entre tablas que se requiere para construir una o más instancias de la entidad Cliente2, así como también de generar automáticamente las sentencias

lo el tipo complejo TipoDireccion, lo que dejamos al lector interesado en calidad de ejercicio propuesto. Una vez hecho esto, podremos operar sobre este segundo modelo de un modo muy similar al aplicado en el primer modelo (listado 4).

Conclusiones En este artículo hemos descrito otros dos mecanismos soportados por el Marco de entidades de ADO.NET para permitirnos crear modelos conceptuales mapeados a bases de datos relacionales. En próximas entregas continuaremos describiendo otras posibilidades que nos ofrece el Marco de entidades para el modelado conceptual.

<<dotNetManía

textual, agregar la tabla Direccion2 y establecer las correspondencias, como se muestra en la figura 5. 4. Ahora podemos eliminar la entidad Direccion2 del modelo conceptual, en el que sin dudas no “pinta” nada.

25


<< dnm.plataforma.net

using System; using System.Collections.Generic; using System.Linq; namespace TiposComplejos { using DNM_EF4_Modelo1; class Program { static void Main(string[] args) { // segundo modelo using (DNM_EF4Entities2 ctx = new DNM_EF4Entities2()) { // nuevo cliente... Cliente2 c = new Cliente2(); c.ID = 0; c.Nombre = “Andrés Galarraga”; c.Email = “aglrg@terra.es”; c.Direccion = “Arroyo Fontarrón 103, 2º”; c.Poblacion = “Madrid”; c.CodigoPostal = “28030”; c.Provincia = “Madrid”; ctx.AddToCliente2(c); ctx.SaveChanges(); // grabar en BD // Salida del SQL PROFILER: // exec sp_executesql N’INSERT [dbo].[Cliente2]([Nombre], [Email]) // VALUES (@0, @1) // SELECT [ID] // FROM [dbo].[Cliente2] // WHERE @@ROWCOUNT > 0 and [ID] = scope_identity()’, // N’@0 nvarchar(16),@1 nvarchar(14)’,@0=N’Andrés Galarraga’,@1=N’aglrg@terra.es’ // exec sp_executesql N’INSERT [dbo].[Direccion2]([ID], [Direccion], [Poblacion], [CodigoPostal], [Provincia]) // VALUES (@0, @1, @2, @3, @4)’, // N’@0 int,@1 nvarchar(24),@2 nvarchar(6),@3 nvarchar(5),@4 nvarchar(6)’,@0=1,@1=N’Arroyo Fontarrón 103, 2º’, // @2=N’Madrid’,@3=N’28030’,@4=N’Madrid’

// // // // // // //

// nombres y códigos postales de residentes en prov. Madrid var q = (from x in ctx.Cliente2 where x.Provincia == “Madrid” select new { x.Nombre, x.CodigoPostal }); // ejecutar la consulta foreach (var x in q) Console.WriteLine(x.Nombre + “ “ + x.CodigoPostal); Salida del SQL PROFILER: SELECT 1 AS [C1], [Extent1].[Nombre] AS [Nombre], [Extent2].[CodigoPostal] AS [CodigoPostal] FROM [dbo].[Cliente2] AS [Extent1] INNER JOIN [dbo].[Direccion2] AS [Extent2] ON [Extent1].[ID] = [Extent2].[ID] WHERE N’Madrid’ = [Extent2].[Provincia] } } }

}

Listado 5. Ejemplo del mapeo “Multiple Tables, Single Entity”

Bibliografía [ 1 ] Hernández, Octavio y Zorrilla, Unai “El Marco de trabajo de entidades de ADO.NET 3.5”, en dotNetManía nº

<<dotNetManía

[ 2]

26

[ 3] [ 4]

44, enero de 2007. Zorrilla, Unai y Hernández, Octavio “El Marco de trabajo de entidades de ADO.NET 3.5 (II)”, en dotNetManía nº 45, febrero de 2007. Zorrilla, Unai y Hernández, Octavio “El Marco de trabajo de entidades de ADO.NET 3.5 (III)”, en dotNetManía nº 46, marzo de 2007. Blog del equipo de ADO.NET Entity Framework, en http://blogs.msdn.com/adonet.


Braulio Díez Reyes García

plataforma.net

Silverlight 2.0: ¡Revolución! Silverlight 2.0 es la palabra de moda. Seguro que, aun estando en beta, ha escuchado algo acerca de esta tecnología en los últimos meses… En este artículo veremos qué hace de la versión 2.0 un producto tan esperado, cómo se desarrolla con él y cómo integrarlo en nuestras aplicaciones Web.

Braulio Díez trabaja en Avanade, es colaborador habitual de dotNetManía y administra el sitio tipsdotnet. Reyes García ha sido consultora "todo terreno". Hoy se dedica al gratificante mundo de la docencia.

Hace unos cuantos añitos que arrancó la World Wide Web, pero si miramos atrás y vemos algún pantallazo de una página Web antigua, nos podemos quedar sorprendidos… ¡Cuánto hemos evolucionado! Ahora tenemos Javascript/DHTML/DOM para modificar la página en cliente, AJAX para hacer peticiones fuera de banda sin tener que enviar el formulario completo al servidor, pero… ¿alguien se atrevería a decir que una aplicación Web puede tener mejor interfaz que una de escritorio? ¿A qué se debe esto? A un problema de raíz: HTML no fue diseñado para lo que se quiere hacer en estos momentos; se ha ido forzando y extendiendo el lenguaje para llegar más lejos, los fabricantes de software de desarrollo han intentado rebajar la complejidad a base de librerías/frameworks y lenguajes “mágicos” que ocultan gran parte de la complejidad que implica hacer una aplicación Web de última generación. ¿Acaso alguien se plantea, hoy en día, implementar una aplicación AJAX sin usar ningún tipo de ayuda? El problema que tenemos es que los usuarios seguimos pidiéndole más a la Web, y surge la duda de si podremos seguir dándole vueltas de tuerca a ese viejo amigo llamado HTML. Aquí es donde entra un nuevo concepto llamado RIA (Rich Internet Applications), es decir, aplicaciones Web que incorporan características de aplicaciones de escritorio, como por ejemplo: tener la lógica de funcionamiento/estado en cliente, comunicarse de forma ligera con el servidor, implementar características avanzadas que normalmente no están

presentes en entornos Web (drag & drop, animaciones…). La apuesta de Microsoft por RIA se llama Silverlight.

¿Qué es Silverlight 2.0? Definición informal Es un plug-in que se ejecuta en un navegador Web. Podemos elegir entre usarlo como base para nuestra aplicación o como complemento a nuestro sitio Web actual (incrustado en un fragmento de nuestras páginas). Nos permite crear todo tipo de aplicaciones: basadas en formularios, con manejo de gráficos, cuadros de mando (ver figura 1), generación de diagramas, etc. Todo esto se reali-

Figura 1. Ejemplo de cuadro de mandos generado con Silverlight 2.0

<<dotNetManía

Introducción

27


<< dnm.plataforma.net za usando un nuevo lenguaje de marcas (XAML), de una forma fácil, potente, bien estructurada, ¡pudiendo desarrollar bajo .NET en la parte cliente!

¿Qué es Silverlight 2.0? Definición formal Wikipedia nos dice algo así como: Plug-in multimedia para navegadores Web. Subconjunto de WPF (Windows Presentation Foundation) que permite ejecutar en un navegador Web animaciones, mostrar gráficos vectoriales y visualizar vídeo. Estará disponible para Windows y Mac OS-X; para Linux hay un proyecto open source paralelo llamado Moonlight, que se espera sea compatible con Silverlight. Silverlight se presenta como la alternativa a Adobe Flash / Flex.

¿Y Silverlight 1.0? Silverlight 1.0 tiene varios hándicaps, como que se programa solamente con Javascript, no incorpora controles de usuario estándar, etc. ¿Por qué salió al mercado? Tiene un reproductor de vídeo potente (soporta el códec de alta definición VC-1, estándar para Blue-ray y HD-DVD), y también sir ve como herramienta de marketing: para cuando salga la versión 2.0, mucha gente tendrá ya la 1.0 instalada y se la bajará de forma automática como una actualización.

<<dotNetManía

¿Otro Flash? ¿Qué tiene esto de revolucionario?

28

No es solo “otro” Flash, Flex o HTML: es un plug-in que nos permite tener una interfaz de usuario avanzada, sin las restricciones y problemas

que otras tecnologías nos acarrean. Algunos de los puntos fuertes de Silverlight 2.0 son: • Podemos elegir entre un amplio abanico de lenguajes para desarrollar, tanto compilados como interpretados: C#, Visual Basic, Iron Python, Iron Ruby… • Es posible desarrollar en un mismo lenguaje en cliente y en servidor (acceso a servicios). Gracias a esto la curva de aprendizaje se reduce, y tenemos un mismo entorno de desarrollo. • Tenemos una versión reducida de .NET Framework disponible en cliente. Por ejemplo: ¿qué le parece disponer de LINQ to XML en cliente? ¿Y enlace a datos? • Al recaer más lógica de la aplicación en la parte cliente descargamos la parte servidora, siendo nuestros sistemas más escalables. • HTML es un lenguaje de marcas que se ha ido forzando para adaptarlo a los nuevos tiempos y requerimientos del público. Desarrollar sitios avanzados con DHTML y Javascript se ha convertido en una tarea muy complicada, que requiere adquirir librerías de terceros,

adaptar el código para que funcione en diferentes navegadores… XAML es un lenguaje de marcas moderno y extensible, y al correr éste sobre un plug-in tenemos una única interpretación del mismo, y no tenemos que preocuparnos de realizar adaptaciones a los diferentes exploradores. • Si programamos en ASP.NET con Web Forms, tenemos que pasar de controles de servidor a controles HTML y viceversa. Esto hace que nuestras páginas sean difíciles de manipular en cliente vía Javascript, y podemos tener problemas de rendimiento (ViewState). Silverlight 2.0 implementa controles estándares que son manipulados directamente en el cliente. • Las aplicaciones Silverlight agrupan los recursos en ficheros ZIP que se envían comprimidos al cliente, teniendo un tiempo de descarga óptimo. • Es posible editar un fichero XAML tanto con Visual Studio como con editores de texto estándares e incluso utilizando herramientas para diseñadores gráficos (Expression).


<< dnm.plataforma.net Esto permite a desarrolladores y grafistas trabajar codo con codo. • Los controles estándar que incorpora Silverlight están pensados desde el punto de vista del desarrollador. Cualquier programador de Windows Forms/ASP.NET/WPF se familiarizará rápidamente con ellos. • Será compatible con tecnologías móviles; recientemente, Nokia ha anunciado que lo incluirá en algunos de sus modelos.

Pero… alguna pega tendrá, ¿no? Nada es perfecto en este mundo, las principales desventajas que tiene este producto son: • Está disponible para plataformas Mac y Windows, pero no para Linux. Aunque el mismo grupo que desarrolló el proyecto Mono está realizando una adaptación, con codename Moonlight, que cuenta con el soporte de Microsoft. • Se encuentra actualmente en fase beta; en proyectos a muy corto plazo no podemos tomarlo como opción de desarrollo. Se espera que este verano tengamos la versión definitiva.

Figura 2. Analogías ASP.NET–Silverlight

En ASP .NET tenemos:

En Silverlight tenemos:

En cliente: • HTML. • Código cliente (Javascript).

En cliente: • Contenedor (página HTML). • XAML (dentro de la página HTML). • Code behind (.NET: C#, VB.NET, etc.). En servidor: • Servicios (.NET: C#, VB.NET, etc.)

En servidor: • Code behind (.NET: C#, VB, etc.). • Servicios (.NET: C#, VB.NET, etc.).

Arquitectura y funcionamiento Vamos ver cómo se estructura una aplicación de este tipo, qué herramientas tenemos disponibles para desarrollar y, para abrir boca, realizaremos un pequeño ejemplo con el que iniciaremos nuestras andanzas en este nuevo mundo.

Una de las mejores formas de asimilar la arquitectura de una solución Silverlight es comparándola con la de un viejo conocido nuestro, ASP.NET (ver figura 2).

Figura 3. Herramientas para trabajar con Silverlight

<<dotNetManía

¿Cómo se estructura una aplicación Silverlight?

29


<< dnm.plataforma.net Todo esto es muy interesante… ¿qué herramientas tenemos disponibles? Si bien un desarrollador puede implementar una aplicación utilizando Visual Studio 2008 tanto para editar el XAML como el code behind, Microsoft nos permite que grafistas y programadores puedan cooperar en armonía, ofreciéndonos herramientas especializadas para cada rol (ver figura 3). En concreto tenemos: Grafistas

ticas nos harán sentirnos como en casa desde el primer día. • Otros editores: Si bien el compañero ideal de Silverlight para un desarrollador es Visual Studio, no siempre lo vamos a tener disponible (por ejemplo, en un servidor). Gracias a que los ficheros XAML y el code behind son ficheros de texto, podemos abrirlos con cualquier editor estándar (Notepad, UltraEdit, etc.). En Silverlight queda claramente separado qué parte tiene que tocar un

Figura 5. Elegimos crear proyecto Web asociado

• Expression Design: herramienta con la que podemos crear gráficos y exportarlos a formato XAML. • Expression Blend: con esta otra, además de poder crear gráficos, podemos también crear “formularios” (soltar en el área de diseño controles de usuario, emplear elementos para definir un layout, etc.). Desarrolladores • Visual Studio 2008: El IDE está totalmente integrado con Silverlight. Por ejemplo, tenemos Intellisense para el XAML y para el code behind, etc. Ésta y otras caracterís-

Figura 6. Proyecto generado por Visual Studio

grafista (XAML) y qué parte es propiedad del programador (code behind). Como somos técnicos, elegimos Visual Studio 2008 como herramienta, y nos instalamos el plug-in de la versión 2.0 y el SDK de Silverlight 2.0 para Visual Studio. Todo este material lo podemos descargar del sitio Web oficial, www.silverlight.net. Ahora estamos listos para crear el primer proyecto.

<<dotNetManía

¡Hola Mundo!

30

Figura 4. Crear nuevo proyecto

Aparquemos la “teoría” y pasemos a implementar un pequeño ejemplo que nos permita comprobar cómo se desarrolla con esta nueva tecnología. Para ello, iniciamos Visual Studio 2008, ele-


<< dnm.plataforma.net gimos crear un nuevo proyecto (previamente deberemos haber instalado el plug-in de Silverlight 2.0 y el SDK), y elegimos “Silverlight Application” (ver figura 4). A continuación se nos pregunta si queremos añadir un proyecto Web ASP.NET a la solución; diremos que sí. Esto hace muy fácil desplegar nuestra aplicación Web a un entorno de producción y nos permite, si hiciese falta, integrarlo con código ASP.NET estándar (ver figura 5). Generamos el proyecto, y analizamos la solución que ha creado Visual Studio (ver figura 6). Si ejecutamos el proyecto, veremos una página vacía. Le añadimos el códi-

Figura 7. Aspecto de “Hola Mundo”

<<dotNetManía

¿Javascript tiene los días contados?

32

Tradicionalmente, los desarrolladores han tenido una relación de amor/odio con Javascript. Siempre que aparece una nueva tecnología, resurge esta pregunta/deseo. Si utilizamos Silverlight como parte de una aplicación Web tradicional, tendremos que usar Javascript para interactuar entre página HTML y plug-in; no nos queda más remedio que pasar por el aro. Si la base de nuestra aplicación es Silverlight, podremos prescindir de Javascript: tenemos todas las herramientas necesarias para poder trabajar.

<!— Aquí indicamos, entre otras cosas, el tamaño de página, y el nombre de la <!— clase que implementa el code behind de la página. <UserControl x:Class=”HolaMundo.Page” xmlns=”http://schemas.microsoft.com/client/2007” xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml” Width=”400” Height=”300”> <!— Tenemos disponibles tres tipos de layout: <!— * Canvas: le decimos la posición exacta (X, Y) en la que queremos <!— mostrar cada control. <!— <!— * Stack Panel: los controles se alinean horizontalmente o verticalmente <!— (útil para visualizar controles como si fueran listas, o galerías de <!— imágenes). <!— <!— * Grid: parecido a una tabla de HTML pero mucho más potente (es el <!— que usamos en este ejemplo). <Grid x:Name=”LayoutRoot” Background=”White”> <!— Queremos dos filas de diferente altura. <Grid.RowDefinitions> <RowDefinition Height=”70”/> <RowDefinition Height=”30”/> </Grid.RowDefinitions> <!— Queremos dos columnas, una para el textbox y otra para el botón. <Grid.ColumnDefinitions> <ColumnDefinition Width=”200”/> <ColumnDefinition Width=”110”/> </Grid.ColumnDefinitions>

—> —>

—> —> —> —> —> —> —> —> —> —> —>

—>

<!— En la primera fila del grid, mostramos el texto “Hola Mundo”. Utilizamos—> <!— para ello un control TextBlock, parámetros a destacar: —> <!— —> <!— * x:Name es el Identificador del control (por el que podremos —> <!— referenciarlo desde el code behind). —> <!— —> <!— * Grid.Row y Column: posición del Grid en la que queremos mostrar el —> <!— texto. ColumnSpan sirve para indicar que la celda ocupe el espacio de —> <!— dos columnas. —> <TextBlock x:Name=”tbTexto” Text=”¡ Hola Mundo !” Grid.Row=”0” Grid.Column=”0” Grid.ColumnSpan=”2” FontSize=”40”/> <!— Dejamos al usuario que cambie el mensaje, tecleando en un TextBox y <!— pulsando el botón “Cambiar Mensaje”. <TextBox x:Name=”txCambio” Grid.Row=”1” Grid.Column=”0”></TextBox> <Button x:Name=”btnCambio” Content=”Cambiar Mensaje” Grid.Row=”1” Grid.Column=”1”/> </Grid> </UserControl>

—> —>

Listado 1. XAML con el layout de la página

go XAML necesario (ver listado 1) para crear una ventana con la apariencia de la figura 7. Ahora sí, al ejecutar el proyecto veremos cómo se muestra nuestra ventana. Solo falta un pequeño detalle: implementar la lógica que permite al usuario cambiar el texto a mostrar (tecleando en la caja de edición inferior y pulsando en el botón “Cambiar”).

Para ello: • Añadimos un manejador al evento Click del botón btnCambio en el XAML (ver listado 2). • Lo implementamos en el code behind de la página (ver listado 3). Ejecutamos de nuevo, ¡y ya tenemos nuestra aplicación completa! (figura 8).


<< dnm.plataforma.net <Button x:Name=”btnCambio” Content=”Cambiar Mensaje” Grid.Row=”1” Grid.Column=”1” Click=”btnCambio_Click” Click=”btnCambio_Click”/>

Listado 2. Manejador del botón de cambio

/// <summary> /// Cuando se pulsa el botón de cambio, le asignamos lo que hay /// en la caja de texto al TextBlock principal. /// </summary> /// <param name=”sender”></param> /// <param name=”e”></param> private void btnCambio_Click(object sender, RoutedEventArgs e) { tbTexto.Text = txCambio.Text; }

¿AJAX vs. Silverlight? Si usamos Silverlight como complemento de nuestro sitio Web, tendremos que hablar de “AJAX y Silverlight”. Si lo usamos como base para nuestra aplicación, utilizar AJAX deja de tener sentido, ya que Silverlight incorpora unas librerías de comunicación mucho más potentes, añadiendo además la comodidad de poder usarlas desde .NET.

Listado 3. Implementación del manejador

Hemos finalizado con el ejemplo y no hemos tocado código alguno del proyecto ASP.NET asociado ¿Para qué sirve? Nuestro proyecto necesita instanciar el plug-in de Silverlight en un navegador Web para poder ejecutarse. Visual Studio genera por nosotros el código necesario para visualizar el plug-in en una aplicación ASP.NET (fichero HolaMundoTestPage.aspx, ver listado 4), y en una página HTML (fichero HolaMundoTestPage.HTML, ver listado 5).

Conclusión Como reza el titular de este artículo, Silverlight 2.0 tiene todos los visos de pro-

Listado 4. HolaMundoTest.aspx

Silverlight 2.0 tiene todos los visos de provocar una auténtica revolución en el mundo del desarrollo Web <<dotNetManía

Figura 8 Aplicación completa

<body style=”height:100%;margin:0;”> <form id=”form1” runat=”server” tyle=”height:100%;”> (…) <div style=”height:100%;”> <!-- Control de servidor para instanciar el plug-in de Silverlight. --> <!-- Parámetros: --> <!---> <!-- * ID: para acceder al control desde el code behind de ASP.NET. --> <!---> <!-- * Source: dónde se encuentra el fichero de recursos de nuestro proyecto --> <!-- Silverlight (al estar el proyecto Web enlazado, Visual Studio nos copia --> <!-- automaticamente el resultado de la compilación a una carpeta del --> <!-- proyecto ASP.NET) . --> <!---> <!-- * Version: indicamos que el código corre bajo la versión 2.0 de --> <!-- Silverlight. --> <!---> <!-- * Width/Height: lo establecemos al 100 % para que ocupe todo el área --> <!-- de la página. --> <asp:Silverlight ID=”Xaml1” runat=”server” Source=”~/ClientBin/HolaMundo.xap” ~/ClientBin/HolaMundo.xap Version=”2.0” Width=”100%” Height=”100%” /> </div> </form> </body>

33


<< dnm.plataforma.net

<object data=”data:application/x-silverlight,” type=”application/x-silverlight-2-b1” width=”100%” height=”100%”> <param name=”source” value=”ClientBin/HolaMundo.xap”/> ClientBin/HolaMundo.xap <param name=”onerror” value=”onSilverlightError” /> <param name=”background” value=”white” /> <a href=”http://go.microsoft.com/fwlink/?LinkID=108182” style=”text-decoration: none;”> <img src=”http://go.microsoft.com/fwlink/?LinkId=108181” alt=”Get Microsoft Silverlight” style=”border-style: none”/> </a> </object>

Listado 5. HolaMundoTest.html

¿Necesita tener el .NET Framework instalado en cliente? No, el propio plug-in (que en estos momentos pesa alrededor de los 4 megas) trae una versión reducida del framework, con lo que no es requisito tener instalada la versión completa.

vocar una auténtica revolución en el mundo del desarrollo Web. Ahora que el producto ha pasado de Alfa

a beta, es un buen momento para comenzar a practicar con esta tecnología. Es un candidato a evaluar para desarrollos a medio y largo plazo.

¿Cuándo sale la versión definitiva? No hay ninguna fecha oficial, pero se rumorea que posiblemente este verano (junio).

<<dotNetManía

Para saber más

34

URL

Comentarios

http://silverlight.net

Sitio oficial de Silverlight. Desde aquí podrá descargar todo el material necesario para desarrollar (plug-in, SDK, tutoriales, etc.).

http://weblogs.asp.net/scottgu/archive/2008/02/22/first-look-at-silverlight-2.aspx

Introducción a Silverlight Beta 1, compuesto de un tutorial que se divide en 8 partes, con el sello inconfundible de Scott Guthrie. Ideal para iniciarse en esta tecnología.

http://www.silverlight.net/quickstarts/managed.aspx

Conjunto completo de tutoriales; la serie sobre comunicación es muy interesante. Los ejemplos están disponibles para descargar.

http://silverlight.net/blogs/jesseliberty

Blog del “evangelista mayor” de Silverlight. Muy buen material, útil y ameno.

Si quiere explorar más a fondo los detalles de los controles y componentes que incorpora Silverlight, puede tomar como base un buen libro de WPF; al fin y al cabo, Silverlight es un subconjunto de éste. Una lectura muy recomendable y que también le puede servir como referencia técnica es el Cuaderno Técnico Nº7 de dotNetManía, “Windows Presentation Foundation”, de los autores Miguel Katrib, Mario del Valle, Iskander Sierra y Yamil Hernández. Próximamente editaremos un libro sobre Silverlight 2.0 de Marino Posadas (¡estén atentos!).


plataforma.net

Daniel Seara

Componentes de uso general De contadores y trazas

Siguiendo con la serie de componentes de múltiples usos, veamos cómo crear nuestros propios contadores y definir trazas, lo cual nos permitirá identificar aquellas situaciones que puedan provocar dolores de cabeza cuando toda la aplicación esté en uso.

Otro mes ha pasado... y aquí estamos nuevamente, viendo qué podemos generalizar. Es el turno hoy de algunos componentes que nos ayudarán a medir qué está pasando con nuestra aplicación. Aun cuando esto no parezca muy útil, les puedo asegurar que, cuando se trabaja evaluando qué está pasando con una aplicación, realmente se echan en falta estas cosas.

[

NOTA Estas clases estarán en un espacio de nombres nuevo, en mi caso llamado Solid.Diagnostics

]

De contadores

Esas son, precisamente, las formas que los contadores pueden expresarse. Y cada una de ellas servirá para cosas distintas.

Funcionalidad que podemos encapsular Obviamente, existen elementos en el propio .NET Framework para trabajar con contadores. Específicamente, el tipo System.Diagnostics.PerformanceCounter. Lo que vamos a intentar es encapsularlo de modo que resulte algo más sencillo implementar luego contadores en otros componentes (como ya hicimos con los manejadores de excepciones). Una de las primeras cosas a decir en estos casos es: implementemos IDisposable. Así .NET Framework tendrá absoluta certeza acerca de qué hacer con estos objetos. Public MustInherit Class PerformanceCounterBase_

Daniel Seara es mentor de Solid Quality Mentors y director del área de desarrollo .NET. Es MVP desde 2003 y ponente habitual de INETA y Microsoft.

Establecer contadores en los componentes es como cuando se va al médico. Te toma el pulso, te mide la presión, te hace un análisis para ver cuántos glóbulos tienes o cómo está el azúcar en la sangre. Llamativamente, esta comparación me viene como anillo al dedo, porque se parece mucho a lo que podemos hacer. Algunos de estos resultados, como los de los glóbulos, se expresan en cantidades: cuántos rojos tienes, por ejemplo. Otros son proporcionales: cuántos gramos de azúcar por litro tienes. Y en muchos casos se miden variaciones: cuánto peso has aumentado desde la última vez que medimos.

Implements IDisposable

E inmediatamente, tengamos como privado un objeto contador del propio .NET Framework. Protected mPerfCounter As _ System.Diagnostics.PerformanceCounter

Definamos las acciones posibles para nuestros contadores Ya dijimos qué tipos de conteos podríamos llevar, comparados con la medicina. Simplemente, vamos a por ello:


<< dnm.plataforma.net

Aumentar un contador

Además, definiremos algunas propiedades que las clases que heredan deberán implementar (estimo que los nombres son explicación suficiente ☺).

[

NOTA Como se puede ver, algunos métodos tienen el mismo nombre y distinta firma (uno recibe un argumento, el otro no). Digamos que, a fuerza de ser estrictos, aquí está faltando el Overloads; pero vamos, que Visual Basic es lo suficientemente inteligente para darse cuenta.

]

Disminuir un contador Sub DecrementCount() mPerfCounter.Decrement() End Sub Sub DecrementCount(ByVal value As Long) For i As Long = 1 To value mPerfCounter.Decrement() Next End Sub

Cambiar un valor promedio

Sub ChangeAvg(ByVal newValue As Long) Dim actual As Long = mPerfCounter.RawValue mPerfCounter.RawValue = _ CLng(If(actual=0, newValue, (newValue+actual)/2)) End Sub

También deberemos ocuparnos de la interfaz IDisposable:

#Region “MustOverrides” MustOverride ReadOnly Property _ Name() As String MustOverride ReadOnly Property _ Type() As PerformanceCounterType MustOverride ReadOnly Property _ Description() As String #End Region

La complicación de la creación de contadores El problema que nos encontramos es que los contadores de rendimiento deberían instalarse antes de ser utilizados. Lo cual significa que deberíamos crear instaladores para nuestros componentes, cosa que podría estar bien, pero a veces resultar innecesario. Sin embargo, podríamos partir de la base (que no tiene por qué ser del todo cierta, pero éstos son nuestros componentes, los diseñamos a nuestro estilo) de que cada categoría de contadores se corresponde con un proyecto/ensamblado. Esto nos permitiría agrupar los contadores por ensamblado y manipularlos adecuadamente, incluyendo su creación en caso de no existir. El problema es que los contadores pueden crearse por código… siempre que se creen junto con la categoría de los mismos. Entonces, lo que deberíamos hacer es seguir un planteamiento como el que muestra la figura 1. Cuando se quiera utilizar un contador, obviamente se creará una instancia. Es entonces el constructor el mejor lugar para decidir si todas las condiciones están dadas, y establecerlas de no ser así.

#Region “ IDisposable Support “ Private disposedValue As Boolean = False ‘ To detect redundant calls ‘ IDisposable Protected Overridable Sub Dispose(ByVal disposing As Boolean) If Not Me.disposedValue Then If disposing Then If mPerfCounter IsNot Nothing Then mPerfCounter.Dispose() End If End If End If Me.disposedValue = True End Sub

<<dotNetManía

Sub IncrementCount() mPerfCounter.Increment() End Sub Sub IncrementCount(ByVal value As Long) mPerfCounter.IncrementBy(value) End Sub

37


<< dnm.plataforma.net

Luego, investigaremos qué tipos (clases) existen que hereden de esta clase base; ellos serán los contadores de ese ensamblado. Para ello, primero obtenemos quién es el ensamblado del que se está creando una instancia, utilizando System.Reflection.Assembly.GetCallingAssembly. Este objeto expone los tipos definidos como públicos, a través del método GetExportedTypes. Y, ya que estamos, por qué no usar un poco de LINQ para obtener los que nos interesan (así mi amigo Octavio se pone contento ☺).

Figura 1 Lógica de construcción de contadores

For Each t As Type In _ (From tp As Type In _ System.Reflection.Assembly._ GetCallingAssembly._ GetExportedTypes _ Where tp.IsSubclassOf(_ GetType(PerformanceCounterBase)))

Create: Shared inCreation As Boolean = False

<<dotNetManía

Protected Sub New( _ ByVal CategoryName As String, _ ByVal CounterName As String, _ ByVal instanceName As String) Dim cat As _ PerformanceCounterCategory ‘Esto permite reentrar, para ‘crear cada instancia en ‘el momento de la definición If inCreation Then Exit Sub

38

Claro que, siendo éste el caso, y necesitando crear instancias para poder obtener sus definiciones, estamos haciendo un pequeño truco: utilizar una señal compartida (la variable inCreation), para saber cuándo ya estamos dentro de este proceso. Si estamos preparando el terreno (creando la categoría y los contadores), entonces esto nos permite crear instancias sin caer en un bucle infinito. Luego procedemos a evaluar si la categoría no existe, en cuyo caso definimos un creador de contadores (CounterCreationDataCollection):

‘Si no existe la categoría If Not PerformanceCounterCategory.Exists(CategoryName) Then ‘Para permitir reentrar sin volver a crear la categoría inCreation = True ‘Creador de contadores Dim Creator As New CounterCreationDataCollection()

Una de las cosas que siempre quedan para después en una aplicación es implementar mecanismos de medición. Pues bien, esto no debería ser así. Por ello, este artículo pretende sentar las bases de una implementación simple y reutilizable

Los contadores que encontramos en dicho bucle los vamos agregando al creador de contadores:

With CType(System.Reflection.Assembly._ GetCallingAssembly.CreateInstance(_ t.FullName),_ PerformanceCounterBase) Creator.Add(New _ CounterCreationData(.Name, _ .Description, _ .Type)) End With Next


<< dnm.plataforma.net

cat=PerformanceCounterCategory.Create(_ CategoryName, _ String.Format( _ “Performance counters for {0} Assembly”,_

System.Reflection.Assembly._ GetCallingAssembly.GetName.Name),_ PerformanceCounterCategoryType._ MultiInstance, _ Creator)

Usando el contador base Como estoy seguro que tengo lectores fieles, todos sabréis del componente de acceso a datos de números anteriores ☺. En él mencioné la posibilidad de tener métodos que llamen a auxiliares de diagnóstico, para contar rendimiento, hacer trazas, etc. (dotNetManía nº 46, página 33). Pues bien, creemos dos contadores en dicho componente:

Contador de cantidad de consultas:

inCreation = False

Imports Solid.Diagnostics

Ahora bien, si la categoría existiese, pero no el contador, casi con toda certeza se ha cambiado de versión del ensamblado que las define (se han agregado nuevos contadores). En este caso, no es sólo cuestión de agregar el contador… hay que hacer todo de nuevo. Entonces, eliminamos la categoría, y retomamos la creación completa.

Else If Not PerformanceCounterCategory._ CounterExists(CounterName,_ CategoryName) Then PerformanceCounterCategory._ Delete(CategoryName) GoTo Create ‘Crea todo el conjunto End If End If

Finalmente, estando seguros de que tenemos todas las condiciones que necesitamos, procedemos a crear el contador interno de esta clase.

mPerfCounter = New _ PerformanceCounter( _ CategoryName, _ ‘Categoría CounterName, _ ‘Contador instanceName, _ ‘Instancia False) ‘solo lectura End Sub

Public Class PerfCounterQueries Inherits PerformanceCounterBase Sub New(ByVal instanceName As String) MyBase.New(“Solid Data”, _ “Queries Qty”, _ instanceName) End Sub Sub New() MyClass.New(“”) End Sub Public Overrides ReadOnly Property_ Name() As String Get Return “Queries Qty” End Get End Property

Promedio de tiempo de ejecución entre consultas: Imports Solid.Diagnostics Public Class PerfCounterQueryTime Inherits PerformanceCounterBase Sub New(ByVal instanceName As String) MyBase.New(“Solid Data”, _ “Query Time Avg”, _ instanceName) End Sub Sub New() MyClass.New(“”) End Sub Public Overrides ReadOnly Property_ Name() As String Get Return “Query Time Avg” End Get End Property Public Overrides ReadOnly Property_ Type() As_ System.Diagnostics._ PerformanceCounterType Get Return PerformanceCounterType._ RateOfCountsPerSecond32 End Get End Property Public Overrides ReadOnly Property_ Description() As String Get Return “Average time for queries” End Get End Property End Class

Y una pequeña prueba Public Overrides ReadOnly Property_ Type() As System.Diagnostics._ PerformanceCounterType Get Return PerformanceCounterType._ NumberOfItems32 End Get End Property Public Overrides ReadOnly Property_ Description() As String Get Return _ “Counts the amount of queries executed by the instance” End Get End Property

En el artículo del número anterior antes mencionado, teníamos un formulario para probar el componente de acceso a datos. Voy a modificar el código del botón que hacía la llamada, para que la repita varias veces. De esa forma podremos ver más fácilmente el contador de consultas en acción: Private Sub tsbTodos_Click( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles tsbTodos.Click For i As Integer = 0 To 10 LlenarConTodos() Next

End Class End Sub

<<dotNetManía

Una vez se han agregado todos los contadores del ensamblado, creamos todo el conjunto:

39


<< dnm.plataforma.net

Por otra parte, voy a poner una espera en el procedimiento almacenado, para que demore más tiempo. ALTER PROCEDURE [dbo].[Shippers_TraerTodos] AS WAITFOR DELAY ‘00:00:05’ SELECT ShipperID, CompanyName, Phone FROM Shippers ORDER BY CompanyName

Accediendo al monitor de rendimiento (Performance Monitor), puedo agregar mis contadores luego de haber ejecutado al menos una consulta para que éstos se creen (figura 2).

Figura 3. Medición de los contadores

Figura 2 Selección de contadores

contador “Queries Qty”, mientras que el “Query Time” se mantiene constante la mayor parte del tiempo, ya que la demora en el procedimiento es siempre la misma. En la figura 3 se nota una elevación del contador de tiempo casi al final del gráfico. Allí fue donde se hizo clic en el botón de llamada de la consulta por primera vez, que conlleva mayor tiempo de acceso.

De trazas Seleccionemos todos los contadores (“All Counters”) y todas las instancias (“All Instances”).

[ ] NOTA

<<dotNetManía

El constructor de cada uno de estos contadores utiliza el nombre de la conexión como nombre de la instancia. Por eso, en la figura 2, en la lista de instancias aparece dicho nombre: nw.

40

Si ejecutamos repetidamente la consulta, podremos ver la variación en el

Ya vamos llegando al final de este artículo (el espacio es tan tirano como el tiempo), pero es más fácil resolver el tema de las trazas. En ciertos sentidos se parece al manejo de excepciones. Una clase base, que expone métodos de persistencia y propiedades de valor, y una clase de configuración que determine donde se almacena la traza. Para las trazas, es altamente recomendable que dejemos todo definido como para almacenar en base de datos. Y que separemos en archivos físicos por fecha en el caso en que almacenemos en disco. La clase base de las trazas expondrá tantas propiedades como se quieran

identificar (esto dependerá de lo que se desee informar). También habrá que considerar que las clases que heredan de ésta podrán definir propiedades que expandan la funcionalidad de la clase base… y estar preparadas para persistirlas. Entonces, no importa dónde ni con qué formato se persista, en todos los casos todas las propiedades indicadas deberían almacenarse. Para este ejemplillo (que no tengo lugar para más), asumamos que almacenamos en algún medio que admite XML (no es que sea fanático, pero me sirve para el ejemplo). Podría ser entonces algo así:

Sub Persist() Dim x As XElement = <Entry></Entry> For Each p As Reflection.PropertyInfo_ In Me.GetType.GetProperties <%= p.Name %>> %> x.Add(<<%= <%= CallByName(Me, p.Name,_ CallType.Get) %> </>) Next ‘se guarda el valor End Sub

Si, de acuerdo. Pidamos al Guille que explique esto algo mejor desde su isla. Nos vemos en la próxima.


Isla VB

Guillermo «Guille» Som

Visual Basic solidario Viejas costumbres, nuevas formas

No, no es que a Microsoft le haya dado por crear una nueva versión de Visual Basic que se solidarice con la humanidad. Pero el que escribe quiere que los lectores de esta “Isla VB” sí se solidaricen, y esa solidaridad solo la pueden demostrar actuando. ¡Espero que actúen!

¡ Ayuda a Juanma a vivir!

Guillermo “Guille” Som Es Microsoft MVP de Visual Basic desde 1997. Es redactor de dotNetManía, mentor de Solid Quality Mentors, orador de Ineta Latam, y autor de los libros “Manual Imprescindible de Visual Basic .NET”, “Visual Basic 2005” y "Novedades de Visual Basic 9.0". http://www.elguille.info.

Con el permiso de los lectores, voy a dedicar unas líneas de esta "isla" a comentar el caso de un niño de Almería llamado Juanma, que a primeros de marzo cumplió cuatro años y que padece una enfermedad conocida como Síndrome de Alexander, que es una variante de la leucodistrofia. La primera vez que leí sobre el caso de Juanma fue en un grupo de noticias privado. La primera impresión que me llevé fue la que supongo que muchos se llevarían, sobre todo los que ya llevamos deambulando por Internet algunos años y hemos tenido ocasión de ver alguna que otra llamada a la solidaridad. Pero mi amiga Eva (ex-MVP de Access) insistía en que la historia era cierta. Como soy incrédulo por naturaleza, hice algunas indagaciones, llamé por teléfono, busqué en Internet, incluso estuve en una oficina de Cajamar para informarme sobre la cuenta que habían abierto para recibir las donaciones. El caso es que existe un centro en los Estados Unidos que está investigando una cura para esta enfermedad. Parten de medicamentos ya aprobados por la FDA (han superado todas las pruebas para ser administrados a humanos) y actualmente tienen 10 medicamentos prometedores contra los daños que el síndrome de Alexander produce. Continuar con la investigación de cada uno de estos medicamentos ronda la cantidad de 250.000 dólares USA. La familia de Juanma está moviendo cielo y tierra para conseguir esas cantidades, para que se pueda llegar a tener un tratamiento que administrar al niño. Ni que decir tiene que no solo hay que desembolsar el coste de los tratamientos (2.500.000 dólares USA), sino que también hay que incluir los gastos de desplazamiento y la estancia en EEUU de la familia que acompañe al niño. Por lo que yo sé, el primer viaje lo costeará la Cruz Roja (tanto los gastos de desplazamiento como la estancia), y por la información que tengo, el pasado 25 de marzo hicieron un ingreso en la cuenta de la institución que está haciendo estos estudios sobre la enfermedad de Alexander de 676.207, 50 dólares USA. Algunos estamos haciendo ingresos en la cuenta de Juanma, además de recabar información para despejar dudas, que son muchas las que nos plantean algunos de los que queremos involucrar en esta causa. No quiero alargarme más, solo dejaros la dirección Web de Juanma y esperar que cada cual actúe como buenamente pueda y quiera. Por mi parte, el importe que me corresponde de todos los artículos que escriba para dotNetManía se ingresará directamente en esa cuenta o se usará para costear los gastos de desplazamiento y estancia de Juanma y su familia si tienen que viajar a los EE.UU. La URL con los datos de Juanma, y un poco de la historia: http://www.ayudajuanma.es.


<< dnm.isla.vb

Todos los que alguna vez han usado Visual Basic, pero el de antes, es decir, el Visual Basic que no es para .NET (aunque aquí hay que hacer un inciso, ya que en realidad “los” Visual Basic anteriores a .NET no son solo el que los viejos programadores hemos usado, ya que hoy en día hay muchos, pero muchos, muchos programadores que siguen usando Visual Basic pre .NET, y no solo porque siguen usando Visual Basic 6.0, sino porque usan Visual Basic para Aplicaciones -VBA-, particularmente con Access o Excel), el –digamos– Visual Basic clásico (o Visual Basic new age que diría mi amigo Daniel Seara), seguro que han intentado usar las funciones a las que están acostumbrados, pero se han encontrado que en la versión de Visual Basic para .NET algunas no están y otras han cambiado e incluso se usan de forma muy distinta. A estas alturas de la vida programática de Visual Basic para .NET Framework, no es plan hacer comparaciones de qué función sustituye a cuál, entre otras cosas, porque si me pusiera a hacer esas comparaciones estaría unos cuantos años escribiendo artículos para intentar cubrir solo algunas de ellas. En lugar de eso, lo que voy a hacer en este artículo, y en algunos que sigan, es comentar algunas de esas “cosillas” que normalmente necesitamos hacer, y solo cuando sea estrictamente necesario, pondré la equivalencia con las versiones clásicas de Visual Basic. Y debido a que ya tenemos otra forma de hacer algunas de esas cosas a las que estamos acostumbrados (incluso los que ya hemos olvidado cómo se hacía con VB6), también intentaré explicar cómo podemos aprovecharnos de esas nuevas formas de hacer las cosas. Por supuesto, para que esto sea posible, el lector debe utilizar la últi-

ma versión de Visual Basic, la versión 9.0, sí, la que se incluye con Visual Studio 2008. ¡Exacto!1

¿Por dónde empezar? ¿Convierto mi código? Muchos desarrolladores de Visual Basic 6.0 (llamaré así a las versiones anteriores a .NET o a las actuales que no utilizan el framework como base para trabajar) seguramente se encuentran perdidos cuando quieren afrontar un proyecto de Visual Basic para .NET. Y la mayoría de ellos, casi con toda seguridad, prefieren convertir el

El problema es que pensamos que esa es la mejor forma, y puede que en algunos casos lo sea, pero dudo que en la mayoría de los proyectos reales sea una opción válida. Por ejemplo, ¿tenemos acceso a datos? Si la respuesta es sí, debemos olvidarnos del código anterior. Así de drástico. Si pretendemos ahorrarnos unas horas escribiendo el nuevo código, a la larga las perderemos, y seguramente no nos funcionará el proyecto. O lo que es peor, puede que algunas veces nos funcione. Pero por experiencia puedo asegurar de que serán muy pocos los casos que ese código convertido funcione.

Dudo que en la mayoría de los proyectos reales utilizar el asistente de conversión sea una opción válida

código de sus viejos proyectos usando el asistente de conversión que todas las versiones de Visual Basic ofrecen, ya sea la incluida en Visual Studio o en la versión Express, y no está mal. Es un buen punto para empezar a tener problemas. No es que me queje de esta herramienta, ya que hace medianamente bien su trabajo, el problema real es que no deberíamos convertir los proyectos. ¿Qué estás diciendo, Guille? ¿Me sugieres que lo escriba todo nuevamente, desde cero? Es que son “nnn” líneas de código que quiero aprovechar (sustituir “nnn” por la cantidad de líneas del proyecto). ¿No puedo aprovecharlas? Claro que se pueden aprovechar. De hecho, eso es lo que deberíamos hacer.

Un problema añadido (independientemente de lo que queramos convertir) es que no siempre se utilizan los nuevos controles de .NET. Esto ya se mejoró un poco en la versión 2005 de Visual Studio, pero sigue habiendo algunos que no se utilizan, y no porque no existan, sino porque seguramente la funcionalidad de los nuevos es diferente al de los antiguos, como puede ser el caso del control RichTextBox. También es cierto que existen los PowerPacks de Visual Basic y ya podemos disponer de controles como Line, Shape e incluso el "famoso" Printer. Pero volvamos a los controles de los que no existen equivalencias. Y para reflejarlo con un caso real, voy a contar “mi historia” con un proyecto de Visual Basic 6.0.

1 Esa que es la protagonista de mi nuevo libro electrónico Novedades de Visual Basic 9.0, que por cierto, el cupón de descuento que indiqué el mes pasado sigue siendo válido hasta el 30 de este mes de abril. Por tanto, los lectores de dotNetManía pueden usarlo al comprar el libro en la Web de Solid Quality Press: http://www.solidq.com/ib/eBookDetail.aspx?Id=1. El cupón de descuento del 50% es: “dnm3103”.Y siguiendo con la petición solidaria de ayuda a Juanma, si el lector compra el libro con ese cupón de descuento, que piense que no se ha ahorrado nada, y el resto (7,50€) le pediría que lo ingresara en la cuenta de Juanma. Gracias.

<<dotNetManía

Viejas costumbres, nuevas formas

43


<<dotNetManía

<< dnm.isla.vb

44

Desde que instalé por última vez el sistema operativo de mi portátil (Windows Vista Ultimate en inglés, para más señas), decidí no instalar el entorno de desarrollo de Visual Basic 6.0, entre otras cosas porque ya no quería seguir usándolo. Bueno, en realidad lo que hice fue crear una máquina virtual con el sistema operativo Windows XP (sin ningún Service Pack), en el que tengo instalado el Visual Basic 6.0 con el Service Pack 6, además de Visual Studio .NET 2003. El no instalar los Service Pack de Windows XP es porque aún sigo manteniendo alguna que otra aplicación de gestión creada con el compilador de BASIC versión 7.1, pero para MS-DOS, que no es un Basic “visual”, y el SP2 de XP me deja menos memoria extendida de la que necesito para trabajar con el QBX.exe, y si no puedo cargar el código, es complicado hacer modificaciones. A quien le extrañe que siga manteniendo este tipo de aplicaciones, comentarle que: cuando las cosas funcionan ¿para qué cambiar? En mis aplicaciones de Visual Basic 6.0 siempre he usado (o usaba) muchas llamadas a la API de Windows, la mayoría de las veces para hacer cosas simples, pero que me rendían mejor con mis clases que tenían las llamadas a la API que usando los controles incluidos con el entorno de VB6; por ejemplo, todo lo relacionado a los diálogos comunes, particularmente en lo referente a abrir y guardar. También me gusta dar soporte de arrastrar y soltar (drag & drop), y algunas otras cosas "habituales". El problema es que esas cosas habituales en mis aplicaciones son causa de muchos quebraderos de cabeza a la hora de convertir el código. Desde hace años, suelo encapsular el código todo lo que puedo; si bien Visual Basic 6.0 no soporta la herencia, sí que tiene otros medios para facilitarnos la programación orientada a objetos, bueno, no a objetos, pero sí lo más parecido que se puede, sin necesidad de heredar nada. Y precisamente, tener objetos separados me facilita el trabajo de conversión, por ejemplo, como dije antes, todo

lo relacionado con los cuadros de diálogos comunes lo tengo en una clase; por tanto, cuando hago la conversión, utilizo la versión de esa clase que tengo para que funcione en .NET y simplemente sustituyo la que el asistente ha convertido. Retomando el problema de los controles sin equivalencia (no es que no tengan equivalencia, sino que el asistente no utiliza los que se incluyen en .NET), en uno de los proyectos me decía que no tenía licencia para usarlo en modo de diseño (ver la figura 1). Este problema ya era conocido por muchos de los que habitualmente usábamos Visual Basic desde la versión 5, y sabíamos que existía un fichero que

que me dice el asistente. Si miro la lista de errores de Visual Studio, tengo 102 errores y 49 advertencias (estas cantidades son porque el máximo de errores es de 151, no porque “solo” sean esos los errores). Y curiosamente dos de esas advertencias es indicándome que no se puede localizar el componente Microsoft.VisualBasic.PowerPacks. Sí, es que no instalo ninguno de los PowerPacks para Visual Basic, ya que eso me obligaría a seguir haciendo las cosas como se hacían antes. En un momento vuelvo sobre este comentario; antes sigamos viendo la lista de errores. En realidad los errores son fáciles de solucionar, el problema es que muchos de ellos son por “costumbres”

Figura 1. Error del asistente al no encontrar licencia de un control

solucionaba todos estos problemas: Vbctrls.reg, que si bien se distribuía con

otros controles, en realidad te solucionaba todos estos problemas (y actualmente sigue siendo válido). Pero independientemente de que tengamos ese fichero mágico y podamos convertir cualquier proyecto, la verdad es que no lo tendremos fácil. Siguiendo con el proyecto que comento (que finalmente decidí seguir usando en su versión de VB6), el asistente me dice que tengo 35 errores de compilación, 47 de errores de diseño y 169 advertencias. Pero claro, esto es lo

adquiridas en todo lo referente a la compilación tardía (late binding) de las versiones clásicas de Visual Basic. El problema es que algunas de las cosas que yo hacía “por mejor”, ahora en .NET no se consideran buenas prácticas. Bueno, en realidad es que en .NET no se permite que se hagan. Por ejemplo, yo en algunas partes del código que quería reutilizar, en lugar de crear objetos de tipo Variant, definía ciertas variables como Control, ya que iba a usarlas para almacenar algún control, que bien podía ser una etiqueta o una caja de textos. Por ejemplo, era algo habitual


<< dnm.isla.vb

tText = System.Windows.Forms.Form. ActiveForm.ActiveControl

La variable tText la definía como Control, ya que lo mismo podía ser un TextBox o un ComboBox. Pero esto ahora no funciona, particularmente si quiero acceder a alguna de las posibles propiedades que tiene ese control, por ejemplo, SelText para obtener el texto seleccionado. ¿Solución? Definir esa variable como Object en vez de Control; de esa forma Option Strict Off (que es la forma predeterminada de usar todo el código convertido) me permite hacer lo que quiera... al menos en tiempo de diseño/compilación, lo que ocurra cuando se llegue a esa línea ya se verá en tiempo de ejecución. Porque fallar, fallará, ya que SelText o SelLength o SelStart ya no son propiedades de los controles de textos. Otro fallo habitual es cuando asignamos valores a las propiedades predeterminadas de los controles. Eso no existe en .NET, por tanto, nada de eso funcionará. Sí, el asistente intenta solucionarlo, pero solo cuando conoce el tipo de control. Y puedo asegurar que el asistente muchas de las veces no sabe qué control es el que está manejando. Para solucionar todas estas inconsistencias, debemos hacer la conversión al tipo de datos correcto (o adecuado). Una vez que lo hagamos, veremos si se puede o no usar esta o aquella propiedad. Pero doy fe de que es una tarea muy desagradable y consumidora de tiempo (y que si no se acompaña con litros y litros de tila, seguramente no llegaremos a finalizar nunca). Supongamos que hemos tenido paciencia, que hemos realizado todas las conversiones, que a pesar de que no nos gusta, hemos usado Option Strict Off. Que a pesar de que tampoco nos guste, hemos dejado la referencia al ensamblado Microsoft.VisualBasic.Compatibility, porque este ensamblado y otros de la misma “familia” lo único que consiguen es retrasarnos más nuestro paso al mundo de .NET, además de que algu-

nas de las funciones incluidas en realidad no nos mejoran el código: desde mi punto de vista, hasta lo empeoran, y si no, baste con ver las funciones de manipulación del contenido de los controles ListBox o ComboBox; hay más, pero con eso es suficiente para ver cómo se pueden complicar las cosas sencillas. En el siguiente código tenemos la forma propuesta por el código “compatible” y el que se puede usar de forma “natural”: Texto.Text = VB6.GetItemString( Lista, Lista.SelectedIndex) Texto.Text = Lista.SelectedItem.ToString

Y como esto, muchas cosas que se pueden resolver con una llamada al método ToString (que todas las clases de .NET implementan), pero que en el espacio de nombres para la compatibilidad se esfuerzan en ignorar. Como decía, si una vez que hemos quitado todas esas advertencias y errores ejecutamos el programa, casi con toda seguridad fallará, sobre todo si es una aplicación con acceso a datos. Y digo “con toda seguridad”, porque esta aplicación en concreto no la he terminado de convertir. Era demasiado trabajo para después no usarla por miedo a que falle. Entonces ¿cuál es la solución? Las que yo he utilizado son dos. Una es seguir usando la aplicación de Visual Basic 6.0. La pregunta lógica (o el reproche) sería decirme que no aprovecharé las nuevas características que me ofrece .NET Framework. Y mi respuesta es: si lo necesito, sí que aprovecharé lo que me ofrece .NET. ¿Cómo? Creando con Visual Basic .NET el código que quiero usar en mi aplicación de Visual Basic 6.0. Después de esta afirmación pueden ocurrir dos cosas. Una que el lector no me crea, y será porque no ha leído mi artículo del número 24 de esta revista cuyo título es “Usar componentes .NET desde aplicaciones COM”, y la otra es que el lector me crea, incluso aunque no haya leído ese artículo. La otra solución es crear la aplicación completamente en .NET (preferiblemente desde cero) y si viene al caso, usar componentes COM en la aplica-

Es posible crear con Visual Basic .NET el código que quiero usar en mi aplicación de Visual Basic 6.0

ción de .NET (lo que se explicó en el número 23 de esta misma revista). En la primera de estas dos soluciones (la de usar componentes de .NET desde VB6), se necesita un trabajo extra o previo, ya que la aplicación de VB6 debe estar "pensada" para usar componentes o al menos debe estar lo suficientemente granularizada para que eso sea fácil de hacer, ya que lo habitual es que escribamos el código "todo en uno" y no lo dividamos en componentes. Por suerte, yo casi no tengo ese problema, ya que siempre he intentado encapsular al máximo mis aplicaciones; no todas, debo reconocerlo, pero sí casi todas, al menos las que no eran simples pruebas o aplicaciones de andar por casa y terminarlas en un tiempo récord. La segunda (usar componentes de VB6 en VB.NET) es más inusual, y la verdad es que solo la he aplicado en una ocasión (aparte de las pruebas que uno hace para saber que todo esto funciona). Ese caso concreto era porque necesitaba usar ficheros de datos en los que usaba tipos definidos por el usuario (Type) que tenían valores numéricos, y esa tarea en Visual Basic 6.0 es cosa de niños, pero en .NET, al no permitir estos tipos de datos y esa forma de acceso, pues se complicaba más de la cuenta, incluso usando las nuevas clases que aparecieron en Visual Basic 2005 para acceder a los ficheros usando longitudes de registros de tamaño fijo. Los que hayan usado las

<<dotNetManía

detectar cuál era el control activo usando algo como esto:

45


<< dnm.isla.vb

funciones CVI, CVS, MKI, MKS, etc., sabrán de qué estoy hablando.

<<dotNetManía

Olvidemos el pasado

46

Sí, creo que es lo mejor, ya que esto se va a convertir en una serie de dimes y diretes que será como el cuento de nunca acabar, que si lo describiera al estilo de las conversaciones de José Saramago sería algo así: Quieres que te cuente el cuento de nunca acabar, Sí, No digo que sí, digo que si quieres que te cuente el cuento de nunca acabar. La cuestión es ¿por qué olvidarnos de lo que ya sabemos? Pero esa no es la cuestión, de hecho, yo insisto en que no nos olvidemos de lo que ya sabemos; es decir, si ya sabemos algo de Visual Basic, aprendamos lo nuevo, que todo eso que sabemos ya nos sirve. Pero si la cuestión fuera esta otra: ¿por qué debo dejar de usar Visual Basic 6.0? Ya no habría nada que responder, al menos en contra, porque es una cuestión lícita y con fundamento, particularmente cuando sabemos que la vida de las aplicaciones de Visual Basic 6.0 se garantizan al menos hasta el año 2015 ó 2016, que es la vida de Windows Vista y de Windows Server 2008, ya que ambos sistemas operativos incluyen el motor en tiempo de ejecución (runtime) de Visual Basic 6.0 y otros controles y librerías (o bibliotecas) que se usan habitualmente con las aplicaciones de Visual Basic 6.0, además de que, aunque no esté soportado, hasta el IDE (entorno de desarrollo) de Visual Basic 6.0 sigue funcionando en esos sistemas operativos. Y si la versión de Visual Basic que usaremos es la conocida como VBA, esa vida es más larga, ya que ese lenguaje se incluye con Office, y si no me equivoco, la próxima versión de Office seguirá incluyéndolo, por tanto, se le seguirá dando soporte y seguirá habiendo programadores que lo utilizarán. Pero si ésta es la verdadera cuestión, habría que plantearse otras cosas, particularmente porque en esta revista solo hablamos de .NET y en esta columna en particular, el tema principal es Visual

Basic para .NET, sobre todo en la versión que se incluye con Visual Studio 2008.

PowerPacks y compatibilidad hacia atrás Hace unos párrafos comenté que no tengo instalado ninguno de los PowerPacks de Visual Basic. En realidad solo hay uno, la versión 3.0, que incluye lo que había en los anteriores. La verdad es que si esos controles o componentes que se ofrecen hubieran estado presentes en las primeras versiones de Visual Basic .NET, seguramente me hubiera acostumbrado a ellos, lo mismo que a la posibilidad que tenemos desde Visual Basic 2005 de usar los formularios sin necesidad de crear instancias. Bueno, en realidad esto último dudo que lo llegara a usar, salvo en casos muy contados, porque en mis aplicaciones "clásicas" intentaba evitarlo, ya que es una fuente de problemas que muchas veces son difíciles de detectar, hasta que caes en la cuenta de que estás haciendo las cosas mal. Y es que la manida compatibilidad hacia atrás creo que es más perjudicial que beneficiosa, al menos para los que pretendemos tomarnos en serio la programación, sí, incluso con Visual Basic. Y como resulta que entre unas cosas y otras, en este artículo ya me he pasado un poco, mejor lo dejamos aquí y en próximos artículos hablaremos de esas cosas serias que los programadores de Visual Basic debemos conocer, o al menos, el que escribe esto piensa que debemos educarnos en una mejor forma de hacer las cosas, incluso con un lenguaje que siempre ha tenido tan mala fama, aunque esa mala fama es precisamente por la razón de que este lenguaje sea tan fácil de usar; tanto, que cualquiera es capaz de hacer un programa con Visual Basic, incluso los que no tienen mucha idea. Y esto es lo peor de todo, ya que con la intención de mantener un número alto de desarrolladores que usan este lenguaje, se pretende dejar que se sigan haciendo las cosas como no se deben hacer.

Aunque, también hay que decirlo, seguramente cuando aparezcan las nuevas versiones de C# y de Visual Basic con soporte para la programación dinámica, muchas de las cosas que ahora "detestamos" tendremos que tragárnoslas, al menos si nuestra intención es estar en sintonía con los nuevos tiempos. Por supuesto, esto será así, si lo hacen como hasta ahora tienen previsto, ya que, por ejemplo, en C# se va a permitir la ejecución tardía (o enlace tardío, en inglés late binding), eso que Visual Basic nos permite hacer si desactivamos Option Strict, aunque, por supuesto, al estilo de C#, es decir, incluyendo ese código dentro de un bloque que seguramente estará indicado por la palabra clave dynamic. Pero ese será tema de conversación de los próximos meses o más.

Conclusiones En este artículo no he mostrado mucho código, lo siento, pero quería dejar claros algunos conceptos y temas que a muchos les inquietan. También es cierto que no de dado ninguna solución mágica a esas inquietudes, pero espero haber dado las suficientes pistas para que cada uno decida lo que más le conviene hacer, sobre todo aquellos programadores que no se deciden a "soltar" su viejo código, principalmente por temor. En este aspecto, decirle a todos esos que no quieren cambiar, que cambien; no que cambien su código que ya funciona, porque seguramente será más rápido y hasta es posible que más eficiente que con Visual Basic para .NET. Si funciona bien, ¿para qué cambiarlo? Lo que también digo, y lo digo por experiencia propia, es que si hay que afrontar un nuevo proyecto, lo mejor es hacerlo con los nuevos compiladores; se termina antes y salvo por la curva de aprendizaje, a la larga será más funcional. Afortunadamente, existen revistas como ésta que te explican esas nuevas formas de afrontar las nuevas tecnologías y también hay muchísima documentación que facilita el cambio. Nos vemos en el siguiente número, en el que sí habrá código.


todonet@qa

todotNet.qa@dotnetmania.com

Dino Esposito

Dino Esposito es mentor asociado de Solid Quality Mentors. Es ponente habitual en eventos a nivel mundial.Visite su blog en: http://weblogs. asp.net/despos. (todotNet.QA@ dotnetmania.com)

Asegurarse de que las técnicas son compatibles con la aplicación En términos generales, las técnicas pueden ser muy poderosas, pero podrían no funcionar en un contexto específico. Por esta razón, antes de emplear una característica en una aplicación, deberíamos asegurarnos de que funciona para nuestro caso. Parece algo muy repetido, pero no pueden imaginarse cuántos proyectos fallan por esta causa. Este mes revisaremos un par de pros y contras relacionados con tecnologías ASP.NET.

Estoy considerando incluir SQL Cache Dependency en un sitio Web en el que trabajo actualmente. Mirando la documentación, parece fácil de usar y libre de problemas.Y, de hecho, en mis pruebas funciona bien. Pero me pregunto si estoy pasando algo por alto, y si esta característica escala bien cuando crece el volumen de datos. La caché es una técnica comúnmente utilizada para acelerar el acceso a datos, y se basa en la presunción de que podemos devolver “datos existentes”, en lugar de obtener los más recientes del sistema de almacenamiento. El punto aquí es: ¿con qué frecuencia cambian esos datos? El uso de una caché acelera enormemente las respuestas, pero no hay garantía de que se nos devuelvan datos actualizados. La pregunta es entonces: ¿cuán crítico resulta para la aplicación, o incluso para una página dada, recibir datos actualizados? Normalmente, los datos en caché son mudos y ciegos. Están donde los almacenamos y se quedan hasta que los borramos. No son dinámicos en absoluto y no se actualizan solos. En ASP.NET, sin embargo, se suministran algunos mecanismos para detectar cambios en el estado de la aplicación que pudieran afectar a los datos en caché. El objeto Cache de ASP.NET soporta el concepto de dependencia. Está basado en la suposición de que el sistema operativo informa con prontitud al objeto Cache de qué parte de su contenido está desac-

tualizado. ASP.NET soporta dependencias basada en ficheros o en marcas temporales. El mecanismo basado en ficheros es interesante, porque asocia los datos en caché con un timestamp de un fichero del servidor. Resulta particularmente útil cuando los datos en caché son precisamente los contenidos en el fichero. El sistema se encarga de avisar cuándo cambia el contenido. En ese momento, el gestor de Cache destruye los datos viejos, y la próxima vez que la aplicación los solicite se realizará una consulta al sistema de almacenamiento para actualizarlos. En ASP.NET 2.0, Microsoft añadió dependencia de base de datos mediante la clase SqlCacheDependency, que es el objeto de esta pregunta. Una vez establecida una dependencia entre la tabla de la base de datos y una entrada de la caché, los contenidos de ésta serán invalidados siempre que cambien aquellos de la tabla que representa. Este mecanismo es casi automático y sencillo para el desarrollador. Pero, como puedes sospechar, los problemas aparecen en los detalles.


Tenemos que buscar un balance entre la cantidad de datos en la caché y su frecuencia de actualización

SqlCacheDependency dep = new SqlCacheDependency(cmd); Cache.Insert("MyData", dataSet, dep);

Aquí cmd representa un objeto SQLCommand cuyos resultados van a ir a parar a la caché. Trabajando con el código del objeto Command, se puede modificar el tamaño del conjunto de resultados. Cuando se usa la caché, puede definirse claramente un tiempo de expiración máximo y combinar dependencia de tiempo con dependencia de base de datos. En SQL Server 2005 no se precisa ningún trabajo de configuración sobre la base de datos monitorizada. Si todavía estamos trabajando con SQL Server 2000, necesitamos crear triggers y tablas específicas para soportar esta característica. No obstante, la API de programación permanece casi inalterada.

Tengo una página ASP.NET AJAX que consulta al servidor cada pocos segundos para actualizar algunos contenidos. Recientemente me comunicaron que algunos usuarios finales se olvidan de cerrar el navegador. Desafortunadamente, mi página no es lo suficientemente “lista” como para detectar cuándo hay un usuario activo o no. De forma que establecí un temporizador de cliente que detiene la tarea después de dos horas. El problema es que la tarea consiste simplemente en refrescar un panel usando un control ASP.NET Timer. Y no sé cómo hacer esto programáticamente desde el cliente. El control Timer introducido con ASP.NET AJAX Extensions y mantenido en ASP.NET 3.5 es un envoltorio para un objeto timer de cliente. En particular, el control Timer inyecta código de script que genera un Timer de Javascript y realiza un postback cuando expira el temporizador. Así mismo, el control Timer –un caso único en los controles ASP.NET– expone un modelo de objetos de cliente para ejecutar la mayoría de las operaciones que pueden realizarse sobre él en el servidor. Pero, como has podido experimentar tú mismo, no siempre funciona como debería. El control Timer dispone de una propiedad booleana llamada Enabled. Cuando es verdadera, el timer es reactivado en el cliente; si es falsa, el timer es destruido al final de proceso subsiguiente de postback. ¿Se puede parar desde el cliente un timer de este tipo? Lo prime-

ro es encontrar una referencia a él. Así es como podemos proceder: var clock = $find("<%= Timer1.ClientID%>");

Se puede utilizar el ID del control si no estamos utilizando páginas maestras. La función $find es un alias definido en la librería cliente de AJAX para localizar cualquier instancia de una clase definida en la librería. En este punto, podríamos asumir que un código como el siguiente sería suficiente para detener el timer: clock.set_enabled(false);

No obstante, el método set_enabled únicamente asigna el valor a la variable, pero no detiene el reloj. El

<<dotNetManía

Si los datos de la tabla cambian muy frecuentemente, la caché se actualiza frecuentemente, y esto acaba por añadir presión a la gestión de la base de datos. Estrechamente relacionado con la frecuencia, nos encontramos con el tamaño de los datos en caché. Cuantos más datos en la caché, mayor impacto va a tener su actualización sobre la base de datos cuando algo cambie. Se trata, pues, de una posibilidad interesante, pero tampoco es una solución mágica para acelerar las aplicaciones. Podemos fiarnos de esa tecnología, pero tenemos que buscar un balance entre la cantidad de datos en la caché y su frecuencia de actualización. Tenemos que conocer nuestros datos. Si tienen demasiados registros, hay que estar preparado para recargarlos al más mínimo cambio. Y, si la probabilidad de esos cambios es alta, pueden surgir problemas. Por otro lado, con muy pocos registros tendremos poca sobrecarga. ¿Cómo modular el tamaño de la caché de dependencia? En SQL Server 2005, una caché de dependencia se define sobre una tabla como el resultado de un comando de consulta, tal y como vemos en el siguiente código:

TodotNet.qa@dotnetmania.com TodotNet.qa@dotnetmania.com

<< dnm.todonet@qa

49


<<dotNetManía T o d o t N e t . q a @ d o t n e t m a n i a . c o m T o d o t N e t . q a @ d o t n e t m a n i a . c o m

<< dnm.todonet@qa

50

método dispose sí que lo haría, pero destruyendo el objeto, que no podría ser reactivado más adelante. El truco está en llamar al método interno del Timer Javascript, de nombre _stopTimer. clock._stopTimer();

El hecho de que el nombre de este método comienza por subrayado indica que es un miembro privado, y, por tanto, no debería de llamársele desde fuera de la clase. Pero, por el momento, sí que funciona y es la única manera de realizar la tarea.

Estoy teniendo problemas con un sencillo servicio WCF que quiero exponer a clientes AJAX. Lo creé utilizando el asistente de Visual Studio 2008 y no cambié nada significativo de la configuración. Me di cuenta de que en el código producido se añade un atributo AspNetCompatibilityRequirements. Si quito el atributo, el servicio no funciona, pero en la documentación pone que el atributo es opcional. Seguramente me falta algo, pero ¿qué?

Una petición dirigida a un servicio WCF es una petición a una URL con la extensión .svc. La petición es capturada por IIS y manejada a través de ASP.NET. Se realiza una autenticación y se pasa a la pila de WCF para su procesamiento. La petición nunca vuelve a la cadena de proceso ASP.NET. El servicio WCF es alojado por IIS y funciona en colaboración con ASP.NET, pero de forma totalmente separada. Esto quiere decir que ningún servicio WCF puede acceder a HttpContext o a ASP.NET de forma intrínseca. No hay fichero o autorización URL que se pueda configurar en un recurso .svc. No es posible la suplantación (impersonation). Para que esto pueda suceder, hay que modificar el atributo de compatibilidad en la clase de servicio WCF:

WCF sirve peticiones de una forma mucho más desligada e independiente del transporte y el alojamiento

[AspNetCompatibilityRequirements( RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] public class TimeService : ITimeService { //... }

¿Cuándo necesitas realmente compatibilidad con ASP.NET? Tanto WCF como ASP.NET sirven peticiones entrantes, pero WCF lo hace de una forma mucho más desligada e independiente del transporte y el alojamiento. Un servicio WCF puede ser utilizado en múltiples sitios e incluso utilizar diferentes asociaciones (bindings) y sus hosts no tienen que ser compatibles con ASP.NET. Al mismo tiempo, un servicio WCF que se diseña únicamente para su utilización en aplicaciones ASP.NET se integra mejor con ASP.NET. Hay que notar que esa integración se produce en dos niveles: aplicación y servicio. Se necesita la siguiente

sección en el fichero Web.config para habilitar la compatibilidad con todos los servicios bajo control del fichero de configuración: <system.serviceModel> <serviceHostingEnvironment aspNetCompatibilityEnabled="true" /> </system.serviceModel>

A continuación, cada servicio puede declarar cómo debe comportarse respecto a la compatibilidad utilizando el atributo AspNetCompatibilityRequirements. Los valores posibles son: NotAllowed (predeterminado), Required y Allowed. Si se elimina el atributo, el servicio no puede funcionar en modo de compatibilidad. Como los valores en el fichero Web.config habilitan la compatibilidad para todos los servicios de la aplicación, obtenemos una excepción. Puedes deshabilitar la compatibilidad a nivel de aplicación, o hacerla requerida o permitida para cada uno de los servicios.

Traducido al castellano por Marino Posadas


Laboratorio.net

<< dnm.laboratorio.net

Octavio Hernández

Crystal Reports 2008 Este mes presentamos las nuevas características que ofrece la versión más reciente de otra de mis herramientas habituales, en este caso una con la que llevo trabajando más de una década en roles tan diferentes como los de formador, consultor, proveedor de soporte técnico o usuario avanzado. Se trata de Crystal Reports, sin duda alguna el software con mayor solera dentro de la categoría de los generadores de informes.

Developer) del producto, sino que la única edición existente (con un precio de salida muy competitivo) incluye todas las posibilidades que antes se reservaban únicamente a la edición superior. • En versiones anteriores, el despliegue de aplicaciones Web (pero no Windows) que utilizaran el motor de Crystal Reports requería el pago de royalties, aun cuando se tratara del servidor Web corporativo de nuestra propia empresa. En la versión actual se ha eliminado este requisito. • Esta nueva versión incluye varias facilidades que antes presentaban limitaciones o solo estaban disponibles a través de productos de terceros, como la posibilidad de creación y modificación dinámica de informes, la internacionalización o el soporte para códigos de barras.

• A diferencia de versiones anteriores, ya no existen diferentes ediciones (Standard, Professional,

La tabla 1 presenta en formato resumido todas las novedades incorporadas a Crystal Reports 2008.

Ficha técnica Nombre: Crystal Reports Versión: 2008 (12, según la numeración interna) Fabricante: Business Objects (SAP) Sitio Web: http://www.businessobjects.com/ Categoría: Generadores de informes Precio: • Producto completo: 479 EUR + IVA • Actualización: 299 EUR + IVA • Visual Studio 2008 Professional y superiores incluyen Crystal Reports 2008 Basic Edition, desde el cual es posible actualizarse al producto completo.

<<dotNetManía

Octavio Hernández es Mentoring Team Leader de Plain Concepts, editor técnico de dotNetManía y tutor de campusMVP. Es MVP de C# desde 2004, MCSD y MCT.

En este mundo de hoy, en el que cada vez la competencia es mayor y se acortan más los plazos que median entre la concepción un sistema y el momento de su implantación, la palabra de orden es, necesariamente, productividad. Y ese ha sido siempre uno de los puntos fuertes de Crystal Reports, muy probablemente la herramienta de creación y procesamiento de informes más popular del planeta, gracias en buena medida al hecho de que viene siendo embebida de una forma u otra dentro de las diferentes versiones de Visual Studio y Visual Basic desde hace más de una década. En esta nueva versión, ya preparada para Visual Studio 2008, Crystal Reports integra dentro del entorno de desarrollo el diseñador de informes, un conjunto de ensamblados que encapsulan el motor de procesamiento de informes, herramientas personalizadas para la generación de clases .NET y componentes para el desarrollo rápido de aplicaciones Windows y Web que incorporen informes Crystal. Todo eso, unido a las bondades innatas del producto y de su arquitectura (que se muestra en la figura 1), hace posible optimizar al máximo el proceso de creación de informes y su integración en aplicaciones .NET de cualquier tipo. Antes de hacer un repaso general del proceso de creación de un informe Crystal dentro de Visual Studio 2008 (aunque quienes se actualicen a la versión completa de Crystal Reports 2008 tendrán también la posibilidad de lanzar el diseñador de manera independiente) y su consumo desde una aplicación Windows Forms, quisiera destacar tres aspectos importantes que aparecen por primera vez con Crystal Reports 2008 y que podrían ayudar a tomar una decisión sobre la adquisición de esta versión del producto:

51


<< dnm.laboratorio.net

Figura 1. Arquitectura de Crystal Reports CREACIÓN DE POTENTES DATA MASHUPS Driver para obtener datos de servicios Web, con soporte de codificación RPC de mensajes SOAP, SSL y estándares WS- Security, entre otras facilidades. Integración con Xcelsius, Adobe Flex y Adobe Flash: integración sencilla de componentes diseñados en Flash y Flex. AHORRO DE TIEMPO DE DISEÑO Mejoras en el diseñador, como la búsqueda de fórmulas, duplicación de fórmulas y acumulados o completamiento automático de nombres de campos. Internacionalización: permite adaptar los informes en tiempo de diseño y ejecución al idioma y convenios locales. Soporte nativo para códigos de barras: permite representar campos como códigos de barras fácilmente y sin codificación alguna. Huella de instalación reducida: los tamaños de las librerías a incorporar en las aplicaciones se han reducido de manera significativa. MAYORES POSIBILIDADES VISUALES Integración con Adobe Flash: los datos del informe pueden ser accedidos desde los ficheros Flash (SWF) para hacer posibles informes espectaculares e interactivos. Potentes tablas cruzadas: múltiples nuevas características hacen posible la creación de tablas cruzadas mucho más potentes que las de versiones anteriores. Paginación flexible: múltiples novedades relacionadas con la paginación hacen posible, entre otras facilidades, combinar en un mismo informe distintas orientaciones de folios, tamaños de páginas, etc. NUEVAS POSIBILIDADES DE INTERACCIÓN Integración con Xcelsius: hace posible el análisis dinámico de diferentes escenarios, lo que facilita la toma de decisiones. Integración con Adobe Flex: hace posible integrar flujos operacionales desarrollados en Flex dentro de informes. Visualización interactiva: los visores de informes para aplicaciones Windows y Web permiten la ordenación, filtrado y reformateado dinámicos, de modo que los usuarios puedan analizar la información. Panel de parámetros: el diseñador y los visores ofrecen un panel de parámetros en el que se puede modificar los valores de los mismos.

<<dotNetManía

NUEVAS FACILIDADES DE DESPLIEGUE

52

Guardar informes en crystalreports.com: le permite gestionar y compartir informes de manera segura. Driver de salesforce.com integrado: permite acceder a los datos de esa popular sistema. Exportación mejorada a XML: ahora es posible embeber transformaciones XSLT dentro de los informes, para que se disparen al exportar a XML. SDK de modificación de informes: ahora está disponible para los que utilicen la API de Crystal Reports para .NET, sin necesidad de disponer de un servidor RAS. Tabla 1. Novedades en Visual Studio 2008


<< dnm.laboratorio.net

Creando una aplicación básica Para aquellos que no estén familiarizados con el desarrollo de aplicaciones .NET que consuman informes Crystal, presentamos un pequeño tutorial basado en una aplicación Windows Forms. Y para que éste sea de algún interés también a quienes ya han utilizado alguna versión anterior del producto, haremos uso de algunas de las nuevas facilidades que ofrece Crystal Reports 2008. Utilizaremos, como es ya habitual, la base de datos FUTBOL2006 de mi libro “C# 3.0 y LINQ” [2]. El infor-

Figura 3. El informe de ejemplo en ejecución

<<dotNetManía

Figura 2. Se genera un fichero de código fuente que define un informe tipado

me a desarrollar permitirá listar toda la plantilla de un club cualquiera, cuyo valor se determinará en tiempo de ejecución y por lo tanto será un parámetro del informe. Puede descargar la base de datos y todo el código del ejemplo del sitio Web de la revista. Tenga en cuenta que necesitará al menos la versión de evaluación de Crystal Reports 2008 para ejecutar la aplicación de ejemplo, puesto que he hecho uso de nuevas características en el informe y utilizado los ensamblados de la nueva versión. Para comenzar, creamos una nueva aplicación Windows Forms (lenguaje C#) y sobre el nodo del proyecto, seleccionamos la opción “Agregar” | “Nuevo elemento” | “Crystal Report”, dándole el nombre PlantillaClub.rpt. El diseño de informes, que no describiremos aquí, puede acometerse dentro del entorno integrado utilizando un asistente de múltiples páginas o partiendo desde cero. En cualquier caso, recomendamos el estudio del informe de ejemplo, pues incluye algunos elementos no triviales como grupos anidados, fórmulas y parámetros. Los informes incorporados a un informe pasan a formar parte de él en calidad de recurso embebido. Al mismo tiempo, se genera un fichero de C# (figura 2) que define un informe tipado: una clase heredera de la clase ReportClass de Crystal Reports, que extiende y personaliza ésta última de modo similar a como un DataSet tipado extiende la clase DataSet. En este punto, podemos empezar a hacer uso de los componentes que agrega Crystal Reports 2008 al Cuadro de herramientas para aplicaciones Windows

53


<< dnm.laboratorio.net

Actualidad La única edición de Crystal Reports 2008 incluye todas las posibilidades que antes se reservaban únicamente a la edición superior

Telelogic Modeler. Entorno gratuito de modelado basado en UML 2.1 La multinacional sueca Telelogic ha puesto a disposición del público Telelogic Modeler, un entorno gratuito de modelado basado en UML 2.1 para el diseño y la documentación de sistemas y software. Desarrollada por uno de los autores de UML 2.0 y basada en tecnologías utilizadas por el fabricante en productos comerciales como Raphsody o Tau, esta herramienta ofrece la posibilidad de capturar y documentar los diseños de una manera clara y eficiente.

Forms. En primer lugar, utilizaremos CrystalReportViewer, el componente que se utiliza para visualizar los informes. Este componente visual se enlaza a una instancia de documento (informe) a través de la propiedad ReportSource, que ofrece un editor personalizado que nos permite indicar que vamos a utilizar como origen del informe una instancia del componente CrystalReportDocument asociada a una instancia de nuestra clase PlantillaClub. El visor de informes ofrece toda una serie de propiedades para configurar su barra de herramientas. Los que conozcan versiones anteriores de este componente encontrarán dos nuevas propiedades: ShowParameterPanelButton y ToolPanelView, que permiten activar el nuevo Panel de parámetros, que facilita en gran medida la ejecución repetida de un informe con diferentes valores de sus parámetros. La apariencia final de la aplicación, en la que se puede ver este nuevo panel, se presenta en la figura 3.

Conclusiones

<<dotNetManía

Crystal Reports 2008 es la nueva versión de uno de los líderes del mercado en el área de la generación de informes, y gracias a la integración completa con Visual Studio 2008 que ofrece, pone a disposición de quienes desarrollan software para la plataforma .NET todos los recursos necesarios para la creación, mantenimiento e integración en aplicaciones de potentes informes de una manera sencilla y altamente productiva.

54

Entre las principales características de este producto, podemos destacar las siguientes: • Entorno de diseño orientado a los modelos: los diagramas forman un modelo unificado, permitiendo que Modeler oriente al usuario en el desarrollo de aplicaciones completas y correctas. • Modelado robusto: entre los diagramas UML 2.1 soportados se incluyen los diagramas de actividad, clases, componentes, estructuras compuestas, despliegue, interacción, objetos, paquetes, máquinas de estado, secuencias y casos de uso. • Características avanzadas: Modeler soporta elementos UML 2.1 complejos, como la herencia de máquinas de estado o los modelos de actividad detallados. • Documentación integrada: los diseños pueden ser documentados y comunicados de forma automática. Para más información y descarga de la herramienta, visite http://www.telelogic.es/products/modeler/index.cfm.

Referencias [ 1 ] Sitio Web de Crystal Reports 2008: http://www.businessobjects.com/product/catalog/crystalreports. [ 2 ] Hernández, O. “C# 3.0 y LINQ”, Krasis Press, noviembre de 2007.


biblioteca.net Novedades de Visual Basic 9.0 Guillermo “Guille” Som Editorial: Solid Quality Press Páginas: 206 Publicado: marzo de 2008 ISBN: 978-8493641702 Idioma: castellano

Dto. 50% para suscriptores Usando el cupón dnm3103, válido para este mes de abril en http://www.solidq.com/lib/ eBookDetail.aspx?Id=1

En este excelente libro, que se distribuye en formato electrónico, nuestro redactor y columnista Guillermo “Guille” Som (para mí siempre “El Maestro”) nos presenta, con el estilo ameno y asequible al que nos tiene habituados, una minuciosidad absoluta y una gran profusión de ejemplos que hacen aún más fácil la comprensión del material, las nuevas características incorporadas por Microsoft a Visual Basic 9.0, la versión del popular lenguaje implementada en .NET Framework 3.5 y Visual Studio 2008. En particular, a lo largo de los últimos cuatro capítulos se describen con lujo de detalles las nuevas posibilidades relacionadas con LINQ; incluyendo, por supuesto, aquellas que solo están disponibles en Visual Basic y que probablemente el lector que se haya acercado a esta tecnología desde C# aún no conozca. Pensamos honestamente que este libro es todo lo que necesitará cualquier programador de versiones anteriores del lenguaje (y en particular de la versión 8.0, materializada en Visual Studio 2005 y sobre la que “Guille” ha producido abundante documentación, mucha de ella disponible públicamente en su sitio Web) para ponerse al día con respecto a las nuevas características que ofrece la más reciente versión de Visual Basic. Absolutamente recomendado.

C# 3.0 Cookbook Jay Hilyard y Stephen Teilhet Editorial: O’Reilly Páginas: 886 Publicado: enero de 2007 ISBN: 978-0596516109 Idioma: inglés

novedades

Este conocido “manual de recetas” de programación en C# es sistemáticamente uno de los libros mejor valorados por los lectores en todos los foros sobre el lenguaje en los que participamos. De corte eminentemente práctico y orientado principalmente a programadores de nivel medio y medio-avanzado, incluye más de 250 soluciones a problemas de programación comunes (y no triviales) que suelen presentarse con frecuencia durante el desarrollo de software para la plataforma .NET, cubriendo numerosos aspectos tanto del lenguaje como de la Librería de Clases Base. La edición más reciente incluye múltiples referencias a las nuevas características incorporadas a C# 3.0, y en particular un capítulo dedicado a LINQ; pero pensamos que, a pesar de ello, éste no es “el fuerte” del libro, y si usted piensa en comprarlo (algo que sin duda alguna recomendamos), deberá hacerlo más pensando en su valor integral que en lo que le enseñará acerca de estas novedades.

Essential Windows Communication Foundation Steve Resnick, Richard Crane, Chris Bowen. Editorial: Addison-Wesley Professional. Páginas: 608. ISBN: 978-0321440068. Fecha de publicación: febrero de 2008.

Understanding Windows CardSpace Vittorio Bertocci, Garrett Serack, Caleb Baker. Editorial: Addison-Wesley Professional. Páginas: 384. ISBN: 978-0321496843. Fecha de publicación: enero de 2008.

TEXTO: OCTAVIO HERNÁNDEZ


comunidad.net Second Nug Grupo de usuarios de .NET Online

Second Nug

<<dotNetManía

• Ubicación: online • Fecha de fundación: mayo de 2007 • Fundador: Toni Recio y José Luis Cubero • Miembros: 13 • Página: http://www.secondnug.com • Email de contacto: contacto@secondnug.com

56

¿Alguna vez os habéis quedado con ganas de asistir a algún evento de un grupo de usuarios? En este contexto nace la idea de buscar algún medio para poder hacer llegar la labor de la comunidad al mayor número de usuarios posible, permitiendo complementar su labor haciendo uso de Internet, potenciando la idea de un grupo virtual donde las barreras físicas ya no sean un impedimento y haciendo uso de nuevas tecnologías que nos permitan explotar otras posibilidades. Es por ello que tomando como excusa la celebración del día del Orgullo Friki, Toni Recio y José Luis Cubero deciden intentar crear un grupo de usuarios que intente complementar la amplia oferta de NUG en España haciendo uso de un mundo virtual como es SecondLife, donde Microsoft venía invirtiendo mucho dinero y donde curiosamente la lógica de dicho mundo está programada con .NET. Pasados los días, esa idea me fue transmitida de casualidad mientras Toni y yo comentábamos los nuevos hilos del foro de MSDN. Así pues, me sumé al

carro de Second Nug, colaborando para reunir a más gente y a concretar ideas y tecnologías. En un principio íbamos a seguir la idea inicial de usar Second Life y vídeo en directo vía streaming, para retransmitir eventos propios y para tratar que los grupos presenciales se animaran a compartir sus charlas por ese medio. Hubo muchos contactos con grupos anglosajones dentro de Second Life. En esa fase del proceso, David Salgado de Microsoft nos ayudó a mover el tema, pero las limitaciones técnicas del entorno virtual que plantea Second Life no ayudaban a acabar de lanzar el proyecto. Second Nug no despega hasta que en octubre de 2007 fuimos invitados al Train The Trainers de Microsoft. Compartiendo nuestras ideas con el resto de grupos, Alfonso Rodríguez de MSDN nos propuso un nuevo medio para llevar a cabo nuestras ideas: la tecnología Live Meeting de Microsoft, herramienta que a las pocas pruebas nos demostró que nos venía como anillo al dedo. Ya no había excusas, ¡Second Nug podía empezar a andar! Concretamos un día (el primer martes de cada mes) y un tema y convencimos a nuestro primer ponente Marçal Serrate para que nos diera en febrero una más que amena charla sobre CSLA.NET, a la que asistieron una treintena de personas y a la que cualquiera todavía puede asistir, ya que nuestros even-


<< dnm.comunidad.net Visual Basic .NET vs C# .NET: ¿Cual es mejor y por qué? Martes 6 de mayo de 2008, 19:30h - 21:30h (GMT+1) Ponentes: • Guillermo Som, MVP de Visual Basic • Marino Posadas, MVP de C# Second Nug tiene el honor de presentar a dos ponentes de excepción, Guillermo Som (el Guille) y Marino Posadas (el Ave Fénix), en la que será una gran batalla donde dos voces con gran experiencia expondrán sus mejores bazas en un duelo sin igual: VB .NET vs C# .NET.

tos se graban y son accesibles para su descarga desde la propia página de Microsoft. Nuestro grupo ha ido ampliándose con la integración de varias de las personas implicadas en la colaboración de diversas comunidades técnicas de Microsoft como el Foro de MSDN y otros grupos de usuarios, y una vez en marcha volvimos a la idea de colaborar para retransmitir eventos presenciales, y aprovechamos que Toni iba a LoNetCamp a dar una charla sobre Windows Presentation Foundation para ayudarles y guiarles en la retransmisión online del evento. En la actualidad, seguimos con nues-

Sabremos por qué se decantaron por un lenguaje u otro y nos presentarán la evolución de éstos en las nuevas versiones del .NET Framework. Nos desvelarán secretos y trucos de sus defendidos y veremos si es cierto aquello de que lo que se puede hacer con uno, se puede realmente hacer con el otro. Además, los asistentes podrán resolver sus dudas preguntando a nuestros expertos y participar en el resultado final de la contienda. El eterno dilema al descubierto. ¿Quién será el vencedor? Más información en: http://www.secondnug.com

tro empeño de animar y ayudar a otros grupos a que se animen a compartir su labor con todos nosotros. Mientras escribo estas líneas, en Second Nug ya estamos preparando nuestro segundo evento (el de marzo), “Presentando informes: Reporting Services vs. Crystal Reports” con Fran Díaz y Carmen Sánchez, del que podréis disfrutar en diferido cuando leáis estas líneas. Y la cosa no acaba aquí, ya que para el 1 de abril, Hadi Hariri nos obsequiará con una charla sobre WCF a la que espero os animéis a acompañarnos. Para obtener toda la información sobre los eventos y todo lo relacionado

con Second Nug, podéis visitar el sitio Web, que cuenta con un aspecto renovado y más funcional gracias en buena medida a Carmen Hernández, que además nos ayuda a crear los carteles de los eventos. Esperamos que nuestro espíritu de compartir los conocimientos más allá de las fronteras geográficas de los NUG actuales se vaya contagiando poco a poco y pronto podamos ver eventos que, como los nuestros, puedan ser disfrutados desde cualquier lugar del mundo en vivo o en diferido.

Javier Conesa

Conclusión y entrega de premios del Desafío Silverlight El 27 de febrero se realizó la entrega oficial de premios del Desafío Silverlight, el concurso organizado por BcnDev, el grupo de usuarios de Barcelona, y patrocinado por Microsoft Ibérica, Avanade, IN2, Anaya, dotNetManía y otras empresa fabricantes de software (ver http://desafiosilverlight.bcndev.net ). En esta competición, se eligieron las mejores aplicaciones de Silverlight en base a criterios de código, diseño, innovación e utilidad. El total de premios superó los 20.000€, lo que es muy destacable para una competición de tal índole, y como parte del primer premio teníamos un viaje al MIX 2008 (ver págs. 6-7). Aunque hubo muchas participaciones excelentes, solo podía haber un ganador, que se llevó el viaje al MIX, viaje a Las Vegas, hotel y entrada incluidos. Todo ello junto con el título de “Mejor desarrollador Silverlight de España”, que no es poco. El ganador desarrolló la aplicación “Weather Viewer”, un original mashup que accede a varios servicios de una forma original y con muy buena realización. Este galardón y premios correspondieron a Francisco Gómez Martín. Sobre los jueces, nos han honrado con su votación:

• Arturo Toledo, responsable de producto de Microsoft Expression, en la parte de diseño. • María Vila, directora de innovación de Barcelona Activa, en la parte de innovación. • Damir Tomicic, presidente de INETA Europa, en la parte de código. • Alfonso Rodríguez, director de MSDN España, en la parte de utilidad. En cualquier caso, agradecer a los patrocinadores por su excelente soporte y apoyo a esta iniciativa, especialmente a Microsoft, Avanade, IN2, Anaya Multimedia y dotNetManía. Sin ellos esta competición no habría sido posible. ¡Muchísimas gracias a todos! El equipo de BcnDev

eventos.eventos.eventos.eventos.eventos.eventos


desván

Marino Posadas

<<dotNetManía

¿Qué hay de nuevo, viejo?

58

Como sabe el lector habitual, en esta sección comentamos a menudo noticias científicas relacionadas con el tratamiento de la información, y –de hecho- nuestro conocimiento (siquiera superficial) de algunas de esas iniciativas de I+D de Microsoft nos hace reaccionar con asombro ante comentarios en el sentido de “¿qué es lo que Microsoft investiga realmente?”, por la falta de información que denotan. Y es que, a veces, como reza el refrán, “no basta con serlo, sino que también hay que parecerlo”. Justo con ese espíritu de dar a conocer los trabajos de investigación de la compañía se ha celebrado en el campus de Redmond, EE.UU. TechFest 2008, donde los investigadores han sorprendido con iniciativas tan variopintas, que muchas de ellas no son directamente aplicables a la informática, pero tienen un innegable valor científico. Vea http://research.microsoft.com/techfest con interesantes vídeos explicativos de algunas de las propuestas más relevantes, como Microsoft WorldWide Telescope, que lideró durante años el Premio Turing James Gray (desaparecido el año pasado y a quien tuvimos ocasión de entrevistar para dotNetManía en el nº 12). Se trata de poner a disposición de los investigadores de todo el mundo terabytes de información recopilada por todos los telescopios activos del globo, incluso haciendo disponible una herramienta para su visualización, donde uno puede llegar a programar sus propios “tours” por el universo (vea el vídeo publicado en http://gizmodo.com/361728/microsoft-worldwide-telescope-in-awesomevideo-action-verdict-my-god-its-full-of-stars). Otros desarrollos sí son directamente aplicables –y deseables–, como un dispositivo táctil que permite seleccionar los elementos a través de la parte posterior del aparato (Lucid Touch), o los trabajos sobre orígenes de datos protegidos y consultas con privacidad integrada, sobre los que trabajan los equipos de diseñadores de LINQ y que protegen la información de las tuplas de entrada y agregan nuevos niveles de privacidad al proceso de recuperación y almacenamiento de la información. ¿Y qué sucede con el día a día? En el sitio antes citado podrán leerse multitud de iniciativas de toda clase, pero me gustaría citar algunas que prometen mostrar sus primeros bits (en fase beta) muy pronto. Uno de ellas es Stirling, producto en beta privada, que consolida muchos de los esfuerzos de la compañía en materia de seguridad, incluyendo ForeFront, de forma que se pueda tener gestión unificada de los sistemas de seguridad tanto en el servidor como en el cliente. Y es que la lucha por la seguridad no cesa, ni debe hacerlo. De ahí el anuncio reciente de la compra de la empresa cuyo producto estrella era un detector de rootkits (Komoko). Y de ahí que se hable de todo un nuevo sistema de gestión de correo administrado para las empresas que permita cumplir con normativas y políticas de trabajo (Employee Managed Mailbox, EMM). También suena Albany, un nuevo producto asociado con Microsoft Office, pero más al estilo del antiguo Microsoft Works, esto es, para usuarios domésticos principalmente, y que funcionaría –si es cierto el rumor– asociado a las nuevas plataformas de publicidad y presencia que la compañía prepara ahora y veremos en muchos productos en el futuro cercano. Y eso, con Office Live Workspace actualmente en beta, y anuncios iniciales de lo que promete la nueva versión “Office 14”, especialmente en innovaciones en las áreas de colaboración en línea y presencia de los productos en el servidor. ¿Innovación? Sí, gracias.

noticias.noticias.noticias

documentos en la red Top Ten software Easter Eggs consiste en una recopilación de los más afamados “Huevos de Pascua” (comportamientos no conocidos o sorpresivos) que podemos encontrar en el software más popular: Internet Explorer, Firefox, Google Earth, Picasa, etc. Puede leerse en http://lifehacker.com/371083/top-10-software-easter-eggs. Shut down Windows in an instant. Como dice su autor, Dennis O’Reilly, algunos programas no saben cómo decir adiós. Tras un poco de investigación, descubrió cómo hacer que eso no sea un problema, y los sistemas operativos se apaguen en un instante. Disponible en http://www.cnet.com/8301-13880_1-9900788-68.html?part =rss&subj=news&tag=2547-1_3-0-20).

blogs del mes Blog de Martin Maly. Se trata del creador de muchos de los avances relacionados con lenguajes dinámicos (IronRuby, IronPython, y el propio Dynamic Language Runtime DLR). Precisamente ahora acaba de anunciar la disponibilidad de la Beta 1 del DLR: http://blogs.msdn.com/mmaly. Blog de Chris Love. MVP en ASP.NET, igualmente experto en SharePoint. Muchas entradas de interés relacionadas con ambas tecnologías, noticias, entrevistas y reflexiones sobre el desarrollo del “Windows Client”: http://professionalaspnet.com.

utilidades del mes TechSupport: un sitio de utilidades. Uno de los sitios especializados en recopilar utilidades de interés, ya sea para desarrollo o para sistemas. En la página recomendada se analizan las “46 Best-ever Freeware Utilities”, que aparte de ser muy buenas herramientas, son gratuitas. Accesible en http://www.techsupportalert.com/best_46_free_utilities.htm.

RunAsDate. Como su nombre indica, permite ejecutar un programa “desde otra fecha”, como si el sistema operativo tuviese cambiada la fecha del sistema. Es gratuito y está disponible en http://www.freewarefiles.com/RunAsDate_program_32729.html.


dotNetManía #047  
Read more
Read more
Similar to
Popular now
Just for you