dedicada a los profesionales de la plataforma .NET Silverlight 2 · edad, ¡como lo oyen!— una...

68
eventos Imagine Cup 2008 ¡Ganamos! entrevistas Joe Marini Director del Visual Studio Industry Partners Program David Silverlight Fundador de Community Credit Silverlight 2.0 Animation System • Silverlight DataGrid • Comunicaciones en Silverlight • Webparts Silverlight para SharePoint WPF, DirectX y los gráficos tridimensionales Acceso a ficheros con Visual Basic WPF, DirectX y los gráficos tridimensionales Acceso a ficheros con Visual Basic Silverlight 2.0 dedicada a los profesionales de la plataforma .NET www.dotnetmania.com entrevistas Joe Marini Director del Visual Studio Industry Partners Program David Silverlight Fundador de Community Credit dotNetManía nº 51 septiembre 2008 6,50 Visual Basic • C# • ASP.NET • ADO.NET • AJAX • Silverlight • .NET Framework eventos Imagine Cup 2008 ¡Ganamos! dotNetManía Silverlight 2.0 Animation System • Silverlight DataGrid • Comunicaciones en Silverlight • Webparts Silverlight para SharePoint Silverlight 2.0 Excepciones en ASP.NET y gestión excepcional de formularios Además... Excepciones en ASP.NET y gestión excepcional de formularios TodotNet@QA

Transcript of dedicada a los profesionales de la plataforma .NET Silverlight 2 · edad, ¡como lo oyen!— una...

eventos

Imagine Cup 2008¡Ganamos!

entrevistas

Joe MariniDirector del Visual Studio Industry Partners Program

David SilverlightFundador de Community Credit

Silverlight 2.0 Animation System • SilverlightDataGrid • Comunicaciones en Silverlight •

Webparts Silverlight para SharePoint

WPF, DirectX y los gráficos tridimensionalesAcceso a ficheros con Visual BasicWPF, DirectX y los gráficos tridimensionalesAcceso a ficheros con Visual Basic

Silverlight 2.0dedicada a los profesionales de la plataforma .NET

www.

dotne

tman

ia.co

m

entrevistas

Joe MariniDirector del Visual Studio Industry Partners Program

David SilverlightFundador de Community Credit

dotNetManíanº 51 septiembre 2008 6,50 € Visual Basic • C# • ASP.NET • ADO.NET • AJAX • Silverlight • .NET Framework

eventos

Imagine Cup 2008¡Ganamos!

dotNetManía

Silverlight 2.0 Animation System • SilverlightDataGrid • Comunicaciones en Silverlight •

Webparts Silverlight para SharePoint

Silverlight 2.0

Excepciones en ASP.NET y gestión excepcional de formularios

Además...

Excepciones en ASP.NET y gestión excepcional de formulariosTodotNet@QA

Bienvenido al número 51, de septiembre de2008, de dotNetManía.

Poco después de que Avalon perdiera sumagnífico nombre en clave para convertir-se en WPF, apareció su hermano pequeñopreparado para ejecutarse en cualquier nave-gador de cualquier plataforma. Su nombre:WPF/E (la “E” de “Everywhere”). Pero parasorpresa de todos, éste era el nombre en cla-ve y su nombre definitivo acabaría siendoSilverlight. Justo al contrario de lo acostum-brado por Microsoft, su fabricante. Para aña-dir algo de misterio a esta nomenclatura,David Silverlight, un reconocido MVP yfundador del proyecto Web 2.0 denomina-do Community Credit, al que José LuisLatorre entrevista en este número, aseguraser el culpable de este nombre, incluso haberhablado al respecto con el propio Bill Gates.Cierto o no, al menos resulta más divertidode lo acostumbrado.

Silverlight 2.0 está levantando una granexpectación a nivel mundial. Prueba de elloes que la cadena televisiva norteamericanaNBC lo ha utilizado para sus reproductoresmultimedia durante las olimpiadas ¡en ver-sión beta aún! Nosotros no íbamos a sermenos y nos hemos lanzado a preparar esteespecial sobre Silverlight cuando aún notenemos en la mano la versión definitiva, sibien todos sabemos que está al caer.

Este especial Silverlight ha sido coordina-do por Marino Posadas, quien además estápreparando el libro “Silverlight 2.0 para desa-

rrolladores”, y una de las personas que más sabesobre este tema. El resto de artículos los pre-senta él mismo en “Especial Silverlight”.

Independientemente del tema central deeste mes, entrevistamos a Joe Marini, direc-tor del denominado Visual Studio IndustryPartners Program en Microsoft Redmond.

Además, y de temática afín, el grupoWeboo, de la Universidad de La Habana,propone el artículo “WPF, DirectX y los grá-ficos tridimensionales”, que pretende hacerun primer recorrido por los conceptos bási-cos de los gráficos por ordenador y mostrarcómo se manifiestan éstos en DirectX y WPFen lo referente al modelado y al procesamien-to gráfico.

Guillermo “Guille” Som sigue desdesu “Isla VB” aportando sus derechos de autora la causa de Juanma. Su artículo “Acceso aficheros con Visual Basic. Usar clases de.NET o no usarlas…” es una buena excusapara hacer un nuevo llamamiento para ayu-dar a este niño.

No quiero terminar sin anunciarles ladespedida de nuestro editor técnico, Octa-vio Hernández, al que todos ustedes cono-cen sobradamente. Octavio empieza —a suedad, ¡como lo oyen!— una nueva etapa pro-fesional. Quiero agradecerle públicamentelas horas dedicadas a este proyecto, y porsupuesto, desearle la suerte que merece: lamejor de todas.

Y nada más, espero que nuestro trabajode este mes sea de su agrado.

dotN

etM

anía

<<

3

Silverlight, codename WPF/E

editorialDedicada a los profesionales de la plataforma .NET

Vol. III •Número 51 • Septiembre 2008Precio: 6,50 €

EditorPaco Marín ([email protected])

Redactor jefeMarino Posadas([email protected])

RedacciónDino Esposito, Guillermo 'Guille' Som, LuisMiguel Blanco y Miguel Katrib (Grupo Weboo)

Empresas colaboradoras

Alhambra-Eidos

Krasis

Plain Concepts

Raona

Solid Quality Mentors

Además colaboran en este númeroBraulio Díez, José Luis Latorre, LudwigLeonard, Miguel Llopis, Reyes García y YamilHernández.

IlustracionesPortada: Javier Roldán

Atención al suscriptorPilar Pérez ([email protected])

Edición, suscripciones y publicidad.netalia

c/ Robledal, 13528522 - Rivas Vaciamadrid (Madrid)

www.dotnetmania.com

Tf. (34) 91 666 74 77Fax (34) 91 499 13 64

ImprimeGráficas MARTE

ISSN1698-5451

Depósito LegalM-3.075-2004

dotNetManíadotNetManía

Paco Marín

sumario 51Eventos. Imagine Cup 2008 8-10

Entrevista a Joe Marini 10-12Joe Marini es director del denominado Visual Studio Industry Partners Program que el propioMarini definía como el “Development Tools Ecosystem Team” en Microsoft Redmond, y quepodríamos traducir como “el conjunto de herramientas vinculado directa o indirectamente con eldesarrollo”. Se encarga también de la colaboración con compañías que crean productos que seintegran tanto en Visual Studio, como en la suite Expression.

Especial Silverlight 14-15En el momento de escribir estas líneas, acaban de aparecer las versiones definitivas del los ServicePack 1 de Visual Studio 2008 y .NET 3.5, aunque no disponemos aún de la versión final deSilverlight 2.0, cosa que, según la rumorología, tendrá lugar a mediados de septiembre. Noobstante, la disponibilidad de la Beta 2 del producto, y sobre todo, la tremenda expectación que hadespertado en todo el mundo, nos ha llevado a reunir a varios autores que ya trabajaban conversiones anteriores y coordinar con ellos este número especial.

Silverlight 2.0 Animation System 16-22Uno de los aspectos más novedosos y que mejor expresan el “alma” de una tecnología comoSilverlight 2, es la capacidad para crear elementos dinámicos. Para ello, Microsoft ha incluido en elruntime de esta versión una gran cantidad de objetos de soporte basados en las capacidades de suhermano mayor (WPF), al que denomina de forma global Silverlight Animation System.

Silverlight DataGrid 24-28Si escuchamos la palabra “Silverlight” nos viene a la cabeza términos tan atractivos comomultimedia, RIA, gráficos vectoriales… Todo esto es genial, pero la mayoría de nosotros nosganamos el pan de cada día con aplicaciones de gestión. ¿Qué nos ofrece Microsoft al respecto?

Comunicaciones en Silverlight 30-38El artículo que se presenta ahonda el estado actual de las comunicaciones en Silverlight, haciendohincapié en servicios Web WCF (la forma actualmente recomendada de interoperar entre unservidor y Silverlight), servicios Web ASP.NET ASMX, así como solicitudes vía HTTP, como elacceso a feeds RSS, POX y JSON.

Webparts Silverlight para SharePoint 40-45Este artículo pretende ilustrar una forma sencilla de introducir la nueva tecnología de presentaciónpara la Web que es Silverlight, en el desarrollo de WebParts.

WPF, DirectX y los gráficos tridimensionales 46-53La espectacular aparición de WPF aún no explota todas las potencialidades gráficas para lavisualización de escenas tridimensionales en DirectX. El presente artículo pretende hacer un primerrecorrido por los conceptos básicos de los gráficos por ordenador y mostrar cómo se manifiestan éstosen DirectX y WPF en lo referente al modelado y al procesamiento gráfico.

Acceso a ficheros con Visual Basic. Usar clases de .NET o no usarlas… 54-59Visual Basic permite varias formas distintas de acceder al contenido de los ficheros, unas se basan enlas clases de .NET Framework, otras son específicas de Visual Basic. Entre estas últimasencontramos funcionalidad compatible (o casi) con Visual Basic 6.0. En este artículo veremos lasdiferentes formas de acceder al contenido de los ficheros para que el lector pueda elegir la que mejorse adapte a sus necesidades.

dnm.todotnet.qa 60-62Excepciones en ASP.NET y gestión excepcional de formularios ¿Qué es una excepción sino algo excepcional en el ciclo de vida de una aplicación? ¿Y cómo debe manejarse?¿"In-situ" o de forma centralizada? Este mes discutiremos el manejo de excepciones en ASP.NET y cómomanejar múltiples formularios.

dnm.biblioteca.net 63Learning ASP.NET 3.5 Programming .NET 3.5

dnm.comunidad.net 64-65Entrevista a David Silverlight

dnm.desvan 66

El pasado 6 de agosto, en la keynote decierre del Tech-Ed de Sudáfrica, Micro-soft anunció la disponibilidad de laRTM (Release To Manufacturing) deMicrosoft SQL Server 2008, la nuevaversión del sistema de gestión de basesde datos de la compañía.

SQL Server 2008 ofrece una granvariedad de características y funciona-lidades nuevas que mejorarán en granmedida la administración de bases dedatos. Entre ellas, destacan el soportepara la gestión basada en políticas, capa-cidades de auditoría, almacenamientode datos a gran escala, datos geoespa-ciales y servicios de análisis y reportingavanzados.

Según Fernando Bocigas, res-ponsable de negocio de SQL Server yBPI Server de Microsoft, “Microsoftha desarrollado esta versión de SQLServer pensando en el cliente. SQLServer 2008 es la única plataforma debase de datos que incluye unas fun-cionalidades completas y totalmenteintegradas para la gestión de datos, asícomo capacidades de Business Intelli-gence embebidas, con las que ayuda-mos a nuestros clientes a ahorrar tiem-po y dinero y a que puedan centrarseen trabajar para sacar el mayor prove-cho de sus activos de datos”.

Hasta la fecha ha habido más de450.000 descargas del producto por par-te de la Community Technology Pre-views (CTP), hay más de 75 aplicacio-nes a gran escala que ya se encuentranen producción y más de 1.350 aplica-ciones que están siendo desarrolladaspor cerca de 1.000 ISV sobre SQL Ser-ver 2008.

Plataforma de Aplicaciones deMicrosoft

SQL Server es un componente clave dela Plataforma de Aplicaciones de Micro-

soft, una suite de productos y tecnologíasdiseñadas para ayudar a los clientes aconstruir, hacer funcionar y gestionaraplicaciones de negocio dinámicas, yque se encuentra disponible en lassiguientes ediciones:

SQL Server 2008 Enterprise

SQL Server 2008 Enterprise es unacompleta plataforma de business intelli-gence y gestión de datos, que propor-ciona características de escalabilidad,data warehousing, seguridad, soporteanalítico avanzado y reporting para apli-caciones críticas de negocio. Con estaedición, ahora es posible consolidar ser-vidores y ejecutar procesos transaccio-nales online a gran escala.

SQL Server 2008 Standard

SQL Server 2008 Standard es una com-pleta plataforma de business intelligencey gestión de datos, que proporciona ges-tión y facilidad de uso para funcionaren aplicaciones departamentales.

SQL Server 2008 Workgroup

SQL Server 2008 Workgroup es unaplataforma de reporting y gestión dedatos fiable, que proporciona capaci-dades de gestión y sincronización remo-ta seguras. Esta edición incluye carac-terísticas de base de datos clave y hacemuy sencilla la migración a las versio-nes Standard o Enterprise.

SQL Server 2008 Web

SQL Server 2008 Web está especí-ficamente diseñado para entornosWeb de alta disponibilidad que seejecutan sobre Windows Server.SQL Server 2008 Web proporcionalo necesario para soportar aplicacio-

nes Web altamente escalables y debajo precio o soluciones de hostingpara los clientes.

SQL Server 2008 Developer

SQL Server 2008 Developer permi-te a los desarrolladores construir yprobar cualquier tipo de aplicacióncon SQL Server 2008. Esta ediciónincluye todas las funcionalidades deSQL Server Enterprise, pero contie-ne licencia solo para desarrollar, pro-bar y utilizar como demo. Las aplica-ciones y las bases de datos desarrolla-das bajo esta edición pueden ser actua-lizadas fácilmente a SQL Server 2008Enterprise.

SQL Server 2008 Express

SQL Server 2008 Express es una ver-sión gratuita de SQL Server queincluye funcionalidad de base de datosclave, entre las que se incluyen todoslos tipos de datos del nuevo SQL Ser-ver 2008 ahora en una aplicación lige-ra. Esta edición es perfecta paraaprender y construir escritorios ypequeñas aplicaciones de servidor, ypara ser redistribuida por los ISV.

SQL Server Compact 3.5

SQL Server Compact es una base dedatos embebida gratuita diseñada paradesarrolladores, idónea para construiraplicaciones independientes y ocasio-nalmente conectadas para dispositi-vos móviles, ordenadores de mesa, yclientes Web. SQL Server Compactfunciona sobre todas las plataformasMicrosoft Windows, incluyendo lossistemas operativos Windows XP yWindows Vista, y en dispositivos Poc-ket PC y smartphones.

Más información en: www.micro-soft.com/sqlserver o en español enwww.microsoft.es/sql/2008.

dotN

etM

anía

<<

6

noticiasnoticias

noticias

noticias

noticias

Microsoft lanza la versión final de SQL Server 2008

dotN

etM

anía

<<

7

Microsoft ALM’08 Sessions

El próximo día 16 de octubre, Microsoft Ibé-rica celebrará en Madrid el mayor evento delaño sobre el Ciclo de Vida de las Aplicaciones(ALM): Microsoft ALM´08 Sessions.

Un evento en el que los principales clien-tes y partners de Microsoft (entre los que seencuentran patrocinadores de este mediocomo son Alhambra-Eidos, Krasis, PlainConcepts, Raona, Solid Qualiy Mentors...),a través de más de 20 ponencias, expondránsu experiencia, cubriendo distintas temáti-cas: Metodologías, Procesos, Integraciones,Calidad, Solucio-nes, etc.

Es totalmentegratuito. Reservesu plaza y regístre-se en: www.micro-soft.es/alm2008.

Workshops sobre Team System

Adicionalmente, durante el mes de sep-tiembre se celebrarán en Madrid cuatroeventos sobre Team System; todos ellos gra-tuitos y en los que podrá inscribirse desdeel sitio: http://msevents.microsoft.com/CUI/default.aspx?culture=es-ES.

El primero, “Workshop de Team Foun-dation Server 2008”, se celebrará el día 11de septiembre, en colaboración con Alham-bra-Eidos. El segundo, “Gestión de códi-go fuente con Visual Studio Team System”,será impartido por el grupo de usuarios.NET MAD.NUG el día 18 de septiembre.El tercero, “Ask the expert: Scrum y TeamSystem”, se celebrará el 23 de septiembrecon la colaboración de Plain Concepts, yfinalmente, el cuarto, de igual título que elprimero, se celebrará el 30 de septiembre enconlaboración con Danysoft.

ALManía

<<dnm.directo.noticias

Visual Studio 2008 y.NET Framework 3.5Service Pack 1 dan conti-nuidad a la inversión deMicrosoft en herramientas de desarro-llo líderes del mercado. El Service Pack1 resuelve problemas encontrados tan-to mediante pruebas internas como gra-cias a información recibida de clientesy partners. Además, el Service Pack 1ofrece a sus usuarios tanto nuevas carac-terísticas para el desarrollo de aplica-ciones para Windows, Office y la Web,como mejoras en la estabilidad y el ren-dimiento de Visual Studio 2008 y .NETFramework 3.5.

Visual Studio 2008 Service Pack 1

• Diseñadores mejorados para el desa-rrollo de aplicaciones WPF.

• Soporte completo para SQL Ser-ver 2008.

• La introducción del Diseñador deentidades de ADO.NET.

• Componentes y herramientas paraVisual Basic y Visual C++ (inclu-yendo un ribbon de Office 2007 paraMFC).

• Mejoras en Team Foundation Ser-ver para responder al feedback de losclientes acerca de la usabilidad y ren-dimiento del control de versiones,y ofrecer una mejor integración dele-mail con el seguimiento de ítemsde proyectos y soporte completopara la utilización de SQL Server2008.

• Mejoras para el desarrollo Web,incluyendo un soporte más com-pleto de Javascript, herramientasmejoradas para AJAX y ASP.NETDynamic Data que proporciona unentorno completo de generaciónautomática de plantillas (scaffolding).

.NET Framework 3.5 Service Pack 1

• Mejoras de rendimiento con lacapacidad de generar código quemejore el tiempo de arranque de lasaplicaciones de un 20 a un 45%, yel tiempo de ejecución de aplica-ciones “end-to-end” hasta un 10%.Además, los servicios que conectancon aplicaciones .NET tambiénpueden ver incrementado hasta 10veces su rendimiento cuando se eje-cutan en IIS 7.0.

• Ofrece a los desarrolladores que tra-bajen con WPF soporte paraDirectX pixel shader y para el nue-vo control WebBrowser.

• Mejoras en WCF que ofrecen máscontrol al desarrollador sobre elacceso a datos y servicios.

• Experiencia de instalación mejora-da para aplicaciones cliente con elnuevo .NET Framework ClientProfile, que permite a los desarro-lladores desplegar aplicacionesWindows y aplicaciones cliente deuna forma más rápida y sencilla, gra-cias a la reducción en un 86,5% deltamaño del framework .NET (queha pasado de 197MB a 26,5MB).

• Mejoras en la plataforma de accesoa datos, como ADO.NET EntityFramework, ADO.NET Data Ser-vices y soporte para las nuevas carac-terísticas de SQL Server 2008.

En el número anterior ya publi-camos una lista completa de las mejo-ras y nuevas características de este Ser-vice Pack. Además, puede encontrarmás información en http://msdn.micro-soft.com/es-es/vs2008.

Microsoft publica el Service Pack 1 deVisual Studio 2008 y .NET Framework 3.5El Service Pack I no solo añade mejoras en el rendimiento y la fiabilidad,añade un buen número de nuevas caractarísticas avanzadas tales comoADO.NET Entity Framework y ADO.NET Data Services o el nuevo .NETFramework Client Profile.

ALM’08 Sessions

Día16 de octubre de 2008

LugarHotel Velada (Madrid)

Durante los primeros días del mes de julio (del 3 al 9)tuvo lugar en París la final internacional de ImagineCup ’08. La competición, organizada anualmente porMicrosoft, va creciendo en relevancia internacional yen participación año tras año y, en ésta su sexta edi-ción, superó los 200.000 participantes de más de 100países de todo el mundo, en las nueve categorías dis-ponibles. El lema de este año “Imagina un Mundo enel que la Tecnología posibilite un Medioambiente sos-tenible” retaba a los estudiantes a desarrollar proyec-tos tecnológicos que colaboraran en la conservacióndel medioambiente, el ahorro energético o la reutili-zación de energías, por citar algunas de las posibili-dades. Fue una intensa semana en la que más de 300estudiantes finalistas pudieron compartir sus expe-riencias y pasión por la tecnología en un marco incom-parable de intercambio cultural e innovación tec-nológica, sin duda, dos de los pilares fundamentalesde la competición.

La representación española corrió a cargo delequipo de Windows Drive, compuesto por Héc-tor Juan, David Rodríguez, Carlos Junquera yMiguel Llopis. El equipo consiguió el derecho acompetir en la final internacional tras la victoriaen la fase española de Desarrollo de software, noti-cia de la que ya se habló en dotNetManía en la

edición de junio. Adicionalmente, el proyectologró clasificarse para la final internacional en lacategoría de Desarrollo con Windows Live,logrando de este modo que hubiera representa-ción española en más de una categoría, hecho queno había sucedido en las anteriores ediciones dela competición.

Desarrollo con Windows Live, ¡ganamos!

La categoría de Desarrollo con Windows Live,creada este mismo año, perseguía premiar a nivel mun-dial a aquel proyecto que hiciera un mejor uso de lastecnologías y servicios de la red Windows Live. Detodos es sabida la creciente importancia en el mundodel software de los modelos S+S y la relevancia de lasredes sociales en Internet, el objetivo de esta categoríaera valorar soluciones que enriquecieran la red de ser-vicios de Windows Live y lo dotaran de característi-cas sociales, relacionadas con el medioambiente; con-formando además un modelo de negocio en el cual eluso de Windows Live fuera un elemento central delproyecto, y consiguiendo combinar diferentes tecno-logías de Live de manera elegante y original. Para laúltima fase de esta categoría fueron seleccionados tresproyectos: UniqueStudio de China, 1stAnbul de

Imagine Cup 2008

eventos

<<

event

osdo

tNet

Man

ía<<

8

dotN

etM

anía

<<

9

dnm.directo.eventos<<

Turquía y Windows Drive de España.El proyecto español consiste en una

solución orientada a enriquecer la red deWindows Live añadiendo los servicios yfuncionalidades necesarias para podercompartir vehículos particulares connuestros contactos de dicha red (con-tactos de Windows Live Messenger,etc) combinando dichas funcionalida-des con el uso de mapas de Live Search(www.maps.live.com) y sistemas de aler-tas, así como el uso de otras tecnologíasMicrosoft de última generación talescomo diferentes clientes de WindowsPresentation Foundation, ASP.NETAJAX, MSN Messenger Activities, Win-

dows Mobile 6 y tecnologías de servidortales como Windows 2008 Server y SQLServer 2008, encargadas de proporcio-nar las capas de datos y lógica de la arqui-tectura a través de una capa de serviciosexpuesta al resto de clientes mediante eluso de Windows Communication Foun-dation y LINQ. Los detalles de imple-mentación y uso de Windows Live tam-bién se pueden encontrar en la ediciónde junio de dotNetManía.

El jurado, compuesto por miembrosdel equipo de desarrollo de WindowsLive de Microsoft Corp., consideró quela solución presentada por Windows Dri-ve era la que mejor se ajustaba a losrequerimientos y exigencias de esta cate-goría, otorgando el primer premio mun-dial al equipo español y confirmando deesta forma que el año 2008 no es tan soloun año histórico para nuestro país en loreferido al deporte, sino también en otros

ámbitos al tratarse de la primera victoriade un equipo español en esta competi-ción desde su creación en el año 2003.

El premio —consistente en 10.000dólares a repartir de igual modo entretodos los miembros del equipo—, la posi-bilidad de realizar entrevistas para optara puestos de becario en el equipo de Win-dows Live en Microsoft Corp. y la apari-ción del proyecto como caso de estudioen la Web principal de desarrollo conWindows Live (www.dev.live.com) —espe-ramos que sea únicamente el comienzode una larga lista de premios para equiposespañoles en próximas ediciones—.

Proyectos ganadores en otras categorías

Al margen de la categoría de WindowsLive, son dignos de mención los proyec-tos ganadores en el resto de categoríasentre las que destacan la categoría deDesarrollo software (ganada por el equi-po de Australia gracias a un proyecto quepretende optimizar el uso de agua y otrostipos de fuentes energéticas en los culti-vos agrícolas) y la categoría de Desarro-llo embebido (en la que el ganador fue elequipo de Singapur, mediante la creaciónde unos sensores para la monitorizaciónde la composición del aire y un softwarepara procesar dicha información captada).

Los ganadores del resto de cate-gorías (IT, Desarrollo de juegos XNA,Algoritmia, etc.) pueden ser consulta-dos en la Web oficial de la competición(www.imaginecup.com).

Imagine Cup ’09, en El Cairo (Egipto)

La próxima edición de la competi-ción, que dará comienzo el 15 de agos-to y finalizará en el verano de 2009 conla fase final que tendrá lugar en El Cai-ro (Egipto), contará con 8 categoríasdiferentes.

El lema del concurso es bastantemás amplio que en anteriores edicio-nes: “Imagina un Mundo en el que laTecnología ayude a resolver los pro-blemas más relevantes de la actuali-dad”. Estos problemas coinciden con8 grandes retos para la Humanidad(Educación, Pobreza, Medioambien-

te, Salud, etc.), reflejados en los Obje-tivos del Milenio, redactados por laONU. Para más información acercade la competición, categorías y plazos,consultar la Web oficial (www.imagi-necup.com)

Desde estas líneas, me gustaría atítulo personal recomendar a todos losestudiantes españoles que leen dot-NetManía que participen en la com-petición por tratarse de una experien-cia única desde el punto de vista técni-co y también de intercambio culturalcon estudiantes de los cinco continen-tes. Y, por supuesto, animarles a com-petir para llegar a lo más alto y demos-trar así el gran nivel técnico de los estu-diantes y desarrolladores de nuestropaís: ¡a por ellos…!

Texto: Miguel Llopis

Marino Posadas

Marino Posadas esredactor jefe de ddot-

NetMania y consultorindependiente. Es MCP,MCSD, MCAD, MCT y

MVP en Visual C#.Puedes consutar su

página Web enwww.elavefenix.net

entrevista

entrevista a Joe MariniJoe Marini es director del denominado VisualStudio Industry Partners Program que el propioMarini definía como el “Development ToolsEcosystem Team” en Microsoft Redmond, y quepodríamos traducir como “el conjunto deherramientas vinculado directa o indirectamentecon el desarrollo”. Se encarga también de lacolaboración con compañías que crean productosque se integran tanto en Visual Studio, como en lasuite Expression.

Tu trabajo está vinculado al progra-ma Visual Studio Industry PartnersProgram. ¿Qué es exactamente loque hacéis con los partners?

Se trata de un programa que —esen-cialmente— recluta a partners que cons-truyen productos que se integran ennuestras herramientas de desarrollo,pero que son desarrolladas íntegra-mente por ellos. El programa suminis-tra a los constructores de herramientasla asistencia técnica necesaria, así comosugerencias a la hora de la puesta enproducción y el modelo de negocio rela-cionado con estas herramientas.

¿Qué es lo que os suelen pedir esospartners?

Pues, fundamentalmente, dos cosas:la más importante es la asistencia téc-nica durante el proceso de construcciónde las aplicaciones de integración o delos componentes o plugins (depende delo que se trate). Dudas que surgen enel proceso de desarrollo, dudas sobre laforma correcta de instalación, sobre ladocumentación, sobre coexistencia conel sistema, etc.; el otro aspecto es la asis-tencia en técnicas de marketing com-partido. Su presencia en las páginasWeb de Microsoft dedicadas al desa-rrollo, su colaboración con nosotros através de los eventos de Microsoft, pro-mociones en forma de webcasts y simi-lares.Por tanto, entiendo que trabajáis conlos departamentos de “evangelismo”de tecnologías, tanto en Redmondcomo fuera…

Así es. Y también con los ISV eincluso con empresas de la competen-cia que tienen programas de integra-ción con nuestros productos. Oracle oIBM serían un buen ejemplo de esto.El otro es lo que denominamos GlobalISV, que tienen un alcance mayor en ladifusión del producto.Volcándonos en el aspecto técnico,¿está siendo Visual Studio 2008 tanimpactante como prometía la publi-cidad?

Ésa es la gran pregunta, efectiva-mente. Para muchos de nuestros part-ners ésta está siendo una gran oportu-nidad. Supongo que siempre se dice esocuando sale un nuevo producto, pero lacantidad de novedades que aportaVisual Studio para la construcción deaplicaciones “de hoy” (soporte WPF,Silverlight, LINQ, etc.), hacen que seauna ocasión inmejorable para situarsebien en el mercado.No es corriente que Microsoft pon-ga en el mercado 3 productos de laenvergadura de Visual Studio 2008,SQL Server 2008 y Windows Server2008 en un mismo año. Por otra par-te, se habla de dos tipos de com-pañías respecto a la adopción de tec-

nologías: las innovadoras y las con-servadoras. ¿Cuál sería tu consejopara ambos tipos de empresa, res-pecto a estas novedades?

Yo les diría, tanto a unos como aotros, que no dudaran en consultarnos.Que nos expusieran sus inquietudes ysus necesidades, y nosotros con muchogusto les daremos el mejor consejo per-sonalizado para cada situación. Inclusosi no desean adoptar la tecnología en elmomento de la consulta, es convenien-te que nos contacten lo antes posiblepara poder preparar y aconsejar sobre

las mejores formas de adopción y comu-nicarles nuestra experiencia al respec-to. Hay muchas ventajas adicionales conesto, y es un proceso muy sencillo paraempresas de todos los tamaños. Entiendo que el producto que máste interesa promocionar en este con-texto de trabajo es el MicrosoftVisual Studio Extensibility SDK.¿Qué más puedes decirnos sobre supresente y futuro?

Ya sabes que es un conjunto de APIque permiten extender las posibilida-des de la herramienta, añadiendo nue-vas características. No es algo nuevo,Visual Studio ha sido extensible duran-te los últimos 12 años, desde los años94/95 en que podía usarse COM coneste objetivo hasta la actualidad, con.NET, y una forma mucho más ade-cuada de extensibilidad. Eso ha permi-

tido la aparición en el mercado (e inclu-so en las comunidades de software libre)de muchas herramientas vinculadas conVisual Studio de esta forma.

Y continuamos realizando inver-siones significativas para que esto sigaasí. Queremos que se entienda tam-bién Visual Studio como una plata-forma sobre la que se pueden cons-truir muchas herramientas que laextiendan o la complementen. Unejemplo en esta versión es la inclu-sión del “Visual Studio Shell SDK”.Eso te permite construir tu propia

versión de Visual Studio, por decirloasí, incluyendo la ventana de splashinicial, los menús, etc., de forma quetenga el aspecto de “tu herramienta”,personalizando prácticamente todo.Y eso se ha lanzado de forma gratui-ta, sin cargos de licencia ni royaltiesde ninguna clase.¿Nos recomiendas algún sitio Webdonde nuestros lectores puedanampliar esta información?

Claro. Lo mejor es visitar http://msdn.com/vsx, que es la página prin-cipal sobre extensibilidad para VisualStudio, y descargarse el Visual Studio2008 SDK, donde está incluido el VS-Shell del que hablábamos antes. Tam-bién hay ejemplos y documentaciónmuy interesante al respecto. De hecho,en la keynote de Soma Somasegar enel pasado Tech-Ed, Dan Fernandez

dotN

etM

anía

<<

11

dnm.directo.entrevista<<

Joe Marini junto a Marino Posadas durante la entrevista

dotN

etM

anía

<<

12

dnm.directo.entrevista<<

hizo una demo que se basaba en este SDK, y queresultó muy interesante porque mostraba muchas desus nuevas posibilidades.He leído un entrada tuya en tu blog, algo lla-mado “When secrets make sense”. Esto teníaque ver con la seguridad, que en los años pasa-dos ha sido una prioridad para Microsoft, peroparece que —resueltos los problemas funda-mentales— todo el mundo lo asume como una“pesadilla necesaria”. ¿Va a seguir esto siendoasí o va a ser cada vez más transparente para elusuario?

Desde el momento en que trabajamos con unsoftware que cada vez es más abierto y más conec-tado, siempre va a suceder que la seguridad sea unelemento capital en el desarrollo, no importa laherramienta que se use. No obstante, Microsoft vaa continuar con esta política de preocupación por laseguridad de cara a nuestras herramientas y a losusuarios, naturalmente.Algunas de tus últimas presentaciones han teni-do como tema de fondo el diseño Web. Estonos lleva nuevamente a una pregunta que hehecho a más de un entrevistado acerca de laadopción del nuevo paradigma que separa eldiseño del desarrollo (aunque lo integre a travésde las herramientas). ¿Se está produciendo esaseparación de roles en las empresas norteame-ricanas?

Estamos empezando a ver esa separación. Perono es una cosa de un día. En principio, creemos quees debido a que no es fácil que los diseñadores y losprogramadores trabajen de forma conjunta. De ahíque hayamos hecho un notable esfuerzo para queherramientas como Expression se integren de la for-ma que lo hacen con Visual Studio. Y esa separación,paradójicamente, puede facilitar mucho el acerca-miento de ambos roles. Eliminar las distancias entrelo que un diseñador hace y lo que un desarrolladorpuede programar. No hay que preocuparse por eldiseño, porque el diseño —como parte del proceso—ya se nos entrega con el aspecto visual adecuado expre-sado en forma de XAML. Y el desarrollador se pue-de centrar exclusivamente en la parte funcional.

Respecto a la adopción por parte de las empresas,creo que cada vez más. Estamos empezando a vercómo muchas empresas incluso contratan diseñado-res para que las aplicaciones importantes establezcanla diferencia desde un principio. Cuando se empie-cen a ver más resultados de lo positiva que es esa sepa-ración no me cabe duda de que la adopción se incre-mentará.Por otro lado, hay muchos menos diseñadoresque desarrolladores. Al menos, en lo que puedodecirte del mercado en España…

Si, eso también es cierto en los EE.UU. Lo quees otra razón para facilitar su trabajo con los desa-rrolladores y también para animar a más informáti-cos a abordar el mundo del diseño, que va a más y esapasionante y muy creativo. Afortunadamente, esediseño puede hacerse con herramientas como Expres-sion Blend o Expression Design sin necesidad de sabernada del código XAML que la herramienta genera.Además, esto redunda en una mayor productividad,como he dicho antes, al poder enfocarse cada uno ensu labor. Es curioso que todo esto está basado en el están-dar XML y sus posibilidades. Todavía recuerdoque hacia 2000, había muchos escépticos sobrela utilidad de XML. Hoy nadie lo discute. ¿Cuálpiensas que va a ser la evolución de XML y de loslenguajes de marcas en general?

Como cualquier otra tecnología que se muestreútil. Puede utilizarse bien o de forma muy pobre(que también lo he visto). Yo lo entiendo como unaforma de construir otros lenguajes en realidad. Esmuy abierto, es independiente de las plataformas,de las herramientas, es texto plano, con lo que losbeneficios de cara a Internet son claros. Pienso queXML ha venido para quedarse, desde luego, y queseguirá evolucionando.

de la aparición de la primera Beta delproducto, las promesas eran espectaculares. Nada que ver conla versión 1. Nada de Javascript obligatorio. Nada de carenciade controles: un conjunto completo (por no hablar de los yadisponibles de terceras partes). C#, VB.NET y lenguajes diná-micos. Capacidad de acceso a servicios, tanto tradicionales,como WCF. Integración con HTML y DOM. Soporte de soc-kets y otros mecanismos de redes. LINQ. Y sobre todo, un sor-prendente subconjunto de XAML incluido en un runtime desolo 4 Mb. Todo ello, perfectamente programable desde VisualStudio 2008 y –para el diseño– con Expression Blend (JunePreview). Que nadie me pregunte cómo se puede meter todaesa funcionalidad en tan poco espacio, pero ahí está. No care-ce de nada que pueda encontrarse en Adobe Flash, y cuentacon un sinfín de ventajas respecto a éste (más de un diseñadorprofesional de Flash, me ha pedido ya documentación y ejem-plos, tras ver algunas demos del producto). Es difícil reunir unconjunto funcional tan potente y extensible y, además, hacer-lo siguiendo los patrones adecuados de diseño, las pautas bienprobadas de construcción de elementos gráficos y los meca-nismos matemáticos recomendados para la interpretación visual(renderización, para los anglófilos).

Y la verdad es que, como dice el anuncio: “¡promesas cum-plidas!”. Silverlight 2 tiene todo eso y muchísimo más. Porejemplo, dispone de capacidades de integración con Share-Point, y Yamil Hernández (viejo conocido ya de los lecto-res de la revista por sus aportaciones junto al Grupo Webooen WPF), se encarga de demostrarlo en “Webparts Silver-light para SharePoint”, donde revisa los mecanismos de cre-ación e integración de elementos Silverlight 2 para Share-Point 2007, la interacción del código de script con el código.NET y la compleción y puesta a punto de una arquitecturade este tipo.

especial

Silverlight<< Y es que, ya antes

Marino Posadas esredactor jefe de ddot-

NetMania y consultorindependiente. Es MCP,MCSD, MCAD, MCT y

MVP en Visual C#.Puedes consutar su

página Web enwww.elavefenix.net

En el momento deescribir estas líneas,acaban de aparecer lasversiones definitivas delService Pack 1 de VisualStudio 2008 y .NET 3.5,aunque no disponemosaún de la versión final deSilverlight 2.0, cosa que,según la rumorología,tendrá lugar a mediadosde septiembre. Noobstante, ladisponibilidad de la Beta2 del producto, y sobretodo, la tremendaexpectación que hadespertado en todo elmundo, nos ha llevado areunir a varios autoresque ya trabajaban conversiones anteriores ycoordinar con ellos estenúmero especial.

Silverlight

Marino Posadas

Tampoco podíamos obviar el acceso a datos. Ni loselementos visuales que ofrece Silverlight 2 para su con-trol, especialmente el nuevo DataGrid. Ésa ha sido lalabor que hemos encomendado a Braulio Díez, quien,junto a Reyes García, ilustra sobradamente sus posi-bilidades en el artículo “Silverlight DataGrid”. Unode los controles más utilizados que –como anticipába-mos– ya tiene varias contrapartidas en productos deterceros.

¿Y qué hay del acceso a datos en sí? Bueno, la granpromesa se llamaba Astoria, y, ahora, ADO.NET DataServices. Pero su nivel de compleción no llega, todavía,al de otros componentes y librerías mencionadas. Tiem-po tendremos de dedicar a ese tema crucial el espacionecesario. Mientras tanto, los servicios son la soluciónmás fiable, además de aportar el vínculo principal decomunicación con la información exterior. Así se lopedimos a José Luis Latorre, y es lo que presentamosen “Comunicaciones en Silverlight”, donde se desa-rrolla la conexión con servicios Web WCF y ASP.NETASMX, así como las solicitudes vía HTTP, tales comofeeds RSS, POX y JSON.

Por último, aquello que constituye el alma visualde esta tecnología. Lo que la hace aparecer como com-petidor directo de Flash y amenaza seriamente su hege-monía: las animaciones visuales, que la documentaciónoficial engloba bajo el epígrafe “Silverlight AnimationSystem”, y cubre los conceptos de animación y trans-formación de elementos visuales. Con el mismo títu-lo aporté mis dos céntimos (de euro, supongo) a esteespecial, abordando ambos aspectos del subconjuntode XAML disponibles en esta Beta 2.

Y habrá más, mucho más, sobre Silverlight. A títu-lo de curiosidad, veamos algunas estadísticas: el núme-ro de agosto 2008 de la revista MSDN Magazineincluye 5 artículos sobre diversos aspectos de Silver-light 2. El número de blogs existentes sobre el temase ha multiplicado por 40, el número de páginas por500, el número de aplicaciones que ya lo usan (inclu-so en su estado actual), ha subido espectacularmen-te, llegando, como en el caso de la NBC a usarlo paradar cobertura a los JJ.OO. Y también podemos visi-tar http://www.silverlightshow.net/olympics con losresultados de todos los juegos olímpicos disputadospara todas las disciplinas. Ahí pueden verse datoscuriosos, como que John Rambo fue –en la realidad–medalla de bronce en los JJ.OO. de Tokio'64 en lamodalidad de salto de altura (creo que después nosentía las piernas...) En fin, la marea continúa… Elpropio José Luis Latorre, en el colmo de la cohe-rencia con los contenidos y sus autores, entrevista estemes a un MVP que dirige el proyecto CommunityCredit (http://www.community-credit.com/Community-CreditInfo.aspx), tan proactivo y creador, que hay quiendice que Microsoft decidió bautizar a esta tecnología en

su honor. Su nombre: David Silverlight (http://www.com-munity-credit.com/cs/blogs/starbucks_is_my_home).

Para los principiantes, un grupo de evangelismode Microsoft, especialmente volcado con el tema ydirigido por Jessy Liberty (ver entrevista con él, enel número de enero de este año en dotNetManía)y estupendamente secundado por Tim Heuer, JoeStegman, Lawrence Moroney y otros, están cre-ando un enorme conjunto de materiales de apoyo yaprendizaje en el sitio especializado http://Silver-light.net. Ejemplos, tutoriales, vídeos, artículosintroductorios, foros y varios libros que verán la luzen los próximos dos meses, al igual que espero quela vea el que yo mismo estoy terminando sobre eltema, perteneciente a la serie Cuadernos Técni-cos de dotNetManía, y que servirá para ampliar lacobertura tecnológica que Netalia ofrece a sus lec-tores sobre tecnologías Microsoft.

Indudablemente, quedan cosas por hacer y, dehecho, Microsoft ya está diseñando la siguiente ver-sión. Gráficos 3D, la versión final de ADO.NET DataServices (muy prometedora por lo que se ve hasta elmomento), optimización aún mayor del proceso decarga en las páginas, y un conjunto de controles queestá en proceso de crecimiento y que promete ofrecertanto o más que lo que existe hoy en día para WindowsForms.

Hasta Ben Hoyt (evangelista de Adobe Systems)reconoce en http://news.cnet.com/8301-17939_109-10011048-2.html?part=rss&tag=feed&subj=Webware,que “no ve un ganador claro en el futuro inmediato delliderazgo de las aplicaciones R.I.A., pero lo que sí estáclaro es que estas aplicaciones son el futuro de los sitiosWeb”. Eso pensamos nosotros y ése ha sido el leit motivque nos ha animado a la confección de este especial.Espero que lo disfruten leyéndolo, tanto como noso-tros produciéndolo.

dotN

etM

anía

<<

15

dnm.especial.silverlight<<

Es difícil reunir un conjunto funcional tanpotente y extensible y, además, hacerlosiguiendo los patrones adecuados dediseño, las pautas bien probadas de

construcción de elementos gráficos y losmecanismos matemáticos recomendados

para la interpretación visual

Dado que una parte importante de la programaciónde animaciones en Silverlight está vinculada al len-guaje XAML, el editor asociado Expression Blend2.5 (June Preview) –que puede descargarse gratuita-mente de la dirección http://silverlight.net/GetStarted– será una de las herramientas que reco-mendamos si se desea reproducir los contenidos yprocedimientos de diseño que explicamos aquí.Además, en la dirección http://www.silverlight.net/quickstarts/blend_quickstart están disponiblesejemplos para inicio rápido (quick starts), junto a víde-os y otras opciones de aprendizaje.

AnimacionesLas nuevas interfaces de usuario se caracterizan

por su dinamismo. Ése ha sido uno de los elemen-tos diferenciadores de Adobe Flash, y ésa es una delas grandes virtudes de esta versión de Silverlight.Con una diferencia: la programación (que en Flashse realiza con el lenguaje propietario ActionScript),tiene lugar utilizando dos lenguajes, al igual que suce-de con Windows Presentation Foundation: XAMLen la parte del diseño visual, y un lenguaje .NET(incluyendo los lenguajes dinámicos IronPython yIronRuby) en la parte funcional.

Para corresponder a este modelo de desarro-llo, Microsoft ha diseñado las dos herramientasideales: Expression Blend para la parte de diseñovisual, y el propio Visual Studio 2008 (SP1 eneste caso), para manejar el código no-XAML ocódigo funcional. Ambos trabajan conjuntamen-

te, y ambos son conscientes de los cambios pro-ducidos en el código del proyecto por parte delotro, permitiendo incluso la actualización semiau-tomática del código modificado. Dicho esto, vamosa centrarnos en la generación del código XAMLpara producir animaciones.

Entendemos por animación una ilusión visual, cre-ada mediante la proyección rápida y continua de variasimágenes o gráficos, cada uno de ellos ligeramente distin-to del anterior. El mecanismo de creación de vídeo noes más que un sistema de animaciones de fotogra-mas. Pero no vamos a ocuparnos aquí de los vídeos(para los que disponemos de otras herramientas alter-nativas como Expression Encoder), sino de las ani-maciones de gráficos generadas por nosotros.

Animaciones en SilverlightEn Silverlight, animamos un objeto XAML apli-

cando elementos de animación a sus propiedadesindividuales. Por ejemplo, para que un elemento dela interfaz de usuario crezca, procedemos a aumen-tar progresivamente sus propiedades Width y Height.Si queremos que se oculte progresivamente, vamosreduciendo el valor de su propiedad Opacity, y asísucesivamente. La versión de XAML soportada porSilverlight contiene muchos objetos cuyas propie-dades son susceptibles de animarse, en este sentido.

Ahora bien, solo pueden animarse las propieda-des cuyos valores sean del tipo double, color o point.La excepción es que también pueden animarse valo-res de propiedades mediante la denominada inter-

Silverlight 2.0 Animation System

Silverlight

Uno de los aspectos más novedosos y que mejor expresan el “alma”de una tecnología como Silverlight 2, es la capacidad para crear ele-mentos dinámicos. Para ello, Microsoft ha incluido en el runtime de estaversión una gran cantidad de objetos de soporte basados en las capa-cidades de su hermano mayor (WPF), al que denomina de forma globalSilverlight Animation System.

Marino Posadas

Marino Posadas esredactor jefe de ddot-

NetMania y consultorindependiente. Es MCP,MCSD, MCAD, MCT y

MVP en Visual C#.Puedes consutar su

página Web enwww.elavefenix.net

dotN

etM

anía

<<

17

dnm.especial.silverlight<<

polación discreta (el salto de un valor a otro sin pasarpor estados intermedios, que realmente no es una for-ma de interpolación). Veremos más adelante algo mássobre los dos tipos de interpolaciones soportadas (line-ales y no-lineales) y la forma de programarlos.

Transformaciones vs. animaciones

Otra de las características relacionadas con la ani-mación, para la cual tenemos soporte en Silverlight, esel concepto de transformación. Una transformaciónestablece cómo corresponder puntos de una coordena-da del espacio a otra, utilizando una matriz de transfor-mación que establece un mecanismo de conversión sim-ple. En el lenguaje XAML soportado en Silverlight 2.0existen predefinidas 4 clases de transformaciones: rota-ciones, escalado, elongaciones y traslación (movi-miento). Además, es posible definir nuestras propiasmatrices de transformación, que pueden usarse, por ejem-plo, para combinar varias transformaciones1.

Vamos a proceder de forma gradual viendo el fun-cionamiento de ambos mecanismos y comenzandopor las transformaciones.

TransformacionesLas transformaciones se crean aplicando propieda-

des de transformación, a distintos tipos de objetos.Dependiendo del tipo, las transformaciones soportadasserán, también, distintas (por ejemplo, los objetos Brushadmiten varias formas, los objetos Geometry utilizan supropiedad Geometry.Transform y los que pertenezcan ala categoría UIElement, utilizarán la propiedad Render-Transform). No debemos olvidar que las transformacio-nes son objetos declarados en XAML. Por tanto, si lasidentificamos con un nombre, podremos modificarlasposteriormente mediante código C# o VB.NET. Vea-mos ejemplos de estas transformaciones.

Propiedades RotateTransform y ScaleTransform

La primera permite girar un elemento un ánguloespecificado alrededor de un punto dado en el senti-do de las agujas del reloj. Por ejemplo, el códigosiguiente produce una rotación del texto tal y comovemos en la figura 1.

Como puede verse en el código de la figura 1, aña-dimos el elemento RenderTransform al cuerpo del con-trol (en este caso, el TextBlock) y especificamos unatransformación por rotación, con un ángulo de 45ºempezando el proceso en las coordenadas 150, 30, apartir de la esquina superior izquierda del control.

En el caso de la transformación de escala (Scale-Transform), se sigue un patrón similar al anterior, pudien-do indicarse, igualmente, la dirección del escalado y elpunto a partir del cual deseamos que se haga el proce-so. El código del listado 1 produciría un escalado en eleje de las X de un rectángulo (tenga en cuenta que Ren-derTransform solo se puede establecer una vez).

De la misma forma, para aplicar las transforma-ciones de elongación y translación, la propiedad Ren-derTransform aplicada al mismo rectángulo podríatomar los siguientes valores:

<Rectangle.RenderTransform>

<SkewTransform AngleX="45 />

</Rectangle.RenderTransform>

Para una elongación o estiramiento de 45 grados, y:<Rectangle.RenderTransform>

<TranslateTransform X="-30" Y="-30" />

</Rectangle.RenderTransform>

Figura 1: código fuente y resultado visual delfragmento de código correspondiente a una rotación.

Listado 1

<Pagexmlns="http://schemas.microsoft.com/winfx/2006/xaml/

presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"><Grid> <Rectangle Width="150" Height="50"

Canvas.Left="150" Fill="Blue"><Rectangle.RenderTransform><ScaleTransform ScaleX="1.5" CenterX="150" />

</Rectangle.RenderTransform></Rectangle>

</Grid></Page>

1 Aunque el concepto de transformación es similar, no debe confundirse con las conocidas Transformadas de Fourier (para más datos alrespecto de este aparato matemático ver http://es.wikipedia.org/wiki/Transformada_de_Fourier y también (en inglés) “An Intuitive Explanation ofFourier Theory”, en http://enteos2.area.trieste.it/russo/LabInfoMM2005-2006/ProgrammaEMaterialeDidattico/daStudiare/009-FourierInSpace.html.

dotN

etM

anía

<<

18

dnm.especial.silverlight<<

Para un desplazamiento de 30 píxeles a la izquier-da y arriba respecto a su posición inicial.

Creación de transformaciones mediante código

También es posible crear transformaciones de for-ma dinámica, sin ningún tipo de diseño previo. Paraello, solo necesitamos un elemento que sirva de con-tenedor e ir creando los objetos de la transformacióncon sus propiedades para incluirlos finalmente endicho contenedor. La técnica es muy similar a la uti-lizada para la creación dinámica de animaciones, porlo que remito al lector a ese aspecto que tratamos másadelante con un ejemplo completo.

Matrices de transformación y TransformGroups

Para los casos en los que deseamos realizar una trans-formación múltiple, disponemos de dos opciones: unabasada en la matemática matricial, que se fundamentaen definir una matriz de transformación, mediante elelemento MatrixTransform y la otra, mucho más senci-lla, consistente en utilizar el elemento TransformGroup,que permite exactamente eso: agrupar en un solo pro-ceso un conjunto de transformaciones diversas.

En el ejemplo del listado 2, tenemos un grupo múl-tiple de transformación que produce simultáneamentelas transformaciones de rotación, escalado y elongación.

AnimacionesIndicábamos al comienzo que las animaciones se

basan en transiciones de estado. Es decir, el valorde una propiedad varía desde un estado inicial hastaotro estado o valor final, produciendo la sensaciónvisual de movimiento, o más generalmente, de cam-bio. Esas transiciones de estado tienen lugar a lo lar-go de un período de tiempo, y existen dos conceptosasociados a toda animación que son fundamentales:la línea de tiempo (timeline) y la duración del pro-ceso de animación (duration). La duración es simple-mente un valor escalar que indica al sistema cuandodebe concluir el proceso después de su iniciación. Lalínea de tiempo es algo más compleja y permite otrasposibilidades: establecer cómo se va a comportar la

transición entre estados, en caso de que no deseemosque ésta sea uniforme (por ejemplo, puede ir rápidoal principio, más lento en el medio y nuevamente rápi-do al final), combinar animaciones y mucho más. Altrabajar con animaciones, definiremos todo el pro-ceso a través de la línea de tiempo, indicando la dura-ción y características de cada uno de los estados inter-medios. Estos estados intermedios reciben el nom-bre de KeyFrames.

Triggers

No obstante, antes de continuar con la explicacióny ejemplos del uso de animaciones, es importante quetengamos presente que una animación es un proceso quetiene lugar siempre como respuesta a un evento. Y este even-to se expresa en Silverlight XAML mediante un desen-cadenador o trigger. A diferencia de lo que sucede enWPF, solo existe un tipo de trigger soportado: el Event-Trigger (en WPF disponemos de DataTriggers y todoun conjunto de elementos similares).

Además, como un elemento puede responder a másde una acción, se dispone de una colección de triggers,a la que deberemos añadir al menos uno creado pornosotros si queremos que –como respuesta a algunaacción por parte del usuarioo del sistema– se produzcala acción correspondiente.

El trigger más simple sólo en código XAML

Vamos a ver un ejemplo sencillo de esto par-tiendo de nuestro ejemplo del rectángulo. Supon-gamos que queremos que se produzca una anima-ción consistente en desplazar el rectángulo por eleje de las X hasta una posición dada y volver a suposición inicial. Esto es posible sin escribir más quecódigo XAML siempre y cuando queramos que laanimación se produzca en la carga del control. Silo que queremos es que se produzca como reaccióna un evento de cualquier otro tipo, deberemos

Listado 2

<Rectangle.RenderTransform><TransformGroup>

<RotateTransform Angle="45" CenterX="150" CenterY="30" />

<ScaleTransform ScaleX="1.5" CenterX="150" /><SkewTransform AngleX="45" />

<TransformGroup></Rectangle.RenderTransform>

Entendemos por animación una ilusiónvisual, creada mediante la proyecciónrápida y continua de varias imágenes

o gráficos, cada uno de ellos ligeramente distinto del anterior

incluir nuestra animación dentro deun recurso con nombre (veremos estocon otro ejemplo) y llamarla desdecódigo no-XAML.

El código del listado 3 genera unrectángulo y lo desplaza hasta el punto300 del eje de las X, volviendo nueva-mente a su posición original. La dura-ción de cada desplazamiento se ha esta-blecido en 5 segundos.

Lo único que hemos hecho es aña-dir un trigger a la colección de triggers(Rectangle.Triggers) del elemento Rec-tangle, indicar al trigger que se vincu-

le con el evento Loaded (como dijimosantes, el único posible si no queremosañadir código paralelo para manejarlo)y establecer sus propiedades. Aquíhemos incluido el objeto DoubleAnima-tion dentro de un elemento Storybo-ard, y éste, dentro de un elementoBeginStoryboard, que sólo puede con-tener un único Storyboard, y es el encar-gado de distribuir las animaciones quecontiene a los objetos y propiedadescorrespondientes (por el momento noexiste un objeto-contrapartida llamadoEndStoryboard).

Respuesta a eventos mediante código

¿Y si se pretende que sean eventos deusuario los que lancen los procesos de ani-mación? Entonces, tenemos que recurrira los Resources asociados con el elemen-to. El código fuente para lanzar la res-puesta al evento correspondiente lo escri-biremos en C#, y en lugar de situar elcódigo XAML de la animación dentro deun EventTrigger, lo ubicamos dentro delos recursos propios del elemento y ledamos un nombre a cada animación parapoder referirnos a ellas posteriormenteen el código C# (o cualquiera que sea ellenguaje utilizado). Por ejemplo, paramodificar el proceso anterior de formaque se disparase al pulsar sobre el rectán-gulo, el código XAML se convertiría enel que vemos en el listado 4.

Obsérvese que lo que hacemos esvincular directamente el evento a sumanejador en el propio código XAMLe incluir todas las características de laanimación dentro los recursos corres-pondientes al elemento <Rectangle>.Cuando operamos de esta forma, VisualStudio crea automáticamente un mane-jador de evento en el que podemosincluir el código del listado 5 para elcomienzo de la animación.

Si el lector prueba el ejemplo ante-rior observará un efecto adicional, quehemos añadido a propósito para ilus-trar mejor los conceptos de Animationy StoryBoard: el proceso de ida y vuel-ta del rectángulo se repite dos veces:una por cada aparición del atributoAutoReverse="True", ya que éste puedeaparecer como parte de todo el storybo-ard (contenga las animaciones que con-tenga) y también de cada una de las ani-maciones individuales.

dotN

etM

anía

<<

19

dnm.especial.silverlight<<

Listado 3

<UserControl x:Class="Animacioni2.Page"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="400" Height="300"><Canvas x:Name="LayoutRoot" Background="White">

<Rectangle x:Name="rect" Fill="BlueViolet" Canvas.Top="100" Canvas.Left="10"Width="100" Height="100">

<Rectangle.Triggers><EventTrigger RoutedEvent="Rectangle.Loaded">

<BeginStoryboard><Storyboard x:Name="Animacion2">

<DoubleAnimation Storyboard.TargetName="rect"Storyboard.TargetProperty="(Canvas.Left)"

AutoReverse="True" Duration="0:0:5" To="300"/></Storyboard>

</BeginStoryboard></EventTrigger>

</Rectangle.Triggers></Rectangle>

</Canvas></UserControl>

Listado 4

<Canvas x:Name="LayoutRoot" Background="White"><Rectangle x:Name="rect" Fill="BlueViolet" Canvas.Top="100" Canvas.Left="10"

Width="100" Height="100" MouseLeftButtonDown="rect_MouseLeftButtonDown" ><Rectangle.Resources>

<Storyboard x:Name="Animacion2" AutoReverse="True" ><DoubleAnimation Storyboard.TargetName="rect"

Storyboard.TargetProperty="(Canvas.Left)" AutoReverse="True" Duration="0:0:1" To="300"/>

</Storyboard></Rectangle.Resources>

</Rectangle></Canvas>

Listado 5

private void rect_MouseLeftButtonDown(object sender, MouseButtonEventArgs e){

Animacion2.Begin();}

El ejemplo puede hacerse con unbotón en lugar de un rectángulo,o cualquier otro UIElement. Elevento correspondiente variará enfunción de los que tenga definidosel elemento.[ ]

NOTA

Creación de animaciones mediantecódigo

Ya comentamos antes que todo este pro-ceso es posible realizarlo desde puro códi-go C# o VB.NET. Para ello nos basta concrear un proyecto inicial y realizar todas las operacio-nes de creación y puesta en marcha de la animación enun método llamado a continuación de InitializeCom-ponent(), que –en este caso– bautizamos como CreaYE-jecutaAnimation() (listado 6).

El lector puede comprobar que el efecto es simi-lar al anterior e idéntico funcionalmente. Solo faltaañadir la llamada a este método en el manejador deevento que nos interese (o en InitializeComponent()si deseamos que se ejecute al cargar la página).

Líneas de tiempo y KeyFrames

Anticipábamos antes, que es posible controlar laforma en que se producen las transiciones de estado,recurriendo al concepto de KeyFrame, que establece laduración individual de cada uno de los segmentos en

que podemos dividir una animación. Es posible esta-blecer dos valores relacionados con el tiempo: la dura-ción (Duration), y el momento en que debe de con-cluir cada segmento a contar desde su inicio (KeyTi-me). Es posible representar gráficamente la forma enque evoluciona el valor de la propiedad en el tiempo.Con ello, tendríamos una idea visual del mecanismode interpolación lineal2 utilizado internamente parala construcción de la animación.

Conceptualmente, es algo similar a lo que puedeverse en la figura 2.

Al construir animaciones que utilicen este con-cepto, resulta de especial utilidad Expression Blend2.5 (June Preview, al escribir estas líneas), ya que dis-pone de un conjunto de herramientas visuales quepermiten realizar todo el proceso en modo diseño,generándose el código XAML asociado con él, ypudiendo probar el funcionamiento.

Supongamos que en el caso del dibujo se trata deanimar la propiedad Canvas.Left, al igual que hicimosanteriormente, pero el proceso se va a realizar en 3fases: en la primera se recorren 100 píxeles en 1 segun-do, en la segunda 200 en 3 segundos (va más despa-cio) y en la tercera 100 píxeles en 0,5 segundos (lamás rápida de todas).

Para ello, en el Explorador de proyectos, selec-cionamos la opción “Abrir con Expression Blend”

dotN

etM

anía

<<

20

dnm.especial.silverlight<<

Figura 2. La línea de tiempo abarca un total de 4.5segundos, y está dividida en 3 segmentos

de duración variable.

2 En análisis numérico, se denomina interpolación a la construcción de nuevos puntos partiendo del conocimiento de unconjunto discreto de puntos.

Listado 6

public void CreaYEjecutaAnimation(object sender, EventArgs e){// Creamos el rectángulo a animarRectangle Rect1 = new Rectangle();Rect1.Width = 180;Rect1.Height = 30;Rect1.SetValue(Canvas.LeftProperty, 50.0);Rect1.SetValue(Canvas.TopProperty, 50.0);

// .. y sus propiedadesColor myColor = Color.FromArgb(255, 255, 125, 0);SolidColorBrush myBrush = new SolidColorBrush();myBrush.Color = myColor;Rect1.Fill = myBrush;

// Añamos el rectángulo al contenedor.LayoutRoot.Children.Add(Rect1);

// establecemos la duraciónDuration duration = new Duration(TimeSpan.FromSeconds(0.5));DoubleAnimation Animation1 = new DoubleAnimation();Animation1.Duration = duration;Animation1.To = 200;

// Y creamos la animaciónStoryboard sb = new Storyboard();sb.Duration = duration;sb.Children.Add(Animation1);Storyboard.SetTarget(Animation1, Rect1);Storyboard.SetTargetProperty(

Animation1, new PropertyPath("(Canvas.Left)"));

// Añadir el Storyboard al recurso, para vincular animación y rectánguloLayoutRoot.Resources.Add("Key1", sb);

sb.Begin(); //Lanzar la animación}

El eje de las X representa el tiemponecesario para llegar a un valordado, mientras que los valores

intermedios hacia el valor final serepresentan en el eje de las Y

pulsando sobre el fichero Page.xaml, yuna vez allí, seleccionamos el controlque deseamos animar (de nombre recten el ejemplo). Después, sobre el panelizquierdo, en la sub-ventana “Objectsand Timeline”, creamos la nueva ani-

mación –aquí con el nombre sbMovi-miento–, y para editarla, movemos lalínea amarilla hasta el punto final de laduración del primer segmento (obser-varemos que hay un punto rojo en laparte superior de la pantalla, indicandoque “Timeline recording is on”, que sig-nifica que se están almacenando loscambios en las propiedades que reali-cemos para generar después el códigoXAML correspondiente).

Como puede verse, el proceso essimple. Una vez seleccionado el ele-mento y abierto el editor “Objects andTimeline”, procedemos por partes,moviendo la línea amarilla hasta el finalde cada segmento deseado; una vez allí,cambiamos el valor de la propiedad. Yesto, lo repetimos para cada segmento.

El resultado es un código algo dis-tinto, que utiliza un nuevo tipo de ele-mento llamado DoubleAnimationUsing-KeyFrames, cuyo contenido son elemen-

tos SplineDoubleKeyFrame, cada uno deellos indicando el tiempo transcurrido alconcluir la animación para cada KeyFra-me y el valor de la propiedad a cambiarque debe obtenerse en ese momento. Elcódigo puede verse en el listado 7.

Si el lector ejecuta el código ante-rior verá que, si bien el desplazamientose produce en tres tramos y –en cadauno– la velocidad es distinta (se recorredistinta distancia por unidad de tiem-po), dentro de cada tramo la velocidades constante, como no podía ser de otraforma, de acuerdo con la definición. Seha producido aquí un proceso de inter-polación lineal, para cada una de las tresfases. En la figura 4 vemos el gráficocorrespondiente para una interpolaciónlineal, que se obtiene en Blend pulsan-do en cada uno de los símbolos indica-dos por las flechas verdes de la figura 3.

Aquí podemos apreciar que la cur-va que describe la interpolación (el cál-culo de valores intermedios entre dosdados previamente) es –en realidad– unarecta. Eso nos está diciendo que la inter-polación se ha realizado en saltos dis-cretos y uniformes, sin cambios bruscosdentro de cada fase, y generando, de ese

modo, velocidades constantes en el des-plazamiento.

Por tanto, la cuestión es: ¿se puedenutilizar interpolaciones variables (nolineales) que permitan expresar con-ceptos como la aceleración (el cambiobrusco entre valores en el camino haciael valor final)? La respuesta, natural-mente, es que sí. Pero, en este caso, loque haremos será modificar la recta paraconvertirla en una curva. Y lo haremosde una manera totalmente visual. El ejede las X representa el tiempo necesariopara llegar a un valor dado, mientras quelos valores intermedios hacia el valorfinal se representan en el eje de las Y.Por tanto, dependiendo de cómo modi-fiquemos la curva, obtendremos resul-tados distintos.

Así pues, si volvemos al modo deedición y desplazamos los puntos ama-rillos hacia otro lugar de la cuadrícula,modificaremos esa recta, generando unacurva de interpolación, que dará comoresultado aceleraciones y deceleracio-nes. La figura 5 muestra el resultado delcambio.

El nuevo patrón obtenido es una cur-va con un punto de inflexión que pasadirectamente por el centro. En el primertramo, se produce una aceleración que vadescendiendo mientras se adoptan valo-res intermedios, volviendo a acelerarse enel tramo final. De hecho, como puede

dotN

etM

anía

<<

21

dnm.especial.silverlight<<

Figura 3: editor de líneas de tiempo en Expression Blend mostrando los 3 puntossegmentación de la animación. A la derecha, sub-ven tana de edición de posiciones de

objetos mostrando el valor de la propiedad Left al final de la animación.

Listado 7

<Storyboard x:Name="sbMovimiento"><DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rect"

Storyboard.TargetProperty="(Canvas.Left)"><SplineDoubleKeyFrame KeyTime="00:00:01" Value="100"/><SplineDoubleKeyFrame KeyTime="00:00:04" Value="300"/><SplineDoubleKeyFrame KeyTime="00:00:04.5" Value="400"/>

</DoubleAnimationUsingKeyFrames></Storyboard>

</UserControl.Resources>

Figura 4

dnm.especial.silverlight<<

intuir el lector, existe una relación direc-ta entre los valores intermedios obteni-dos y los valores de la función repre-sentada aquí.

En el código XAML no se han pro-ducido muchas modificaciones, en reali-dad, de hecho, lo único que ha cambiadoes que el segundo elemento SplineDou-

bleKeyFrame, contiene ahora un subele-mento KeySpline, donde se definen esoscambios de acuerdo con la sintaxis quepuede ver en el listado 8, donde simple-mente se indican 2 puntos de control, apartir de los cuales, el motor de Silverlightrealizará la interpolación de acuerdo conla curva definida. Pueden crearse tantascurvas distintas como permitan las com-binaciones posibles donde pueden ubi-carse los dos modificadores resaltados conun punto amarillo.

ConclusiónEl Silverlight Animation System es

una potente tecnología para construirlo que hasta ahora –en la Web– solopodía hacerse con soluciones más com-plejas y lenguajes no orientados a obje-tos. XAML + lenguajes .NET (por unlado) y Visual Studio 2008 con Expres-sion Blend, por el otro, nos permitiránindagar en este mundo fascinante y deenorme proyección.

Listado 8

<SplineDoubleKeyFrame KeyTime="00:00:04" Value="300"><SplineDoubleKeyFrame.KeySpline>

<KeySpline ControlPoint1="0.1019,0.899" ControlPoint2="0.893999993801117,0.094" /></SplineDoubleKeyFrame.KeySpline>

</SplineDoubleKeyFrame>

Figura 5

Bibliografía“Silverlight 2.0 Beta 2. Documenta-ción oficial”, Microsoft 2008 (SDKdel producto).

“Silverlight 2, Visual Essentials”, MathewMcDonald, APress, 2008 (e-book).

“Expression Blend 2: Building applica-tions in WPF and Silverlight”, VictorGaudioso. Ed. FriendsOf, 2008.

Desde los tiempos de Clipper, cualquier frame-work de desarrollo que se precie, ya sea orientadoa desktop o Web, debe incorporar un grid (o comodicen en latinoamerica una grilla) para la visuali-zación y edición de datos.

Si comparamos entre grids forms y Web, nosencontramos que estos últimos son bastantepobres. Han habido intentos de mejora tanto porMicrosoft (DataGrid, GridView) como por fabri-cantes de software externos (Infragistics, Tele-rik…), aún así, las limitaciones que HTML nosimpone quedan patentes.

A partir de la versión 2.0 Beta 1 de Silverlight,Microsoft ha incorporado un control llamadoDataGrid, con mayor sabor a Windows Forms.Con él, podemos:

• Redimensionar columnas mediante drag anddrop, o dejar que el propio control las vayaadaptando al tamaño del contenido.

• Redimensionar el propio control cuando elárea de la ventana cambia.

• Implementar binding directo y capturar en clien-te eventos como el comienzo de edición.

• Añadir, con un par de líneas de código, una vis-ta de detalle para el ítem seleccionado.

• Dar formato a columnas mediante clases sepa-radas (Value Converters), ordenación por colum-nas, detección automática de cambios…

Y lo mejor de todo… ¡¡ sin tener que teclearni una línea de código en Javascript !!

Este artículo está compuesto por dos apartados:• Mostrar información: cómo utilizar este con-

trol para visualizar información de solo lec-tura.

• Edición online: permitir al usuario cambiar des-de el propio grid el contenido de cualquiercampo, sin tener que ir a una vista de detalle.

Mostrar informaciónComencemos por cubrir la funcionalidad bási-

ca de este control: visualizar datos de solo lectu-ra. Como ejemplo vamos a construir una aplica-ción que muestre los ejemplares de la revista dot-NetManía de 2008, si hacemos clic en un núme-ro concreto se muestra una vista de detalle.

Para realizar este ejemplo contamos con unacapa de presentación en cliente, que será nuestroproyecto Silverlight, y una capa de backend en ellado del servidor que será un servicio Web queacceda a una base de datos (ver figura 1).

A partir de ahora cuando hablemos de capa de pre-sentación, nos estaremos refiriendo al proyecto Sil-verlight, y cuando lo hagamos de la capa de backendserá al proyecto Web (ASP .NET/servicios Web).

Los pasos para crear este proyecto:• Pulsamos en “New Project” y elegimos “Sil-

verlight Application”.• En la ventana que nos pregunta sobre el tipo

de solución Web a añadir, elegimos “Web Pro-ject”. De esta forma es más cómodo, ya que

Silverlight DataGrid

Silverlight

Si escuchamos la palabra “Silverlight” nos viene a la cabeza términos tanatractivos como multimedia, RIA, gráficos vectoriales… Todo esto esgenial, pero la mayoría de nosotros nos ganamos el pan de cada día conaplicaciones de gestión. ¿Qué nos ofrece Microsoft al respecto?

Braulio Díez trabaja en Avanade,

es colaborador habi-tual de dotNetManía

y administra el sitiotipsdotnet.

Reyes Garcíaha sido consultora

"todo terreno". Hoy sededica al gratificante

mundo de la docencia.

Braulio Díez Reyes García

dotN

etM

anía

<<

25

dnm.especial.silverlight<<

permite establecer un puerto fijo enel servidor Web de desarrollo.

• Una vez creado el proyecto, nues-tra capa de backend, hacemos clic ensus propiedades, y le damos unnúmero fijo de puerto, mediante“Servers” > “Specific port”.

• Creamos una clase entidad paraalmacenar el resultado de la con-sulta a la base de datos, también unservicio Web que será el que expon-ga los resultados vía HTTP.

• En nuestra capa de presentación,arrastramos desde el toolbox el con-trol DataGrid al fichero de códigoXAML de la página por defecto(esto creará las referencias y names-paces necesarios por nosotros).

• Definimos las columnas que vamos autilizar (también podemos dejar quelas infiera automáticamente). Ennuestro caso tendremos una vista nor-mal y una de detalle (listado 1).

• En la capa de presentación añadimosuna referencia al servicio Web defi-nido en la capa de backend. Al igualque en otros proyectos estándares.NET, esto se realiza mediante unasistente (“Add Service Reference”).

• En el code behind, leemos los datosy los enlazamos a nuestro controlDataGrid (listado 2).

La aplicación finalizada puede ver-se en la figura 2.

A este ejemplo básico se le puede aña-dir más funcionalidad: dar formato per-sonalizado a las columnas mediante Value

<UserControlxmlns:my=”clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data”(…)Loaded=”UserControl_Loaded” >

<Grid x:Name=”LayoutRoot” Background=”White”><my:DataGrid x:Name=”dgDNMGrid” IsReadOnly=”True” HeadersVisibility=”Column”

GridlinesVisibility=”All” RowDetailsVisibilityMode=”VisibleWhenSelected” SelectionMode=”Extended”AutoGenerateColumns=”False”>

<!— Vista normal de filas.—><my:DataGrid.Columns><my:DataGridTemplateColumn Width=”85” Header=”Numero”>

<my:DataGridTemplateColumn.CellTemplate><DataTemplate>

<TextBlock Text=”{Binding numero}”/></DataTemplate>

</my:DataGridTemplateColumn.CellTemplate></my:DataGridTemplateColumn><my:DataGridTemplateColumn Width=”85” Header=”Fecha”>

<my:DataGridTemplateColumn.CellTemplate><DataTemplate>

<TextBlock Text=”{Binding fecha}”/></DataTemplate>

</my:DataGridTemplateColumn.CellTemplate></my:DataGridTemplateColumn>

(…)

<my:DataGrid.RowDetailsTemplate><DataTemplate><!— Vista de detalle (incluye imagen con portada y lista de articulos)—><Grid Margin=”0” Height=”140”><Grid.RowDefinitions>

<RowDefinition Height=”140”/></Grid.RowDefinitions><Grid.ColumnDefinitions>

<ColumnDefinition Width=”100”/><ColumnDefinition Width=”370”/>

</Grid.ColumnDefinitions><Image Source=”{Binding portadaURL}”

Width=”100” Height=”106” Grid.Column=”0” Grid.Row=”0”></Image><TextBlock x:Name=”txEditorial” Height=”370” Text=”{Binding editorial}”

TextWrapping=”Wrap” FontSize=”9” Grid.Column=”1” Grid.Row=”0”/></Grid>

</DataTemplate></my:DataGrid.RowDetailsTemplate>

</my:DataGrid></Grid></UserControl>

Listado 1. XAML Definición de control DataGrids y columnas.

Figura 1. DataGrid Acceso a datos a través de servicios. Figura 2. Ejemplo DataGrid solo lectura

dotN

etM

anía

<<

26

dnm.especial.silverlight<<

Converters (p.e., mostrar una fecha en unformato especial), implementar ordena-ción por columnas, redimensionar de for-ma automática las columnas, etc. En “Parasaber más” podrá encontrar enlaces que lepermitirán seguir avanzando.

Edición online

Para esta sección vamos a montar unejemplo en el que editaremos una listasimple de películas (figura 3); tendre-mos dos campos:

• Título: nombre de la película, esun campo de texto libre.

• Género: rango de géneros disponi-bles (ciencia ficción, thriller, come-dia, …).

La aplicación nos permitirá editarlas películas directamente en el grid, asícomo crear nuevas y eliminar entradas.

Partiendo de lo aprendido en elapartado anterior, vamos a ver que nosharía falta añadir para poder realizarla edición online:

XAML

• En el campo Titulo podemos usar elmismo control tanto para mostrardatos como para editarlos (listado 3).

• Para el campo Genero, distinguimosentre visualización y edición: cuan-do solo mostremos datos usaremosuna caja de texto, cuando queramoseditarlos, mostraremos al usuariouna lista de géneros para que elija(listado 4).

Code behind

• La clase entidad que contiene la lis-ta de películas, debe heredar deObservableCollection (listado 5). Uti-lizando esto, cada vez que se aña-da/elimine un elemento, el DataGridrecibe una notificación y puedeactualizar su layout.

• Cuando mostramos el campo Gene-ro como solo lectura, tenemos queindicarle su descripción a la caja detexto que lo representa (en la enti-dad solo tenemos el ID numérico).

private void UserControl_Loaded(object sender, RoutedEventArgs e){

Binding binding = new BasicHttpBinding();// “Harcodeado”, en una applicación real guardar en fichero configuración.EndpointAddress address =

new EndpointAddress(“http://localhost:3150/NumerosDNM.asmx”);

Backend.NumerosDNMSoapClient proxy = new Ejemplo1_MostrarDatos.Backend.NumerosDNMSoapClient(binding, address);

// Hacemos la llamada al servicio Web de forma asíncrona cuando recibamos // la respuesta se lanza el método proxy_CargaListaNumerosDNMCompleted.proxy.CargaListaNumerosDNMCompleted += new EventHandler

<CargaListaNumerosDNMCompletedEventArgs> (proxy_CargaListaNumerosDNMCompleted);proxy.CargaListaNumerosDNMAsync();

}

void proxy_CargaListaNumerosDNMCompleted(object sender, Backend.CargaListaNumerosDNMCompletedEventArgs e)

{// El servicio Web nos devuelve una lista de numeros de DNM y la enlazamos al DataGridBackend.Entidad_NumeroDNM[] numerosDNM = e.Result.ToArray(); dgDNMGrid.ItemsSource = numerosDNM;

}

Listado 2. Acceso a datos via web service y enlace con el DataGrid.

Figura 3. Aplicación de ejemplo edición.

<!— Titulo es una caja de texto, aprovechamos el mismo control para visualizar y editar —>

<my:DataGridTextColumn x:Name=”colTitulo” Header=”Titulo” Width=”260”DisplayMemberBinding=”{Binding Pelicula, Mode=TwoWay}”/>

Listado 3. Columna de texto Titulo.

<!— Para Genero distinguimos entre visualizacion (TextBlock) y edición (lista de valores a elegir). —>

<my:DataGridTemplateColumn Header=”Genero” Width=”140”><my:DataGridTemplateColumn.CellTemplate>

<DataTemplate><TextBlock x:Name=”tbGenero” Text=”“ Loaded=”tbGenero_Loaded”/>

</DataTemplate></my:DataGridTemplateColumn.CellTemplate>

<my:DataGridTemplateColumn.CellEditingTemplate><DataTemplate>

<ListBox x:Name=”lbGenero” Height=”80” Loaded=”lbGenero_Loaded”></ListBox>

</DataTemplate></my:DataGridTemplateColumn.CellEditingTemplate>

</my:DataGridTemplateColumn>

Listado 4. Definición de columna Género.

dotN

etM

anía

<<

27

dnm.especial.silverlight<<

public class EntidadPeliculas : ObservableCollection<EntidadPelicula>{}

Listado 5. Lista ObservableCollection.

// Este evento se dispara cada vez que un TextBlock que contiene el Genero se ha cargado, es la oportunidad // perfecta para visualizar la descripcíon del campo en base al ID númerico de la entidad asociada.private void tbGenero_Loaded(object sender, RoutedEventArgs e){

// Obtenemos la caja de texto asociada a la columna Genero de la fila que se está cargando.TextBlock tbGenero = (TextBlock)sender;

// Obtenemos la entidad a la que está enlazada esta fila.EntidadPelicula entidadPelicula = (EntidadPelicula)tbGenero.DataContext;if (entidadPelicula != null){

// Hacemos una llamada para obtener la descripción del Genero a partir de su ID.string generoDescripcion = DameDescripcionGenero(entidadPelicula.Genero);// Se lo asignamos al control de solo lectura.tbGenero.Text = generoDescripcion;

}}

Listado 6. Carga de Genero solo lectura.

private void lbGenero_Loaded(object sender, RoutedEventArgs e){

ListBox lbEdit = (ListBox) sender;

// Extraemos la entidad película asociada a la fila que vamos a editar.EntidadPelicula peliculaActual = (EntidadPelicula) lbEdit.DataContext;// Asignamos como DataSource la lista de géneros disponibles.lbEdit.ItemsSource = _entidadGeneros;// Le indicamos que muestre en la lista la descripción de cada ítem.lbEdit.DisplayMemberPath = “Descripción”;// Seleccionamos en la lista el género asociado a la película que vamos a editar.lbEdit.SelectedItem = DevuelveItemGeneroAPartirDeID(peliculaActual.Genero);

}

Listado 7. Edición: carga del ListBox de géneros.

private void dgPeliculas_CommittingEdit(object sender, DataGridEndingEditEventArgs e){

// Solo nos interesa para el control listBox de géneros.ListBox lbEdit = e.Column.GetCellContent(e.Row) as ListBox;

// Extraemos la entidad película asociada a la fila que hemos editado.EntidadPelicula peliculaActual = (EntidadPelicula)e.Row.DataContext;if (lbEdit != null){

switch (lbEdit.Name){

case “lbGenero”:EntidadGenero generoSeleccionado = (EntidadGenero) lbEdit.SelectedItem;// Actualizamos la entidad película con el género seleccionado.peliculaActual.Genero = generoSeleccionado.ID; break;

}

}}

Listado 8. Guardar cambios antes de volver a modo lectura.

dnm.especial.silverlight<<

Para ello nos suscribimos al eventoloaded del control y le indicamos ladescripción del campo en base alindicador numérico (listado 6).

• Una vez que entramos en modo edi-ción de una fila, ya sea haciendodoble clic sobre la misma o pulsan-do sobre el botón “Editar Película”,tenemos que visualizar una lista degéneros, y permitir al usuario selec-cionar el que estime conveniente.Para ello nos suscribimos al evento

que nos indica que se acaba de car-gar el Listbox de géneros, y lo car-gamos con los valores de la entidadcorrespondiente (listado 7).

• Cuando el usuario sale del modoedición, debemos de actualizar loscambios en la entidad correspon-diente, para ello nos suscribimos alevento Commiting_Edit del DataGrid(listado 8).

• Si lo que queremos es crear unanueva película, solo tenemos que

añadir un nuevo elemento a la lis-ta. Ésta, al ser del tipo Observable-Collection, notificará al DataGrid elcambio y éste se actualizará automá-ticamente (listado 9).

• Para borrar una entrada, solo tene-mos que eliminarla de la lista depelículas (listado 10).

ConclusiónLos desarrolladores Web estamos

de enhorabuena, con Silverlight Data-Grid contamos con un control flexi-ble, fácil de usar, potente, 100%.NET… casi, casi como un controldesktop.

private void btNuevaPelicula_Click(object sender, RoutedEventArgs e){

// Le asociamos un ID temporal ( ID -1) a la nueva entrada. EntidadPelicula nuevaPelicula =

new EntidadPelicula(){ID=-1,Pelicula=“*** Nueva Pelicula ***”,Genero=1};

// Lo posicionamos en la primera fila del grid.int indiceNuevoElemento = 0;PeliculasAsociadasAlGrid.Insert(indiceNuevoElemento, nuevaPelicula);// Lo seleccionamos.dgPeliculas.SelectedItem = nuevaPelicula;

// Nos aseguramos que el nuevo item es visible y cambiamos a modo edición.dgPeliculas.ScrollIntoView(nuevaPelicula, dgPeliculas.Columns[1]);dgPeliculas.BeginEdit();

}

Listado 9. Añadir una nueva película.

Para saber más...http://blogs.msdn.com/scmorris. Blog muy completo del Project Manager de Silverlight DataGrid. En el podrá encontrartutoriales introductorios y tópicos avanzados (implementar la ordenación, redimensionar columnas en base al contenido, uti-lizar Value Converters, etc.).

http://blog.seancleaver.com/sean_cleaver/2008/05/combobox-dropdo.html. Implementación sencilla de un dropdownlist.

http://www.c-sharpcorner.com/UploadFile/nipuntomar/SilverlightADONETDataService07222008140755PM/SilverlightADONET-

DataService.aspx. Introducción a Silverlight Data Grid + ADO .NET Services (Astoria).

http://www.c-sharpcorner.com/UploadFile/nipuntomar/PagingSilverlightDataGrid07242008140228PM/PagingSilverlightData-

Grid.aspx. Cómo implementar paginación en un DataGrid.

private void btBorrarPelicula_Click(object sender, RoutedEventArgs e){

EntidadPelicula peliculaSeleccionada = dgPeliculas.SelectedItem as EntidadPelicula;if (peliculaSeleccionada != null){

PeliculasAsociadasAlGrid.Remove(peliculaSeleccionada);}

}

Listado 10. Borrar una película.

Los desarrolladores Webestamos de enhorabuena,con Silverlight DataGrid contamos con un control

flexible, fácil de usar, potente,100% .NET… casi, casi

como un control desktop

Las comunicaciones son una parte muy impor-tante de Silverlight, y más ahora que se cumplendos factores muy importantes: uno es que ya tene-mos licencia go live, con lo que es posible publicaren Internet aplicaciones comerciales de formalegal; el segundo factor es que ya está permitidocomunicarse entre dominios. Ambos infieren enque es un momento interesante para examinar eindagar a fondo las capacidades de networking deSilverlight.

En cualquier caso, y antes que nadie men-cione “¿Y los ADO.NET Data Services?”, decirque originalmente este artículo estaba enfoca-do a estos nuevos servicios, pero esto ha cam-biado debido a los problemas que conlleva elactual Service Pack 1 para Visual Studio 2008.Para ayuda y referencia en la instalación, ver lossiguientes enlaces:

http://www.itwriting.com/blog/665-more-sil-

verlight-visual-studio-setup-hassles.html

http://silverlight.net/forums/t/17500.aspx

Otra razón importante para no tratar este temaes la de no disponer del plugin de Visual StudioADO.NET Data Services Silverlight Add-On(http://blogs.msdn.com/astoriateam/archi-ve/2008/01/11/ado-net-data-services-silverlight-

add-on.aspx) realizado por el equipo de Astoria,con lo que la única forma es conectar y operar conlos ADO.NET Data Services es hacerlo “a mano”.Y –muy probablemente la forma de hacerlo hayacambiado en el momento de impresión del artí-

culo. Por ello se deja de lado este tema, reserván-dolo para un posterior artículo y me he centradoen algo actualmente más terrenal y práctico, conpocas posibilidades de cambio en la reléase finalde Silverlight.

Para estar al día de los ADO.NET Data Ser-vices, recomiendo os suscribáis al blog del Asto-ria Team, cuya URL es la siguiente: http://blogs.msdn.com/astoriateam.

Por lo que respecta a los servicios Web desdeSilverlight, que seguidamente veremos, remarcarque son extremadamente potentes, basados encliente rico y que actualmente soportan cross domain(llamadas a dominios diferentes del que se ejecu-tan), siempre que el servicio/sitio Web de origendel servicio lo permita –luego vemos este puntocon mayor detalle–.

Con esta nueva versión de Silverlight se nosabren las puertas al desarrollo de aplicaciones alta-mente interconectadas, pudiendo añadirles lariqueza e interacción que deseemos. Para hacer-nos una idea, antes de “ahora” para hacer algosimilar a lo que nos permite Silverlight, debíamosdominar JavaScript, AJAX, DHTML, y realizarmultitud de servicios Web tipo proxy en el Servi-dor... Actualmente podemos desarrollarlo en unúnico lenguaje que unifica todo lo que necesita-mos, Silverlight, y en la capa de cliente, desaho-gando al servidor de una parte considerablemen-te significativa de su carga.

En la tabla 1, podemos ver un cuadro aclara-torio de los diferentes acrónimos utilizados en esteartículo.

Comunicaciones en Silverlight

Silverlight

El artículo que se presenta ahonda el estado actual de las comunicacio-nes en Silverlight, haciendo hincapié en servicios Web WCF (la formaactualmente recomendada de interoperar entre un servidor y Silver-light), servicios Web ASP.NET ASMX, así como solicitudes vía HTTP,como el acceso a feeds RSS, POX y JSON.

José Luis Latorre

José Luis Latorre es MVPde Microsoft, trabaja como

.NET Software Architecten IN2 (http://www.in2.es)

y está especializado entecnologías RIA y UX

(WPF, Silverlight). Esmiembro del Board direc-

tivo de INETA Europa(http://europe.ineta.org) y

coordina el grupo deusuarios .NET de Barcelo-na, http://www.bcndev.net).

También es tutor de CampusMVP.

dotN

etM

anía

<<

31

dnm.especial.silverlight<<

Antes de empezar...

Para poder desarrollar y probar las técnicas aquíexpuestas, se recomienda Visual Studio 2008 con lasSilverlight Tools Beta 2 for Visual Studio 2008.Dado que estas herramientas están en fase Beta,comportan cierto riesgo en su instalación, por loque se recomienda no realizarla en un entorno deproducción. Los enlaces para la descarga de las toolsestán disponibles en la página Web oficial de Sil-verlight, http://silverlight.net/GetStarted.

En cualquier caso no es necesario instalar el plug-in ni el SDK, ya que las Tools ya instalan estos com-ponentes.

Como nos centraremos en la parte de codificacióny comunicaciones, no es necesaria la instalación deBlend y/o Deep Zoom Composer.

Por otro lado, es interesante tener claros unos con-ceptos iniciales:

• Solo podemos acceder a servicios Web de formaasíncrona.

• Las llamadas Cross-domain son posibles, perodeben ser autorizadas por el archivo de políticasclientaccesspolicy.xml.

Y al código...A continuación, desarrollaremos una aplicación que nosservirá para ejemplificar los diferentes métodos de comu-nicación de Silverlight hacia WCF, ASMX y RSS.

Accediendo a servicios ASMXCon Visual Studio 2008 abierto, crearemos un nue-vo proyecto de tipo “Silverlight Application”, de nom-bre SilverlightCommunications, como podemos ver enla figura1.

Seguido, se nos presenta el dialogo con el título“Add Silverlight Application”, en el que selecciona-mos la opción de añadir un proyecto Web a la solu-ción para hospedar el control. Es necesario realizareste paso para poder hospedar la aplicación Silver-light y permitir llamadas entre dominios. Si se ejecu-ta en una página HTML, no está en ningún dominioy por tanto estas llamadas fallaran. Podemos ver eldiálogo en la figura 2.

Con esto, tenemos la aplicación “base” limpia ylista para empezar a añadirle funcionalidades. Losiguiente que haremos será incorporarle un servicioASMX. En el proyecto Web, hacemos clic derecho yañadimos un nuevo elemento, de nombre “Web Ser-vice”, le denominamos ASMXWebService.asmx y pulsa-mos en “Add”. Podemos ver el diálogo en la figura 3.

Al pulsar “Add” nos habrá creado el código delservicio en App_code/ASMXWebService.cs. Ahí inserta-remos el método que vamos a llamar (listado 1).

Seguido, desde el proyecto Silverlight, añadire-mos la referencia al servicio Web que acabamos de

Figura 1

TerminologíaRIA, Rich Internet ApplicationSOAP, Simple Object Access ProtocolWDSL, Web Services Description Language

REST, REpresentational State Transfer

POX, Plain Old XML

JSON, JavaScript Object Notation

RSS, Really Simple Syndication

Figura 2

Tabla 1

dotN

etM

anía

<<

32

dnm.especial.silverlight<<

crear. Hacemos clic derecho sobre el proyecto Sil-verlightCommunications y seleccionamos “Add Servi-ce Reference”. Inicialmente no lo veremos, debien-do hacer clic en “Discover Services in Solution” paraver los servicios disponibles en la solución actual.Seleccionamos el servicio ASMX disponible, le damos

el nombre ASMXServiceReference para generar nues-tro proxy y pulsamos “OK”. En la figura 4, tenemosel diálogo correspondiente.

Como nota, los servicios Web ASMX en Silver-light utilizan SOAP por defecto, pero utilizan el mis-mo modelo que WCF, debiendo definir previamen-te un binding y un endpoint. Para nuestro servicioASMX, el binding será basicHttpBinding y el endpoint,el URI al archivo .asmx.

Antes de programar el acceso al servicio WebASMX vía el proxy que acabamos de autogenerar,montaremos el interfaz Silverlight que nos servirápara comunicarnos con los diferentes serviciosWeb. Para ello, en el proyecto Silverlight, edita-remos el fuente XAML y en el grid añadiremos unTabControl con una pestaña por método de comu-nicación (listado 2).

Para añadir la funcionalidad, agregamos el con-trolador del evento click al botón, tal como vemosen el listado 3.

De esta manera, accederemos a su manejador deeventos. Previamente, deberemos añadir el espaciode nombres System.ServiceModel, necesario para elmanejo de servicios, con la clausula using System.Ser-viceModel; correspondiente.

Acto seguido, añadiremos el código de manejo delservicio Web, empezando por definir el binding y elendpoint. Éstos, anteriormente era recomendableincluirlos para evitar que el proxy que se instancia pos-teriormente de problemas. En cualquier caso, en laBeta 2 funciona sin problemas y es innecesario. Lodejamos como referencia, comentado en el código,por si vuelve a ser necesaria su implementación talcomo vemos en el listado 4.

Actualmente con solo instanciar el proxy ya pode-mos invocar al servicio Web (listado 5).

Figura 3

Listado 1

[WebMethod]public string SaludosDesdeASMX(string nombre){

return string.Format(“Servicio ASMX: ¡Hola {0}!”, nombre);

}

Figura 4

Listado 2

<Grid x:Name=”LayoutRoot” Background=”White”><my:TabControl>

<my:TabItem Header=”ASMX Web Service”><StackPanel>

<Button x:Name=”ASMXButton”Content=”Invocar al Servicio Web ASMX”>

</Button><TextBox Text=”Resultado de la invocación:”></TextBox><TextBlock x:Name=”ASMXOutputText”> </TextBlock>

</StackPanel></my:TabItem><my:TabItem Header=”WCF Web Service”> </my:TabItem><my:TabItem Header=”HTTP (RSS, POX, JSON,..)”> </my:TabItem>

</my:TabControl></Grid>

Listado 3

<Button x:Name=”ASMXButton”Content=”Invocar al Servicio Web ASMX”Click=”ASMXButton_Click”></Button>

Como vimos previamente, todas lasllamadas a WebServices son asíncronasen Silverlight, así que antes de invocarel servicio, enlazamos el manejador delevento de finalización de la llamada,ponemos el proxy con su evento de com-pletado, += para instanciarlo y recorde-mos pulsar [Tab] dos veces para queVisual Studio nos auto-completeautomáticamente la instanciación en elprimer Tab y el método de completa-do en el segundo (listado 6).

Y por último, invocamos el serviciocon el texto que hemos puesto en elTextBox a tal efecto, ASMXNombre.

asmx_Proxy.SaludosDesdeASMXAsync(

ASMXNombre.Text);

El método de completado podemosverlo en el listado 7.

Básicamente asignamos a la pro-piedad Text de un TextBox el resultadodel servicio Web ASMX convertido astring.

Para ejecutar el ejemplo, introdu-ciremos un nombre en la casilla supe-rior y haremos clic en el botón “Invo-car al servicio Web ASMX”. Rápida-mente se nos mostrará el resultado enel TextBox inferior (figura 5).

Accediendo a servicios WCF

Para desarrollar este ejemplo, utili-zaremos la aplicación anterior, para laque deberemos de añadir, inicialmenteun servicio Web WCF.

A destacar que en la Beta 2 de Sil-verlight tenemos un nuevo elemento,el “Silverlight-enabled WCF Servi-ce”, que no es más que un servicioWCF normal pero adecuado a Sil-

verlight, de manera que no tendre-mos que hacer ajustes en el archivoweb.config de ASP.NET, como cam-biar wsHttpBinding a basicHttpBin-ding, ya que Silverlight solamentesoporta este tipo de binding WCF (porahora).

Añadiremos este servicio WebWCF comentado en el proyecto Web,dándole como nombre WCFService.svc.

Lo primero que observamos esque en lugar de tener dos archivos decódigo, uno para la interfaz del ser-vicio y otro para la implementación,solo tenemos uno. Esto es probableque cambie (al menos lo espero) peropor ahora seguiremos el modelo quenos ha propuesto este servicio Web.

dotN

etM

anía

<<

33

dnm.especial.silverlight<<

Listado 4

BasicHttpBinding bind = new BasicHttpBinding();EndpointAddress endpoint = new EndpointAddress(

“http://localhost:1545/SilverlightCommunicationsWeb/ASMXWebService.asmx”);

Listado 5

ASMXServiceReference.ASMXWebServiceSoapClient asmx_Proxy = new ASMXServiceReference.ASMXWebServiceSoapClient();

ASMXServiceReference.ASMXWebServiceSoapClient asmx_Proxy = new ASMXServiceReference.ASMXWebServiceSoapClient(bind, endpoint);

Listado 6

asmx_Proxy.SaludosDesdeASMXCompleted += new EventHandler<SilverlightCommunications.ASMXServiceReference.SaludosDesdeASMXCompletedEventArgs>(asmx_Proxy_SaludosDesdeASMXCompleted);

Listado 7

void asmx_Proxy_SaludosDesdeASMXCompleted(object sender,SilverlightCommunications.ASMXServiceReference.SaludosDesdeASMXCompletedEventArgs e){

ASMXOutputText.Text = string.Format(“{0}”, e.Result.ToString());}

Figura 5

En la Beta 2 de Silverlighttenemos un nuevo

elemento, el “Silverlight-enabled WCF Service”

En cualquier caso el resultado es elmismo.

Como su implementación es muysimilar al servicio Web ASMX, vamosa complicarlo añadiendo complejidadde tipos. Nos vamos al archivo WCFSer-vice.cs generado y añadimos el códigodel listado 8 después de la implemen-tación del método DoWork() que nos vie-ne por defecto como ejemplo.

Así utilizamos algunas de las nue-vas características de .NET 3.5, inclui-das obviamente en Silverlight 2.0,como los constructores de objetos, eneste caso.

Añadimos con “Add Service Refe-rence” la referencia del servicio WCF alproyecto Silverlight, a la que llamamosWCFServiceReference (ver figura 6).

Cambiaremos la interfaz dePage.xaml para añadir la pestaña corres-pondiente al servicio WCF (listado 9).

Pondremos un botón, un texto queidentifique al resultado y un Itemscon-trol para mostrar el resultado de lacolección de animales que pasamos enel servicio.

Seguido, codificamos el evento declick del control button, añadiendo uncódigo idéntico al visto anteriormente(listado 10).

Después montamos el manejadordel evento Completado del servicio Web(listado 11).

Recuperamos el resultado ponién-dolo en una colección a la que poste-riormente filtramos por raza conLINQ, siendo ésta otra de las ventajasde .NET 3.5 que también tenemos enSilverlight 2.0.

dotN

etM

anía

<<

34

dnm.especial.silverlight<<

Listado 8

[OperationContract]public List<animal> GetAnimals(){

List<animal> animals = new List<animal>();

animals.Add(new animal() { nombre = “Pancho”, raza = “gato” });animals.Add(new animal() { nombre = “Martita”, raza = “gato” });animals.Add(new animal() { nombre = “Carla”, raza = “perro” });animals.Add(new animal() { nombre = “Percy”, raza = “perro” });animals.Add(new animal() { nombre = “Alicia Alberta”, raza = “tortuga” });

return animals;}

[DataContract]public class animal{

[DataMember] public string nombre;[DataMember] public string raza;

}

Figura 6

Listado 9

<my:TabItem Header=”WCF Web Service”><StackPanel>

<Button x:Name=”WCFButton” Content=”Invocar al Servicio Web ASMX”></Button><TextBlock x:Name=”TxtResultWCF” Text=”Resultado de la invocación:”></TextBlock><ItemsControl x:Name=”Animals”>

<ItemsControl.ItemTemplate><DataTemplate>

<StackPanel Orientation=”Horizontal”><TextBlock Text=”{Binding nombre}” /><TextBlock Text=” - “ /><TextBlock Text=”{Binding raza}” />

</StackPanel></DataTemplate>

</ItemsControl.ItemTemplate></ItemsControl>

</StackPanel></my:TabItem>

Listado 10

private void WCFButton_Click(object sender, RoutedEventArgs e){

WCFServiceReference.WCFServiceClient wcf_proxy = new SilverlightCommunications.WCFServiceReference.WCFServiceClient();

wcf_proxy.GetAnimalsCompleted += new EventHandler<SilverlightCommunications.WCFServiceReference.

GetAnimalsCompletedEventArgs>(wcf_proxy_GetAnimalsCompleted);wcf_proxy.GetAnimalsAsync();

}

dotN

etM

anía

<<

36

dnm.especial.silverlight<<

A continuación, vaciamos la colec-ción que teníamos previamente en elcontrol ItemsSource "Animals" y le asig-namos la colección filtrada como ori-gen de datos del control. El resultado,en este caso, son los animales cuya fami-lia es gato o perro, tal y como se ve enla figura 7.

Accediendo a RSS (HTTP)

En esta parte, añadiremos única-mente el cliente, ya que el acceso lo rea-lizaremos contra orígenes de datos yaexistentes y bien conocidos por muchos,o eso espero.

En este caso, no podemos generarun proxy, ya que no hay un contrato ypor ello no son descubribles.

Para empezar, en el proyecto Silver-light, añadiremos una referencia a Sys-tem.ServiceModel.Syndication, necesa-rio para trabajar con sindicación de con-tenidos RSS y añadiremos la clausula

using en Page.cs. Seguido, añadiremos lainterfaz XAML correspondiente enPage.xaml, (listado 12).

En ella, destacamos el uso del con-trol ScrollViewer para contener un blo-que de texto que se ajusta dinámica-mente a su contenido.

Seguido, recuperaremos el feed RSSde la URL que previamente hemos intro-ducido en el interfaz Silverlight y lo pro-cesamos para darle un aspecto inteligible.

En el manejador del botón utiliza-remos la clase WebClient, que podemosencontrarla en el espacio de nombresSystem.Net (también la tenemos en el.NET Framework completo). Esta cla-se podemos utilizarla para descargar deforma asíncrona contenido de una URLconcreta.

Hay que destacar que WebClient esextremadamente potente, y aunque enmuchos casos podamos hacer práctica-mente lo mismo utilizando HttpWebRe-quest, seguramente muy conocida pormuchos lectores, es recomendable utili-zar WebClient en Silverlight, sobre todopor su sencillez y facilidad de uso. En cual-quier caso, en la versión actual al momen-to de escribir el artículo (Silverlight V2.0Beta 2) WebClient soporta GET y POST, tam-bién se puede ejecutar desde un threaddiferente al de la interfaz de usuario, loque es de agradecer para según qué esce-narios. Por otro lado, esta clase tiene unevento bastante interesante, el Download-ProgressChanged, que nos permite cono-cer la evolución de una petición asincro-na, pudiendo mostrar el progreso de ladescarga en un texto o montar algo másevolucionado como una barra de progre-so o animación que indique su estado.

En el listado 13 creamos una instan-cia de WebClient y asociamos los maneja-dores de los eventos de completado y deDownloadProgressChanged. Por último, lan-zamos la petición de lectura asíncrona dela cadena que hayamos puesto como ori-gen de RSS. Nota: no se han añadido con-troles de errores por claridad, así que cual-quier fallo provocará un error.

Luego ponemos los manejadores deeventos, por un lado, la actualizacióndel indicador de progreso (listado 14);y, por otro la gestión de completado. Enésta, el resultado es un archivo XML asíque debemos construir un XmlReader y car-garlo desde la clase SyndicationFeed (paraeso agregamos el ensamblado System.Ser-viceModel.Syndication al proyecto). Estaclase nos modela el feed y facilita la nave-gación y manejo del mismo, como se pue-de ver en el listado 15.

Listado 11

void wcf_proxy_GetAnimalsCompleted(object sender, SilverlightCommunications.WCFServiceReference.GetAnimalsCompletedEventArgs e)

{ObservableCollection<WCFServiceReference.WCFServiceanimal> animales = e.Result;

var animalesFiltrados = from animal in animaleswhere (animal.raza.Equals(“gato”) ||

animal.raza.Equals(“perro”))select animal;

Animals.Items.Clear();//Animals.ItemsSource = animales;Animals.ItemsSource = animalesFiltrados;

}

Figura 7

Listado 12

<my:TabItem Header=”HTTP (RSS, POX, JSON,..)”><StackPanel>

<StackPanel Orientation=”Horizontal”><TextBlock>RSS URL:</TextBlock><TextBox x:Name=”RSSUrl” Width=”450”></TextBox>

</StackPanel><Button x:Name=”RSSButton” Content=”Solicitud HTTP a origen RSS”

Click=”RSSButtonClick”></Button><TextBlock Text=”Resultado de la invocación:”></TextBlock><ScrollViewer Height=”200” HorizontalScrollBarVisibility=”Auto”

VerticalScrollBarVisibility=”Auto”><TextBox x:Name=”RSSOutputText”></TextBox>

</ScrollViewer></StackPanel>

</my:TabItem>

dotN

etM

anía

<<

37

dnm.especial.silverlight<<

Por último, nos queda probarlo. Si loejecutamos y accedemos, por ejemplo, alfeed del sistema de blogs de la comunidadde desarrolladores de Barcelona http://bcngeeks.net/blogs/MainFeed.aspx, vere-mos que la lectura del feed nos falla estre-pitosamente. Ahora probaremos el feed degeeks.ms, http://geeks.ms/blogs/main-feed.aspx, y veremos que si nos los recu-pera, como se puede ver en la figura 8.

La razón de ello es que geeks.ms tie-ne algo que bcngeeks.net no tiene,

aparte de muchos más posts y actividad:la clausula de políticas de acceso. Esto noes más que un documento XML en elque se basa el sistema de acceso entredominios de Silverlight. El archivo encuestión se llama clientaccesspolicy.xmly define las políticas de acceso a los servi-cios de un sitio desde diferentes dominios.Este archivo deberá estar en la raíz delsitio Web, con lo que se define explícita-mente el uso de TODOS los servicios deeste sitio, que de ser sensibles, puede serconveniente crearlos en un subdominio.De hecho, es la práctica recomendadaactualmente. En el caso de la política deacceso de geeks.ms, disponible enhttp://geeks.ms/clientaccesspolicy.xml,ésta es la recomendada por defecto, quepodemos ver en el listado 16.

En ella, por un lado, damos accesoa todos los dominios para que accedana todos los servicios que ofrece nuestrodominio y, por otro lado, se extiendenestos permisos de acceso del directorioprincipal hacia todos sus subdirectorios.

Si abrimos un asistente para anali-zar lo que ocurre, como la barra de nave-gador “Web Development Center” deNikhil Khotari, ver http://pro-

jects.nikhilk.net/WebDevHelper, podre-mos ver las peticiones HTTP que rea-liza Silverlight. Podemos ver las peti-ciones correspondientes a la carga delRSS de geeks.ms en la figura 9.

Vemos que primero ha accedido alarchivo de políticas, lo ha validado yseguidamente ha accedido al feed.

Listado 13

private void RSSButtonClick(object sender, RoutedEventArgs e){

WebClient wc = new WebClient();wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);wc.DownloadProgressChanged +=

new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);wc.OpenReadAsync(new Uri(RSSUrl.Text));

}

Listado 14

void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e){

if (e.ProgressPercentage < 100){

IndicadorProgreso.Text = “Cargando: “ + e.ProgressPercentage + “%”;}else{

IndicadorProgreso.Text = string.Empty;}

}

Listado 15

void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e){

if ((e.Error == null) && (e.Result != null)){

XmlReader xrdr = XmlReader.Create(e.Result);SyndicationFeed feed = SyndicationFeed.Load(xrdr);

RSSOutputText.Text = “”;

foreach (SyndicationItem item in feed.Items){

RSSOutputText.Text += “* “ + item.Title.Text + Environment.NewLine;RSSOutputText.Text += “ Publicado el: “ + item.PublishDate +

Environment.NewLine;}

}else RSSOutputText.Text = “Ocurrio un error en la petición RSS...”;

}

Figura 8

Listado 16

<?xml version=”1.0” encoding=”utf-8” ?>- <access-polilcy>- <cross-domain-access>- <policy>- <allow-from http-request-headers=”*”>

<domain uri=”*”/></allow-from>

- <grant-to><resource path=”/”

include-subpaths=”true”/></grant-to></policy></cross-domain-access></access-polilcy>

Saliendo del laboratorio (Outof the Lab)

Fuera del entorno controlado denuestro equipo, es interesante ofrecerunas pinceladas de cómo acceder a unentorno de Web Services real, como porejemplo a los servicios Web de Com-munity Credit (http://www.community-credit.com).

Community Credit, para los que nolo conozcan, es una Web 2.0 que bási-camente se dedica a premiar a la gen-te por sus contribuciones a la comuni-dad de desarrolladores. Ello se reali-za en base a una interfaz Web en la quepodemos subir nuestros logros y accio-nes. En base a ellos, de forma mensual,se efectúa un ranking y una entrega almes de premios de forma totalmentegratuita.

Como habrán sospechado, existeuna interfaz de servicios Web, que pue-den curiosear en http://www.community-credit.com/help, que nos permite subirnuestras acciones en pro de la comuni-dad, ver los ganadores por fecha y otrostantos métodos.

Bien, hemos procedido a montar uncliente que se conecte a estos serviciospara, por ejemplo, permitirnos ver nues-tros últimos resultados.

El servicio al que nos conectaremos,de tipo WCF, está en http://servi-ces.community-credit.com/CommunityCre-

ditData.svc. A destacar del mismo, queha sido montado básicamente para rea-lizar el artículo y muy probablementese convertirá en la evolución del ante-rior servicio ASMX... Ello es debido aque al referenciar el servicio .asmx apa-rentemente no se generaba bien el proxy,dando errores de tipo “Type expected”y de objetos Schema inexistentes que evi-taban la compilación.

En el caso del servicio actual, WCF,éste dio algunos problemas cuyas des-

cripciones (y soluciones) puden ver acontinuación:

Área 1: ajustando el archivo Service-References.ClientConfig

Una vez hemos añadido una referen-cia al servicio, podemos encontrarnos quedebamos ajustar el archivo de configura-ción ServiceReferences.ClientConfigpara que la aplicación se nos ejecute ade-cuadamente. Esto puede sorprender aalgunos ya que este archivo se generaautomáticamente. En cualquier caso, esun archivo relativamente pequeño y ajus-tarlo es bastante rápido una vez sepamoslos cambios a realizar. Hay dos puntos endonde esto suele ser necesario:

1. Especificando el contrato del endpoint

Si nos hallamos con un error de com-pilación como el siguiente:

Es debido a un fallo en la generacióndel endpoint, que en según qué ocasioneso instalaciones falla en la Beta 2. Comoresultado, al realizar llamadas al servicioWeb, no puede hallar el endpoint. Parasolucionarlo, deberemos añadir el nom-bre del ensamblado (espacio de nombrespor defecto) al inicio del contrato. Ennuestro caso añadimos CommunityCredit-Silverlight al inicio de la propiedad con-tract para que así lo referencie correcta-mente.

Antes:contract=“CommunityCreditService.

ICommunityCreditData“

name=“BasicHttpBinding_ICommunityCreditData“ />

Después: contract=“CommunityCreditSilverlight.

CommunityCreditService.ICommunityCreditData“

name=“BasicHttpBinding_ICommunityCreditData“ />

2. Incrementando el tamaño máximo del

buffer (maxBufferSize);

Por defecto, el maxBufferSize estaespecificado en 65536 y esta cifra suele sera menudo muy pequeña. Si el tamaño delos datos de retorno es variable, es muyprobable que debamos cambiarla en unfuturo. Si el tamaño es muy pequeño,seguramente recibiremos el mensaje deerror:

“The maximum message size quota forincoming messages (65536) has been excee-ded. To increase the quota, use the MaxRecei-vedMessageSize property on the appropriatebinding element.”

Para solucionar este problema, bastasimplemente con incrementar el tamañoen ambas propiedades: maxBufferSize ymaxReceivedMessageSize.

Área 2: ajustando el tipo de colecciónpor defecto

En la Beta 2, en la configuración delservicio Web, el tipo de colección (Collec-tion type) está puesto a "ObservableCollection" y esto puede causar algunosproblemas al cargar un DataGrid en Sil-verlight. Para solucionar esto, necesita-remos cambiar el tipo a un Array. Reali-zar este ajuste es simple, hacemos clicderecho sobre la referencia al servicio,seleccionamos "Configure Service Refe-rence" y cambiamos el Collection Typede System.Collections.ObjectModel.ObservableCollection a System.array.

Por último, quiero agradecer a DavidSilverlight por su tiempo y dedicación enla conexión a los servicios de CommunityCredit y en solucionar los diferentes pro-blemas encontrados.

También tienen una aplicación deejemplo de acceso a los servicios deCommunity Credit disponible enhttp://geeks.ms/blogs/jllatorre. Éstales puede servir tanto de ejemplo deestas técnicas como de base para desa-rrollar una aplicación que muestre suslogros y progresos.

dotN

etM

anía

<<

38

dnm.especial.silverlight<<

Figura 9

Figura 10

www.Abox.com

…We make sure your application rocks!Advantage Database Server es un sistema de base de datos cliente/servidor de alto rendimiento y total-mente equipada, especialmente diseñado para darrespuesta a las necesidades de los desarrolladores deaplicaciones• Proporciona tanto acceso a tablas de datos ISAM como SQL • Acceso nativo a archivos dbf a través de Cliente/Servidor,

sin necesidad de importar datos.• Multi Plataforma (Windows, Linux, Netware) • Bajo Coste Total de Propiedad: fácil instalación, administración

cero, Requisitos mínimos de hardware.

Mejoras y nuevas Funcionalidades en la version 9: • Mejoras en el soporte de FoxPro: Advantage 9 soporta la versión

de Visual FoxPro 9. • SQL Debugger ha sido añadido a la versión 9 de ADS Architect. • Notificaciones de Eventos. • 64-bit en servidores Windows y Linux: Advantage ha sido

adaptado para funcionar como aplicación nativa de 64-bit en las versiones de x64 de Windows y Linux.

A que espera!Consiga ya 2 usuarios gratuitos (solo para desarrollo) enviando unEmail a [email protected]

C/ Manso, 26-28, 2ª planta 08015 Barcelona Teléfono: 93 426 22 57E-mail: [email protected]

Los webparts son componentes reusables que pue-den agregarse como contenido en páginas de Sha-rePoint. Por cuestiones de compatibilidad conSharePoint 2003, ahora coexisten dos tipos dis-tintos de webparts:

1. Los webparts que heredan de Microsoft.Sha-rePoint.WebParts, que funcionan con Sha-rePoint 2003 y 2007.

2. Los webparts que heredan System.Web.UI.WebControls.WebParts para WSS y MOSS2007.

Un webpart podrá hacer de host para aplicacio-nes Silverlight, aportando características muy úti-les para el desarrollo en SharePoint. Imagine porun lado las facilidades que aportan el uso de web-parts, permitiendo ser colocados en lugares distin-tos dentro de la página de forma sencilla, así comola facilidad de configuración exponiendo propie-dades a un toolpart, complementado con las gran-des capacidades gráficas que ofrece Silverlight.

Silverlight 1.0 webpartsEmbeber una aplicación Silverlight 1.0 en unwebpart para ser utilizado en SharePoint cons-ta de varios pasos. Básicamente, habrá que hacerun despliegue de los ficheros .xaml, e incluirtodos aquellos ficheros .js que contengan elcódigo Javascript que define la lógica de nues-tra aplicación Silverlight:

1. Incluir los ficheros Javascript y XAML al pro-yecto (generalmente Silverlight.js, Page.xaml.js y Page.xaml).

2. Configurar la propiedad BuildAction como“Embedded Resource” en la ventana de pro-piedades para cada fichero .js y .xaml. Deesta forma se incluirán como recursos embe-bidos en el ensamblado.

3. Añadir el atributo System.Web.UI.WebResour-ce en el AssemblyInfo.cs, garantizando de esta

Webparts Silverlight para SharePoint

Silverlight

Este artículo pretende ilustrar una forma sencilla de introducir la nue-va tecnología de presentación para la Web que es Silverlight, en el desa-rrollo de WebParts.

Yamil Hernández

Yamil Hernández esLicenciado en Ciencias

de la Computación porla Universidad de La

Habana. Es un apasiona-do de las tecnologías

.NET. Colaborador, arti-culista e ilustrador de la

revista ddotNetManía.Actualmente trabajacomo Development

Advisor de Plain Concepts.

Figura 1

dotN

etM

anía

<<

41

dnm.especial.silverlight<<

forma permisos para que estos recursos sean ges-tionados por el handler WebResource.axd y paraasociar un tipo MIME a la respuesta.

[assembly: WebResource(“myNamespace.Silverlight.js”,

“text/javascript” )][assembly: WebResource(“myNamespace.Page.xaml.js”,

“text/javascript”)][assembly: WebResource(“myNamespace.Page.xaml”,

“text/xml”)]

4. Registrar los ficheros .js en el método PreRen-der del webpart:

this.Page.ClientScript.RegisterClientScriptResource(GetType(),

“myNamespace.Silverlight.js“);this.Page.ClientScript.

RegisterClientScriptResource(GetType(), “myNamespace.Page.xaml.js“);

5. En el Render del webpart generar el código Javas-cript necesario para la instanciación del plugin deSilverlight:

output.WriteLine(string.Format(“<div id=’{0}’

Style=”Width:500px;Height:200px”>“ + “<script type=’text/javascript’>“ +“createSilverlightHelloWorld(‘{1}’,’{0}’,

’500px’,’200px’);” +“</script>“ +“</div>“,this.ClientID , Page.ClientScript.GetWebResourceUrl(

this.GetType(), “myNameSpace.SilverlightHelloWorld.xaml“);

Silverlight 2.0 Webparts

Con la versión 2.0 de Silverlight estos pasos yano son necesarios y podemos sencillamente alojaruna aplicación Silverlight dentro de un webpart des-plegando ficheros de extensión .xap con nuestrasolución.

ASP.NET, el control servidor SilverlightEl control Silverlight es uno de los controles ser-

vidor para ASP.NET incluidos con el Silverlight 2.0Beta 2 SDK. Este control brinda una forma sencillade incluir contenido Silverlight como parte de una pági-na Web ASP.NET basado en el modelo de controlesde servidor de ASP.NET. El contenido Silverlight quese muestra dentro del control puede especificarse asig-nado a la propiedad Source la URL, bien del fichero

XAML o del resultado de la compilación de la aplica-ción Silverlight (un fichero .xap):

<asp:Silverlight ID=”Xaml1” runat=”server”

Source=”~/ClientBin/SilverlightHelloWorld.xap”inimumVersion=”2.0.30523” Width=”100%” Height=”100%”

/>

Para el caso de un webpart, podemos usar este con-trol dentro de la misma definición para alojar el esce-nario Silverlight (listado 1).

Este control requiere de acceso al control Script-Manager (por lo general, contenido en la misma pági-na); de otra forma ocurrirá una excepción (InvalidO-perationException) cuando se intente inicializar elcontrol.

Listado 1. HelloWorldSLWP

public class HelloWorldSLWP : WebPart{private ScriptManager _scriptHandler;private System.Web.UI.SilverlightControls.Silverlight

_silverlightControl;

private string _xapUrl = string.Empty;[WebBrowsable(true), Personalizable(true)]public string XapUrl{get { return _xapUrl; }set { _xapUrl = value; }

}

protected override void OnInit(EventArgs e){base.OnInit(e);XapUrl = “ClientBin\\SilverlightHelloWorld.xap”;

_scriptHandler = ScriptManager.GetCurrent(this.Page);if (_scriptHandler == null){_scriptHandler = new ScriptManager();_scriptHandler.ID = “ScriptManager1”;this.Controls.Add(_scriptHandler);

}

if (!string.IsNullOrEmpty(_xapUrl)){_silverlightControl = new System.Web.UI.SilverlightControls.Silverlight();_silverlightControl.ID = “Xaml1”;_silverlightControl.Source = _xapUrl;_silverlightControl.Version = “2.0”;this.Controls.Add(_silverlightControl);}}}

Para el ejemplo que se ilustra en el listado 1, seha creado un webpart en el cual podrá alojarse cual-quier .xap, pues la propiedad XapUrl se expone en laconfiguración del webpart al ser incluido en una pági-na SharePoint.

El fichero .xap que se obtiene resultado de la com-pilación de un proyecto Silverlight, no es más que un.zip que contiene todas las DLL necesarias para lacorrecta ejecución de la aplicación. Este .xap viaja has-ta el explorador y luego es manipulado por el motorde Silverlight. La figura 2 muestra el contenido de unfichero .xap.

Note que se incluye en el .xap la DLL correspon-diente al proyecto (SilverlightHelloWorld.dll) y sucorrespondiente manifesto (AppManifest.xaml). Laestructura del AppManifest.xaml será similar a la que semuestra en el listado 2.

Aunque aparentemente parece resultar tareafácil la de desarrollar un webpart Silverlight, si aéste se le quiere dotar de mayor potencia, ya seainteractuando con códigos externos a él, con códi-go definido dentro de la página que le contiene(código script) o poder configurar propiedades delwebpart y que estas influyan en el comportamien-to de la aplicación Silverlight. Puede ser de utili-dad desmitificar algunos aspectos sobre la interac-ción de una aplicación Silverlight 2.0 con su entor-no. Si bien para las versiones de Silverlight 1.0 –al

ser Javascript el code behind–, resulta más intuitivala forma de interacción, por ejemplo, con códigosdefinidos dentro de la página (generalmente script),para las versiones en las que el codebehind es un len-guaje .NET (C#, VB) habrá que apoyarse en otrosrecursos.

Acceder al HTML DOMEl contenido HTML de una página Web es

accesible programáticamente a través del DOM.Desde las aplicaciones Silverlight 2.0 es posibleinteractuar con el DOM de la página donde se alo-ja el plugin de Silverlight. Podemos escribir códi-go C# que haga uso de los objetos del DOM paramodificar contenido, generar nuevos contenidosHTML dinámicamente, así como reaccionar anteeventos HTML desde código C#. Para un divcomo el que se muestra a continuación:

<div>Autor: <span id=”authorName”></span>

</div>

Podemos acceder a él desde el code behind de nues-tra aplicación Silverlight de la sigueinte forma:

HtmlElement authorName = HtmlPage.Document.GetElementById(“authorName”);

Y es posible entonces modificar el contenidoHTML que se muestra:

authorName.SetAttribute(“innerText”,“Ya1000”);

Pero no estamos limitados a modificar solo códi-go HTML existente; podemos de igual forma generarnuevos elementos. Para un código HTML como elque sigue:

<ul id=”authorList”></ul>

Podemos desde código C# hacer:

dotN

etM

anía

<<

42

dnm.especial.silverlight<<

Figura 2 Fichero .xap.

Listado 2 AppManifes.xaml

<Deployment mlns=”http://schemas.microsoft.com/client/2007/deployment”

xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”

EntryPointAssembly=”SilverlightHelloWorld”

EntryPointType=”SilverlightHelloWorld.App”

RuntimeVersion=”2.0.30523.6”>

<Deployment.Parts>

<AssemblyPart x:Name=”SilverlightHelloWorld”

Source=”SilverlightHelloWorld.dll”/>

</Deployment.Parts>

</Deployment>

Los nombres de los elementosHTML y propiedades del DOMtodos son case-sensitive.[ ]

NOTA

HtmlElement authorList = HtmlPage.Document.GetElementById(“authorList”);

HtmlElement listItem = HtmlPage.Document.CreateElement(“li”);

listItem.SetAttribute(“innerText”,“Ya1000”);

authorList.AppendChild(listItem);

Invocando código script desde .NETAlgunas aplicaciones Web mezclan código script

del explorador y código Silverlight. Por ejemplo, pode-mos hacer uso de las librerías de AJAX para el desa-rrollo de un comportamiento determinado en el ladocliente de una aplicación Silverlight. Veremos enton-ces cómo invocar un código JavaScript desde C#. Dadoel siguiente código JavaScript:

<script type=”text/javascript”>function myScriptMethod(a, b){

var resultDiv = $get(“result”);resultDiv.innerText = “A: “ + a + “, B: “ + b;

}</script>ScriptObject myScriptMethod = (ScriptObject)HtmlPage.Window.GetProperty(“myScriptMethod”);

Con la siguiente línea de código podemos invo-car la función Javascript:

myScriptMethod.InvokeSelf(“Hello”, “World”);

myScriptType = function(name){this.param = name;

}

myScriptType.prototype ={Hello: function() { return “Hello “ + this.param +

“ from mysScriptType.”; }

}

ScriptObject obj = HtmlPage.Window.CreateInstance(“myScriptType”,“dotNetManía”);

object strVal = obj.Invoke(“Hello”);

Invocando código .NET desde códigoscript

Para un código XAML como el que sigue:

<TextBlock x:Name= “result“/>

Para lograr un código .NET disponible desdeel código script, habrá primeramente que de formaexplícita decorarlo con un atributo de tipo Scrip-tableMember.

[ScriptableMember]public void MySilverlightMethod(object o){result.Text = o.ToString();

}

Luego habrá que registrarlo de la siguien-te forma:

HtmlPage.RegisterScriptableObject(“MySilverlightObject”, this);

En este caso se ha pasado como pará-metro una referencia a this, haciendo acce-

dotN

etM

anía

<<

43

dnm.especial.silverlight<<

El tipo ScriptObject hace de wrapper para cualquierobjeto script. (Es la clase base de HtmlElement que asu vez es el wrapper usado para acceder al HTMLDOM desde una aplicación Silverlight). Expone dosmétodos uno Invoke y otro InvokeSelf. En el ejem-plo myScriptMethod es una función de Javascript, aho-ra para acceder a miembros (no funciones) usare-mos el InvokeSelf. De igual forma pueden obte-nerse instancias de prototipos (Prototype) definidosen código Javascript.

[ ]

Es posible invocar código C# desde código script y viceversa de forma bastante simple, permitiendo la interacción

entre un código cliente y uno servidor que define una lógica de negocio más compleja

NOTA

sible el código de la definición del tipo en concre-to. La cadena pasada como primer parámetro espe-cifica el nombre de la propiedad en la cual este obje-to se referencia (más adelante veremos donde estapropiedad es utilizada desde el código script).

Es posible entonces desde un código script defini-do quizás en una página ASPX hacer algo como:

<script type=”text/javascript”>function callSilverlight(){

var slPlugin = $get(“Xaml1”);slPlugin.content.MySilverlightObject.

MySilverlightMethod(“Hello from script”);}

</script>

Note que el objeto registrado con RegisterScrip-tableObject estará accesible como un miembro de lapropiedad content del plugin.

Luego podemos invocar esta función (que hace deproxy al método .NET) en cualquier lugar en el códi-go de la página Web:

<div onmouseover=”callSilverlight()”>Mouse over me!</div>

Otra forma de invocar código C# desde scriptsería, decorando un tipo cuyos métodos se deseeninvocar desde el código script con un atributo Scrip-tableType.

Definir luego el método que quiere exponerse acódigo script:

[ScriptableMember]public double Multiply(double x, double y){

return x * y;}

Añadiendo la segunda línea del código que sigue:

HtmlPage.RegisterScriptableObject(“MySilverlightObject”, this);

HtmlPage.RegisterCreateableType(“MySilverlightType”,typeof(MySilverlightType));

Y la función Javascript callSilverlight quedaría:

function callSilverlight(){var slPlugin = $get(“Xaml1”);var slType=slPlugin.content.services.createObject(

“MySilverlightType”);slPlugin.content.MySilverlightObject.MySilverlightMethod(slType.Multiply(21, 2));

}

Esto ilustra dos mecanismos de acceder a código.NET (code behind de una aplicación Silverlight 2.0 ocódigo que define la lógica de un webpart) desdescript.Usando los métodos RegisterScriptableObject yRegisterCreatableType.

Parámetros para inicialización del con-trol Silverlight

Para especificar parámetros a la inicialización delcontrol Silverlight desde una página HTML básica, unaopción suele ser asignar al parámetro initParams unstringbien formado usando código Javascript. Esta cade-na a asignar deberá cumplir con un patrón “key1=value1,key2=value2, key3= value3, keyn=valuen”.El valor de lapropiedad del control de servidor InitParametersde tipostring, es guardado en el ViewState, y puede asignarsetanto en código markup como code behind (listado 3 y 4códigos de una página ASPX donde se hospeda una apli-cación Silverlight); resulta importante que este stringesté en el formato esperado para asegurar el correctofuncionamiento al ser recolectados los parámetros des-de el escenario Silverlight.

Los pares key/value pueden ser recuperados en elcódigo de la aplicación Silverlight a través de la pro-piedad StartupEventArgs.InitParams (e.InitParams)en un manejador definido para el evento Applica-tion.Startup:

private void Application_Startup(object sender,StartupEventArgs e){this.RootVisual = new Page() {Settings=e.InitParams};

}

dotN

etM

anía

<<

44

dnm.especial.silverlight<<

Listado 3 InitParameters en HTML

<asp:Silverlight ID=”Xaml1” runat=”server”Source=”~/ClientBin/InitParameters.xap”MinimumVersion=”2.0.30523” Width=”100%”Height=”100%”InitParameters=”Autor=Yamil,Revista=dotNetManía”/>

Listado 4 InitParameters en C#

protected void Page_Load(object sender, EventArgs e){Dictionary<string,

string> settings = new Dictionary<string, string>();settings.Add(“Título”, “Desarrollo de WebParts Silverlight”);

Dictionary<string, int> settings2 = new Dictionary<string, int>();settings2.Add(“Número”, 51);Xaml1.InitParameters += “,” + settings.ToInitParams() +

“,” + settings2.ToInitParams();}

En la aplicación Silverlight en el Page.xaml.cs (lis-tado 5) podemos recuperar los valores al hacer Set-tingsGrid.ItemsSource = this.Settings y visualizar-los como se muestra en la figura 4.

Conclusiones Silverlight, como la hermana pequeña Web de la

monumental WPF aporta muchísimo al desarrollode interfaces de usuario cada vez más atractivas.

Incluir Silverlight en el desarrollo de webparts es, sinlugar a dudas, un nuevo e interesante recurso enmanos de los desarrolladores. Podríamos estar escri-biendo varias páginas sobre ambas ramas del desa-rrollo para la Web, pero el objetivo de este artículoes mostrar de forma sencilla algunos de los recursosque tenemos disponibles.

dotN

etM

anía

<<

45

dnm.especial.silverlight<<

Listado 5 Page.xaml.cs

public partial class Page : UserControl{public IDictionary<string, string> Settings {get; set;}

public Page(){InitializeComponent();Loaded += OnLoaded;

}

private void OnLoaded(object sender, RoutedEventArgs e){if (this.Settings != null){

SettingsGrid.ItemsSource = this.Settings;}

}} Listado 6 Page.xaml

<UserControl x:Class=”InitParameters.Page”xmlns=”http://schemas.microsoft.com/winfx/

2006/xaml/presentation”xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”xmlns:data=”clr-namespace:System.Windows.Controls;

assembly=System.Windows.Controls.Data”Width=”400” Height=”300”><Grid x:Name=”LayoutRoot” Background=”White”>

<data:DataGrid x:Name=”SettingsGrid” /></Grid></UserControl>

Figura 4. Mostrando los valores del InitParams

ReferenciasMiguel Katrib, Mario del Valle, Leonardo Paneque, Román Fresneda, Thaizel Fuentes, IskanderSierra, Yamil Hernández y Guillermo Som. Cuaderno Técnico nº8 de dotNetManía. Visual Studio2008. Desafía todos los retos. Netalia.

Gustavo Vélez. Cuaderno Técnico nº6 de dotNetManía. Programación con SharePoint 2007.Netalia.

Adam Nathan. Silverlight 1.0 Unleashed.

Jesse Liberty y Tim Heuer. Programming Silverlight 2.

[1]

[2]

[3]

[4]

Incluir Silverlight en el desarrollo de webparts es, sin lugar a dudas, un nuevo e interesante recurso en manos de los desarrolladores

Ludwig Leonard,Miguel Katrib

Desde la creación de la librería OpenGL en 1992por parte de Silicon Graphics Inc. y luego de DirectXa finales de 1995 por Microsoft, ha ido en aumentoel número de aplicaciones que hacen uso de los grá-ficos tridimensionales (en adelante gráficos 3D).

La principal dificultad que ha habido con ambasAPI es el alto grado de especialización que requie-ren para poder usarlos de manera efectiva. No solohacen faltan los conocimientos necesarios de gráfi-cos por ordenador, sino que hay que conocer bien lapropia API en particular. Para los programadoresque no conocen los detalles del procesamiento grá-fico, las inicializaciones se vuelven demasiado engo-rrosas y las funcionalidades poco intuitivas.

Usando estas API, sea DirectX u OpenGL, elprogramador puede lograr gráficos 3D en el áreacliente de un control de Windows o sobre toda lapantalla (modo Full Screen). Sin embargo, el áreadibujada no puede tener fondos transparentes, porlo que tales gráficos 3D no se podrían anteponer enla misma aplicación a controles de Windows que sepintaron usando GDI, ya que ocultarían parte de losmismos.

Una de las grandes bondades de Windows Pre-sentation Foundation (WPF) es que ofrece una nue-

va API para desarrollar interfaces de usuario, que traeincorporada un conjunto de controles y objetos parafacilitar la visualización tridimensional en nuestrasaplicaciones. Y mejor aún, estos gráficos pueden serdefinidos y animados en el lenguaje declarativoXAML asociado a WPF.

La “maquinaria” gráfica de WPF se basa inter-namente en Direct3D1 (la componente de DirectXencargada de visualizar gráficos tridimensionales)para la visualización de toda la interfaz gráfica. Deeste modo se aprovecha el acceso que brindaDirect3D a las aceleraciones gráficas que ofrecen lastarjetas de vídeo. Puesto que los controles 2D y losgráficos 3D se visualizan usando la misma API, pue-den coexistir y compartir los beneficios de WPF encuanto a enlace a datos, animaciones, recursos, plan-tillas y estilos.

Aunque de momento WPF no aprovecha todaslas funcionalidades que brinda Direct3D, sí incluyelos recursos para obtener gráficos a partir de mode-los, combinados con la utilización de brochas (tex-turas), tratamiento de luces, materiales y transpa-rencias. Este artículo se interna en estos conceptosgráficos y muestra cómo son logrados medianteWPF.

WPF, DirectX y los gráficos tridimensionales

plataforma.net

Miguel Katrib es doctor yprofesor jefe de programa-ción del departamento de

Ciencia de la Computa-ción de la Universidad de

La Habana. Miguel es líderdel grupo WEBOO, dedi-

cado a la orientación aobjetos y la programaciónen la Web. Es redactor de

dotNetManía.Ludwig Leonard es instruc-

tor de programación deldepartamento de Cienciade la Computación de la

Universidad de La Habana.Es desarrollador y diseña-

dor del grupo WEBOOespecializado en

graficación.

La espectacular aparición de WPF aún no explota todas las potenciali-dades gráficas para la visualización de escenas tridimensionales enDirectX. El presente artículo pretende hacer un primer recorrido porlos conceptos básicos de los gráficos por ordenador y mostrar cómose manifiestan éstos en DirectX y WPF en lo referente al modelado yal procesamiento gráfico.

1 En este artículo con Direct3D nos referiremos a las librerías Direct3D9 Extensiones Manejadas (DirectX9Managed Extensions). De igual forma, Direct3D y OpenGL tienen un proceder bastante similar a la hora deconcebir gráficos, por lo que en el resto de este artículo solo nos referiremos a Direct3D y WPF.

dotN

etM

anía

<<

47

dnm.plataforma.net<<

Algunos conceptos de gráficospor ordenador

El término Gráficos por ordenador(Computer Graphics) se refiere al procesa-miento mediante el cual un conjunto dedatos que describen una imagen sontransformados para poder mostrar la ima-gen en un dispositivo visual real median-te el uso de un ordenador. Los gráficospor ordenador tienen varios momentosrelevantes.

- Modelado: el modelado es el proce-so mediante el cual se genera la des-cripción de la imagen que se quiereobtener.

- Animación: se encarga de definircómo los objetos cambian sus pro-piedades con respecto al tiempo.

- Rendering: algoritmo usado para lavisualización de la imagen a partir dela descripción (modelo) de la misma.

- Interacción: posibilidad de que laaplicación pueda interactuar con laimagen o la descripción de la misma.

Modelado

Se considera un objeto geométricoa todo aquel que pueda ser descritomediante propiedades geométricas ytopológicas. Las propiedades geomé-tricas describen la figura de manera pre-cisa en un sistema de coordenadas,mientras que las propiedades topológi-cas definen la estructura fundamentaldel objeto, como son sus superficies yaristas.

La mayoría de las API gráficas para3D posee un conjunto de primitivasgráficas que permiten definir objetosgeométricos a partir de vértices y cone-xiones entre ellos para así formar lassuperficies. A este método de definirmodelos se le conoce como Repre-sentación por superficies (BoundaryRepresentation). La figura 1 muestra unconjunto de vértices y cómo estos pue-den ser interpretados de diversas for-mas para formar puntos, líneas y super-ficies, mediante la especificación de unaprimitiva gráfica en Direct3D.

Otra forma muy común de definirel objeto geométrico es a través de unamalla (Mesh). Una malla está dada por

la secuencia de vértices del modelo yuna secuencia de índices, donde cada 3índices queda especificado un triángu-lo. La figura 2 muestra la definición deun cubo a partir de una malla de 8 vér-tices y 12 triángulos.

Animación

Una vez definidos los modelos, éstosson ubicados en la escena. Mediante unaanimación se puede definir para cada ins-tante de tiempo una descripción diferen-te del modelo, por ejemplo, la manera enque se mueve por la escena.

Rendering

Una vez que se describe la escena apartir los modelos, se procede a obtenerla imagen que se mostraría en la panta-lla de acuerdo a cómo se vería desde unpunto de observación (figura 3).

Durante el rendering se tienen encuenta varios aspectos, como las trans-formaciones que se hacen a los mode-los, la eliminación de las superficies quequedan ocultas y la incidencia de lasluces sobre las superficies.

Figura 1. Primitivas gráficas en Direct3D

Figura 2. Definiendo un cubo apartir de una malla

Figura 3. Proyección de una escena en una pantalla.

dotN

etM

anía

<<

48

dnm.plataforma.net<<

Entre los algoritmos de renderingmás populares están el ray-tracing y elz-buffering. El primero determina cadapíxel de la imagen interceptando unrayo que parte del punto de observa-ción, pasa a través de la posición delpíxel en la pantalla e incide sobre unmodelo. De esta forma, el rayo puedeseleccionar la intersección con la super-ficie más cercana para no tener quevisualizar las superficies que quedanocultas al observador (figura 4).

El z-buffering, por el contrario,proyecta los triángulos que forman lassuperficies y luego hace recorridoshorizontales por cada fila de píxelespara dibujarlos en la pantalla. Este pro-ceso se denomina scan conversion ypermite obtener la información paracada píxel interior del triángulomediante la interpolación de los valo-

res de los píxeles del borde. La figura5 muestra el proceso sobre un trián-gulo, obteniendo primero los píxelesde los bordes del triángulo medianteinterpolación de los vértices y luegolos píxeles interiores interpolando lospíxeles de los bordes.

Este algoritmo trabaja sobre dosbuffers principalmente:

- Un buffer para los colores de cadapíxel (frame buffer).

- Un buffer para la profundidad decada píxel (depth buffer).Por cada píxel del triángulo se cal-

cula su profundidad de acuerdo al pun-to de observación. Si éste está delantede un píxel puesto con anterioridad endicha posición, de acuerdo a la infor-mación almacenada en el buffer de pro-fundidad, se actualiza el color en el buf-fer de los colores y la profundidad en elde profundidades. De esta forma, los

píxeles de las superficies que están opa-cadas por otras superficies más cerca-nas al observador quedarían “ocultos”una vez finalizado el algoritmo.

El algoritmo de z-buffering estáimplementado en las tarjetas gráficasmodernas en lo que se conoce comoprocesamiento gráfico (Graphic Pipe-line). Gracias a esto, muchas de las fun-cionalidades de las API gráficas puedanser aceleradas a nivel de hardware; espor ello que el funcionamiento deDirect3D está orientado a este algorit-mo de rendering.

Interacción

Una vez visualizada la escena en unaimagen, puede ser de interés interac-tuar con los elementos representadosen ella, para de esta forma poder crearinterfaces gráficas de usuario, seleccio-nar objetos, programar eventos. Des-pués de que el gráfico es visualizado, nohay manera de reconocer a partir de unpíxel de la imagen a qué modelo corres-pondía antes del proceso de rendering.

Figura 4. Algoritmo Ray-Tracing.

Figura 5. Scan conversion aplicado a un triángulo.

En WPF, toda la aplicación está bajo el mismo contexto gráfico. El elemento visual de WPF para agregarle gráficos 3D a las aplicaciones es Viewport3D. Los gráficos son creados y almacenados en estructuras propias de WPF y es el mismo

entorno el que visualiza la estructura cada vez que se necesite

dotN

etM

anía

<<

49

dnm.plataforma.net<<

Una forma muy común de lograrlo esusando una metodología ray-cast.

De manera similar al algoritmo deray-tracing, el ray-cast se basa en un rayoque parte del punto de observación y pasapor una posición determinada en la ima-gen (pantalla); en este caso se hace paralograr identificar qué modelo es el quecorresponde al punto X,Y donde se hahecho un clic, de modo que el primerpunto del rayo que se intercepte con unobjeto permite reconocer a dicho objetocomo el más cercano y por tanto el queha recibido el clic (figura 6).

Creando el dispositivo visual

En Direct3D, un dispositivo visual estáencapsulado en la clase Direct3D.Device. Esta clase permite la visualizaciónde gráficos sobre el contexto gráfico deun control Win32. Una vez creado elDevice, éste se utiliza para acceder a lasfuncionalidades de la API, inicializar esce-nas, dibujar primitivas, disponer luces,texturas y por último terminar la escenay presentarla.

Como se puede observar en el códi-go del listado 1, la creación de un “dis-positivo” (instancia del tipo Device)requiere de varios parámetros: el índiceun dispositivo físico (generalmente 0 indi-cando el monitor), el tipo de dispositivopara indicar si habrá aceleración de hard-ware o no, el control en el cual se visua-lizará el gráfico, un parámetro que defi-ne donde será procesado el flujo de vér-

tices y por último un parámetro indican-do el modo de presentación que usará eldispositivo, si será en un control o a pan-talla completa, entre otros elementos másespecíficos de la API. Un código comoel del listado 1 bien puede estar en el cons-tructor de un formulario o de un control.

En Direct3D, los gráficos se generancada vez que necesitan ser visualizados,lo que trae como consecuencia que el pro-gramador debe controlar los estados delas transformaciones, luces, texturas ydemás elementos que determinan la esce-na. Cada vez que una escena requiera serdibujada, se deberá usar una lógica comola que muestra el listado 2. El código dellistado 2 puede ser usado como cuerpo

del método OnPaint del control o for-mulario en el cual se está dibujando.

En WPF, toda la aplicación estábajo el mismo contexto gráfico. Elelemento visual de WPF para agre-garle gráficos 3D a las aplicaciones esViewport3D. Los gráficos son creados

y almacenados en estructuras propiasde WPF y es el mismo entorno el quevisualiza la estructura cada vez que senecesite. Cada elemento que se quie-ra agregar a la escena deberá ser aña-dido a la lista Children de un View-port3D, o ser colocado directamentecomo elemento interno de View-port3D, dado que Children es la pro-piedad de contención por defecto deViewport3D.

<Viewport3D><Viewport3D.Children>

<!— Elementos de la escena —></Viewport3D.Children></Viewport3D>

En WPF todo es más simple, por-que está encapsulado todo el procesode creación de un dispositivo y de pre-sentación de la escena, lo que implicaque el desarrollador no tiene que ocu-parse de esto.

ModeladoTanto Direct3D como WPF tienenestructuras para almacenar un punto3D o un vector 3D. Para cada vérticede la primitiva que se quiere visualizarno solo es necesaria su posición, sinotambién información relativa a la nor-mal de la superficie en ese punto, color,coordenadas para el mapeo de texturas,entre otras. Esta normal del punto esla que permitirá simular superficiescontinuas una vez se aplique la luz. Conel mapeo de texturas se le define unaenvoltura a la superficie usando unaimagen.

Figura 6. Algoritmo ray-cast empleado para la interacción.

PresentParameters pp = new PresentParameters();pp.Windowed = true;pp.SwapEffect = SwapEffect.Discard;device = new Device(0, DeviceType.Hardware, this.Handle,

CreateFlags.SoftwareVertexProcessing, pp);

Listado 1. Creación de un Device de Direct3D.

try{

device.BeginScene();//// Dibujar la escena// device.EndScene();device.Present();

}catch{}

Listado 2. Generación y presentación de unaescena en Direct3D

dotN

etM

anía

<<

50

dnm.plataforma.net<<

Modelos en Direct3D

En Direct3D, es necesario definirun buffer donde se almacenan los vér-tices de forma consecutiva y luego indi-car cuál primitiva quiere dibujarse usan-do estos vértices. Gracias a la políticaconocida como FVF (Flexible VertexFormat) que sigue Direct3D con losvértices, la estructura que almacena unvértice puede ser definida por el pro-pio programador de manera personali-zada. Basta con asignarle al Device unvalor del tipo enumerado VertexFormats,que indicará cuáles elementos están pre-sentes en cada vértice. En el segmentode código del listado 3 se crea unaestructura para almacenar posición ycoordenadas de textura. La estructuratiene un campo estático FVF del tipo Ver-texFormats para indicar la informaciónpresente en cada vértice.

Luego, antes de visualizar una pri-mitiva es necesario indicarle al Deviceel formato del vértice a través de la pro-piedad VertexFormat:

device.VertexFormat =

PositionTexturedVertex.FVF;

No obstante, existe un conjunto deestructuras predefinidas que permitenalmacenar un vértice. Estas estructuraspredefinidas están dentro de la claseestática CustomVertex. La estructura delejemplo anterior existe bajo el nombrede CustomVertex.PositionTextured.

Para crear un buffer de vértices sedispone de la clase VertexBuffer. El

código del listado 4 muestra la creaciónde un buffer de vértices y la forma dealmacenar los vértices. Luego, visuali-za la primitiva gráfica PrimitiveType.TriangleFan.

Este código se visualiza tal comomuestra la figura 7. En el ejemplo secrea un buffer con 4 vértices que for-man un cuadrado, y como no se le defi-nió vértices con colores, éste se visua-liza en blanco.

La librería gráfica Direct3D disponede la clase Mesh, que ofrece un amplio con-junto de funcionalidades para el modela-

do. Esta clase posee información sobreun buffer de vértices y un buffer de índi-ces para indicar las conexiones entre ellosque forman triángulos. Lo más impor-tante de esta clase es que no solo sirve

para modelar sino que tiene funcionali-dades (algunas de ellas orientadas a la ace-leración por hardware) que permiten opti-mizar la visualización del modelo, calcu-lar automáticamente las normales, asícomo algunos métodos estáticos paradefinir mallas básicas de figuras conoci-das, como esferas, cilindros, cubos. Otrafuncionalidad que ofrece Mesh es saber sialguno de sus triángulos es interceptadopor un rayo para propiciar así una posi-ble interacción con los gráficos.

ProgressiveMesh es otra clase que eneste caso permite definir mallas que pue-dan eficientemente “reducir” la defini-ción de sus superficies; quiere decir, obte-ner una malla parecida a la original perocon menos caras y vértices. Tanto Meshcomo ProgressiveMeshheredan de la cla-se base BaseMesh.

Modelos en WPF

WPF hace distinción entre un pun-to del espacio y un vector del espacio.Point3D indica posicionamiento y Vec-tor3D indica direccionamiento.

public struct PositionTexturedVertex{// Posiciónpublic Vector3 Position; // Coordenadas de texturapublic float Tu0, Tv0;public static readonly VertexFormats

FVF = VertexFormats.Position | VertexFormats.Texture0;

}

Listado 3. Definiendo un vérticepersonalizado para almacenar coordenadasde textura y posición

using (VertexBuffer vb = new VertexBuffer(typeof(CustomVertex.TransformedTextured), 4,device, Usage.None, CustomVertex.TransformedTextured.Format, Pool.Default))

{// Asegurar la memoria para almacenar los vérticesGraphicsStream gs = vb.Lock(0, 0, LockFlags.None);// Escribir cada vértice en el buffergs.Write(new CustomVertex.TransformedTextured(20, 20, 0.1f, 1, 0, 0));gs.Write(new CustomVertex.TransformedTextured(120, 20, 0.1f, 1, 1, 0));gs.Write(new CustomVertex.TransformedTextured(120, 120, 0.1f, 1, 1, 1));gs.Write(new CustomVertex.TransformedTextured(20, 120, 0.1f, 1, 0, 1));// Desbloquear el buffer asegurado.vb.Unlock();

// Se asigna el buffer al devicedevice.SetStreamSource(0, vb, 0);

// Decidir el formato de vértice que se usará en el devicedevice.VertexFormat = CustomVertex.TransformedTextured.Format;

// Dibujar una primitiva TriangleFan. Con 4 vértices se forman 2 triángulos.device.DrawPrimitives(PrimitiveType.TriangleFan, 0, 2);

}

Listado 4. Creación de un buffer de vértices

Figura 7. Visualización de unaprimitiva en Direct3D.

dotN

etM

anía

<<

51

dnm.plataforma.net<<

2 Es de desear que en un futuro WPF incluya nuevos herederos de Geometry3D, como por ejemplo una geometría para esferas y otros objetosbásicos no basada en aproximaciones con superficies triangulares, sino con curvas.

WPF tiene una clase base para losmodelos tridimensionales (Model3D).Esta clase agrupa los elementos quemodelan una escena: luces, modelosgeométricos y modelos formados porgrupos de modelos.

De ellos, GeometryModel3D es la cla-se que permite representar objetosgeométricos a partir de un Geometry3D.Geometry3D posee un constructor inter-no y un único heredero, MeshGeometry3D,que no permite herencia. MedianteMeshGeometry3D es que se definen mallasa partir de vértices e índices2.

En WPF no existe como tal el con-cepto de “vértice”, sino que la infor-mación de posición, normal y coorde-nadas de texturas están separadas envarias colecciones, que son propieda-des de la clase MeshGeometry3D.

<MeshGeometry3DPositions=”0,0,0 1,0,0 0,1,0 1,1,0”Normals=”0,0,1 0,0,1 0,0,1 0,0,1”TextureCoordinates=”0,1 1,1 0,0 1,0”TriangleIndices=”0,1,2 1,3,2”

/>

WPF trata las posiciones como pun-tos tridimensionales (de tipo Point3D), lasnormales como vectores (Vector3D) y lascoordenadas de textura como puntos bidi-mensionales (de tipo Point). Aunque,dado que si la cantidad de posiciones no

se corresponde con la cantidad de nor-males o de coordenadas de textura se pro-ducirá una visualización errónea, cabepreguntarse si se necesita una clase Ver-tex en WPF. Esto realmente solo apor-taría más código a las aplicaciones, dadoque WPF no permite internarse en la APIDirect3D para hacer un uso más especí-fico a nivel de vértices.

Otro tipo derivado de Model3D esModel3DGroup. Esta clase permite agru-par varios modelos para conformarotros modelos más complejos (porejemplo, el modelo de un automóvilpudiera estar formado por carrocería,llantas y parabrisas).

Mientras que en Direct3D la interac-ción con los gráficos de la escena necesi-taba ser manejada con ayuda del métodoMesh.Intersect, siendo el programadorquien debía controlar los eventos de ratóny convertirlos en eventos sobre los gráfi-cos de la escena, en WPF no solo se uti-lizan los modelos como simples gráficos,sino que se brindan mecanismos para inte-ractuar con los modelos (hit-testing) y dar-les funcionalidades, al mismo tiempo quepermite la integración con cualquier ele-mento concebido para el entorno 2D. Espor ello que no se le agrega directamen-te un modelo 3D a un Viewport3D, sinoque en su lugar se le agregan elementosvisuales 3D, tratados a través de la clasebase Visual3D, de la cual heredan UIEle-ment3D, ModelVisual3D y Viewport2DVi-sual3D. La clase Visual3D provee funcio-nalidades para la interacción y transfor-maciones, además de las funcionalidadesde visualización.

UIElement3D es una clase abstractaque permite definir objetos tridimen-sionales personalizados y agregarleeventos de ratón y teclado. El modelose especifica mediante la propiedadVisual3DModel. La implementaciónModelUIElement3D de esta clase abstrac-ta permite de forma fácil definir unmodelo 3D que recibe eventos de ratóny teclado.

A su vez, la clase ModelVisual3D es laque permite que los modelos puedanconsiderarse como simples gráficos deuna escena. El modelo que se va consi-derar como gráfico para la escena se le

da como valor a la propiedad Contentdel ModelVisual3D, como muestra elcódigo XAML del istado 5.

Por último, la clase Viewport2DVi-sual3D se encarga de brindar la inte-gración con elementos 2D. Usando estaclase, se puede crear un objeto 3D quetenga como envoltura un elemento delentorno 2D (por ejemplo un Button) yluego, los eventos de ratón y tecladosobre el objeto 3D se transforman eneventos sobre el elemento 2D. La figu-ra 8 muestra una tetera envuelta por unbotón, en este caso al hacer clic sobrela tetera se traduce a un clic sobre elbotón.

Procesamiento gráfico (Grap-hic Pipeline)Una vez determinado el conjunto devértices y la manera en que se formanlos triángulos de la superficie, esta infor-mación se pasa al procesamiento gráfi-co. Este procesamiento está dividido entres etapas (figura 9).

<ModelVisual3D><ModelVisual3D.Content><GeometryModel3D><GeometryModel3D.Geometry><MeshGeometry3D …/

</GeometryModel3D.Geometry></GeometryModel3D>

</ModelVisual3D.Content></ModelVisual3D>

Listado 5. Declaración de un modelo en WPFa partir de un objeto geométrico

Figura 8. Ejemplo de aplicación que muestra eluso de la clase Viewport2DVisual3D.

En WPF no solo se utilizan losmodelos como simples gráficos,sino que se brindan mecanis-mos para interactuar con losmodelos (hit-testing) y darles

funcionalidades, al mismo tiem-po que permite la integración

con cualquier elemento conce-bido para el entorno 2D

dotN

etM

anía

<<

52

dnm.plataforma.net<<

La primera etapa es en la que se pro-cesa la secuencia de los vértices y setransforman éstos hasta determinar paracada uno la posición en que deberá serubicado en la pantalla, su intensidad deluz y su color. La segunda etapa deter-mina las áreas que quedan fuera delcampo visual y procesa cada triángulopara obtener los píxeles de la imagen.En una tercera etapa se procesa cadapíxel para determinar si se visualiza ono, se toma la muestra del color corres-pondiente al píxel dada la textura quese está usando y se determina entoncesel color final que se le indicará a éste enel buffer de colores (imagen final).

El comportamiento del procesa-miento gráfico es posible configurarlomediante lo que se conoce como losestados de renderización (render sta-tes). El procesamiento gráfico se com-porta como una gran maquinaria quese ajusta para producir determinadoresultado; en este caso, determinadaimagen. Existen estados que determi-nan las transformaciones que se reali-zan sobre el modelo, el color que refle-jan las superficies, las luces presentesen la escena, entre otros muchos.

Procesamiento gráfico en Direct3D

Direct3D es una API que práctica-mente brinda total acceso al procesa-miento gráfico. Muchos estados que tie-nen cierta relación entre ellos quedanagrupados bajo clases. Ejemplo de estoson los estados de transformación (mun-do, vista, proyección) que se accedenmediante la propiedad Device.Transform.De igual forma, las luces se acceden através de la propiedad Device.Lights y elmaterial mediante el tipo estructura Mate-rial y la propiedad Device.Material.

Existen otros estados que configu-ran otros elementos del procesamien-to gráfico y que se acceden a través dela propiedad Device.RenderState. El lis-tado 6 presenta un segmento de códi-go que genera una escena en la que semuestra una tetera de color rojo (mate-rial) sobre la que incide una luz en cier-ta dirección.

Procesamiento gráfico en WPF

Como se dijo en un principio, lamaquinaria gráfica de WPF utiliza pordetrás DirectX para la visualización. Noobstante, tiene un conjunto de clasesque permiten “construir” una escena enlugar de acceder libremente a los esta-dos del render. Muchos de los estadosque son configurables en Direct3Destán prefijados en WPF. Por ejemplo,en WPF se ocultan las superficies conprofundidades mayores que las ya visua-

lizadas (si se pinta un mismo modelodos veces, el segundo se dibuja encimadel primero) lo que en Direct3D se con-figura explícitamente mediante la asig-nación:

device.RenderState.ZBufferFunction =

Compare.LessEqual;

En la clase Viewport3D se define laproyección y la posición del observa-dor mediante la propiedad Camera. Paracada modelo geométrico (GeometryMo-del3D), se le puede definir su propiatransformación dentro de la escena(mediante la propiedad Transform) y supropio material (mediante las propie-dades Material y BackMaterial). Lasluces son tratadas como modelos, locual posibilita que puedan ser fácil-

mente ubicadas en la escena y trans-formadas (rotadas, trasladadas).

WPF además agrupa los conceptosde textura y material bajo el conceptode brocha (Brush). La misma claseencargada de definir cómo se rellenanlos interiores de las figuras bidimen-sionales se puede utilizar en una esce-na para definir las envolturas de losobjetos 3D. Podemos con ello aprove-char toda la variedad de brochas exis-tentes para los gráficos bidimensiona-

Figura 9. Etapas del Procesamiento Gráfico.

// Borrando el buffer de colores y el de profundidaddevice.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Blue, 1, 0);// Activar la luz 0device.Lights[0].Diffuse = Color.White;device.Lights[0].Type = LightType.Directional;device.Lights[0].Direction = new Vector3(-1, -1, -1);device.Lights[0].Enabled = true;// Definir el tipo de proyección que se usadevice.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4,

this.Width / (float)this.Height, 1, 1000);// Definir la posición del observadordevice.Transform.View = Matrix.LookAtLH(new Vector3(2, 2, 4), new Vector3(0, 0, 0),

new Vector3(0, 1, 0));// Material rojo para la teteraMaterial m = new Material();m.Diffuse = Color.Red;m.Ambient = Color.DarkRed;// Se asigna el material al Devicedevice.Material = m;// Se crea la tetera en el dispositivo y se manda a visualizarMesh.Teapot(device).DrawSubset(0);

Listado 6. Visualizando una tetera en Direct3D

dotN

etM

anía

<<

53

dnm.plataforma.net<<

les con sus funcionalidades para trans-formaciones, efectos y transparencias.

El equivalente en WPF al códigodel listado 6 quedaría como se muestraen el listado 7.

Conclusiones

DirectX representa una poderosalibrería para la creación de video jue-gos, aplicaciones de diseño, y multi-medios. Es una librería que va en la van-guardia no solo en cuanto a software,sino también en compatibilidad y actua-

lidad con las nuevas tecnologías dehardware gráfico. Gracias a Direct3D,los programadores pueden hacer uso delas funcionalidades más novedosas queson incorporadas en las tarjetas gráfi-

cas modernas y de esta forma logrargráficos muy realistas y de comporta-miento eficiente. Son innumerables lastécnicas gráficas que se pueden crear enDirect3D mediante la programación deshaders3 y el uso de los efectos (Effect).

No obstante, muchos de los concep-tos que son necesarios dominar para el

trabajo con esta librería son desconoci-dos para la mayoría de los programado-res no tan especializados y que solo inten-tan crear interfaces de usuario con ciertavisualización tridimensional.

Si bien es cierto que la versión actualde WPF aún no alcanza todas las posi-bilidades visuales de Direct3D, su APIpara la creación de gráficos 3D permi-te crear un gran número de éstos grá-ficos y efectos muy realistas, controlespersonalizados, integración entre ele-mentos 2D y 3D, interacción con losgráficos (hit-testing), eventos, anima-ciones y enlace a datos.

Lo que es más relevante es que WPFresulta más intuitivo y fácil de usar. Lanaturaleza declarativa de su lenguaje aso-ciado XAML facilita su utilización entiempo de diseño de la aplicación. Es deesperar que futuras versiones de WPFincorporen nuevas sorpresas 3D. Para nohacerlo muy extenso, en este artículo seha evitado entrar en detalles a la hora deexponer los mecanismos de modelado yprocesamiento gráfico. En un futuro tra-bajo se podrá profundizar en los algorit-mos de modelado que están presentes enDirect3D y cómo pueden ser aprove-chados desde WPF. También quedanpendientes más detalles sobre el proce-samiento gráfico, cómo son implemen-tadas técnicas gráficas como sombras,reflejos, texturas rugosas (bump mapping)o ambientales (environment mapping), ycómo pueden ser logrados estos efectosen WPF.

<Viewport3D><Viewport3D.Camera><PerspectiveCamera Position=”2,2,4” LookDirection=”-1,-1,-2” FieldOfView=”45”/>

</Viewport3D.Camera><Viewport3D.Children><ModelVisual3D><ModelVisual3D.Content><DirectionalLight Direction=”-1,-1,-1” Color=”White”/>

</ModelVisual3D.Content></ModelVisual3D><ModelVisual3D><ModelVisual3D.Content><Model3DGroup><GeometryModel3D

Geometry=”{Binding Geometry, Source={StaticResource TeapotGeometry}}”><GeometryModel3D.Material><DiffuseMaterial Brush=”Red”/>

</GeometryModel3D.Material></GeometryModel3D>

</Model3DGroup></ModelVisual3D.Content>

</ModelVisual3D></Viewport3D.Children>

</Viewport3D>

Listado 7. Visualizando una tetera en WPF.

3 Códigos que pueden ser ejecutados por el procesador gráfico (GPU) y que permiten definir el procesamiento gráfico y hacer operaciones a nivelde vértices y píxeles.

Bibliografía[1] 3-D Graphics Overview, http://msdn2.microsoft.com/en-us/library/ms747437.aspx

[2] 3-D Graphics, http://msdn2.microsoft.com/en-us/library/ms746698.aspx

[3] 3-D Transformations Overview, http://msdn2.microsoft.com/en-us/library/ms753347.aspx

[4] Nathan, Adam. Windows Presentation Foundation Unleashed, Sams Publishing, 2007.

[5] DirectX 9.0 SDK Documentation, 2003.

[6] Gray, K. Microsoft DirectX9 Programmable Graphics Pipeline, Microsoft Press, 2003.

[7] Open GL Super Bible. Waite Group Press, 1996.

[8] Miller, Tom. Managed DirectX® 9 Kick Start: Graphics and Game Programming, Sams Publishing 2003

Cómo acceder a los ficheros con VisualBasic 6.0

No voy a entrar en detalles de cómo se accede al con-tenido de un fichero con Visual Basic 6.0, ya que estaisla es para la versión de Visual Basic que trabaja con.NET Framework, pero sí me gustaría explicar algunasde las formas de acceso con idea de que podamos com-pararlas con las que nos ofrece la versión de .NET, y asílos lectores que han tenido experiencia con las versio-nes anteriores sepan cómo hacer lo mismo (o casi).

En Visual Basic 6.0 tenemos cinco formas de acce-der al contenido de un fichero, aunque de forma gené-

rica son tres: secuencial, binario y aleatorio (random).Las otras dos es porque el acceso secuencial lo pode-mos hacer para lectura o para escritura, y en este últi-mo caso lo podemos hacer de dos formas diferentessegún agreguemos contenido a un fichero o lo sobres-cribamos.

En los accesos binarios y aleatorios se puede escri-bir o leer indistintamente usando la misma forma deabrir los ficheros.

La forma de abrir un fichero en Visual Basic 6.0es por medio de la instrucción Open a la que le tene-mos que indicar el nombre del fichero, el modo deapertura y el número del fichero (o canal) que usare-mos para indicar que accedemos a un fichero con-creto. La sintaxis (simplificada) sería parecida a ésta:

Open <nombre> For <modoApertura> As <numeroFichero>

Debido a que Visual Basic 6.0 no tiene un enfo-que orientado a objetos, necesitamos un número decanal para usarlo en las operaciones posteriores delectura y escritura que correspondan.

Acceso secuencial

Para el acceso secuencial debemos decidir si que-remos escribir o leer del fichero, y en el caso de escri-bir, tenemos que decidir si queremos añadir algo alcontenido existente o no. Todos estos modos de acce-so los indicaremos en la instrucción Open de VisualBasic 6.0, siendo los modos: Output (para escribir),Append (para agregar texto) e Input (para leer). Estos

Isla VB

Guillermo “Guille”Som

Es Microsoft MVP deVisual Basic desde 1997.Es redactor de ddotNet-Manía, mentor de Solid

Quality Mentors, oradorde Ineta Latam, y autor

de los libros “ManualImprescindible de Visual

Basic .NET” y “VisualBasic 2005” y “Noveda-

des de Visual Basic 9.0” ypróximamente “Apren-da C# 3.0 desde 0.0 –

Parte 3: Lo nuevo” .http://www.elguille.info.

Visual Basic permite varias formas distintas de acceder al contenido de losficheros, unas se basan en las clases de .NET Framework, otras son especí-ficas de Visual Basic. Entre estas últimas encontramos funcionalidad compa-tible (o casi) con Visual Basic 6.0. En este artículo veremos las diferentes for-mas de acceder al contenido de los ficheros para que el lector pueda elegirla que mejor se adapte a sus necesidades.

Guillermo «Guille» Som

Acceso a ficheros con Visual BasicUsar clases de .NET o no usarlas…

Guillermo Som ingresará los derechos de autor deeste artículo en la cuenta de Ayuda a Juanma a vivir.Desde aquí, invita a los lectores de esta isla solida-ria para que hagan sus aportaciones o participen enlas subastas que se realizan desde la Web de Juan-ma para recaudar fondos con el fin de ayudar en lainvestigación de una cura para la enfermedad deAlexander. http://www.ayudajuanma.es.

Firmas para solicitar ayuda del gobierno españolpara la investigación de una cura para la enfermedadde Alexander: http://www.elguille.info/solidario/ayu-daJuanma/Firmas_Juanma.aspx.

Isla solidaria

dotN

etM

anía

<<

55

dnm.isla.vb<<

modos de apertura los indicaremos des-pués de la instrucción For usada en laorden de apertura del fichero (no con-fundamos esta instrucción con la quesirve para realizar los bucles).

A la hora de escribir en un ficherode forma secuencial tenemos dos for-mas de hacerlo: una es usando la ins-trucción Write y la otra es usando la ins-trucción Print. Cada una de estas ins-trucciones usan su propio criterio decómo se deben guardar las cosas.

En el caso de Write, las cadenas seguardan dentro de comillas dobles, losvalores numéricos con decimales usansiempre el punto como separador deci-mal, las fechas se guardan usando el for-mato #yyyy-MM-dd HH:mm:ss# y los valo-res lógicos se guardan como #TRUE# o#FALSE#.

Por otro lado, Print lo guarda todocomo una cadena (los valores que no sonString los convierte a cadena) y usandola configuración regional, y a pesar de queen la documentación de esta instrucciónse indica que los valores de tipo Booleanno se traducen, pues… hay que decir queno es cierto, y siempre se traducen. Portanto, un valor True se guardará como unacadena, que en el caso de la configura-ción regional para España, se guardacomo “Verdadero”.

Además de todo esto, si en esas ins-trucciones se usan comas (o puntos ycomas) para separar los valores a guardar,Write los maneja de una forma diferenteque Print. Y esto influye (y mucho) a lahora de leer esos valores con Input.

Como dije al principio, no quieroalargarme en estos temas, pero en elcódigo que acompaña al artículo hay unproyecto de Visual Basic 6.0 que mues-tra estas diferencias.

Debido a que todo esto es un poco“liante”, yo casi siempre evitaba usarWrite y cuando tenía que guardar variosvalores, cada uno de ellos los guardabaen su propia línea, de esta forma paraleerlos, siempre usaba Line Input quees la instrucción que lee el contenidode una línea completa. Es decir, tomatodo el contenido de la línea, indepen-dientemente de que se hayan usadoseparadores individuales para guardarla información.

Acceso binario

El acceso binario nos permite leer (ograbar) la información de un fichero usan-do cantidades fijas de bytes. AunqueVisual Basic 6.0 es un poco flexible a lahora de leer o guardar esa información.Por ejemplo, si guardamos un valor decualquier tipo que no sea cadena, lo alma-cenará usando la representación internade esos valores, es decir, no lo guardacomo una cadena de caracteres (al igualque ocurre en el formato secuencial), portanto, si usamos tipos de datos diferentesa una cadena a la hora de guardar un valoren un fichero binario (usando la instruc-ción Put), deberíamos usar esos mismostipos a la hora de leerlos (usando la ins-trucción Get). Y para complicar la cosa, sileemos usando una cadena, la cantidad decaracteres que se leerán serán los que ten-ga esa cadena. En realidad, esto es lo queyo habitualmente hacía cuando queríaleer de un fichero abierto en modo bina-rio. El problema es que si se habían guar-dado los datos usando otros tipos de datos,debía hacer mi conversión a esos tipos.Pero, en realidad, el acceso binario no espara leer información “normal”, para esoestán los accesos secuenciales o los alea-torios.

Acceso aleatorio

El acceso aleatorio en realidad noes tan aleatorio, ya que la manera deusar esta forma de acceso a los ficheroses usando longitudes fijas. Puede queel nombre de esta forma de acceder alos ficheros venga a que podemos indi-car en cualquier momento a qué partedel fichero podemos acceder sin tenerque hacer nada especial.

Debido a que el acceso es de longi-tud fija, las instrucciones Get (para leer)o Put (para guardar) usan un valor queindican qué registro es el que estamosaccediendo. Este tipo de acceso a fiche-ros se usa habitualmente con tipos defi-nidos por el usuario (Type) y si algunosde los campos de ese tipo es una cade-na, esa cadena debe ser de longitud fija(algo que no se permite en .NET).

En mis tiempos de programación conVisual Basic 6.0 (incluso con el QuickBasic de MS-DOS) éste era el tipo deacceso que usaba con más asiduidad, almenos cuando los datos que almacenabaeran con datos fijos, ya que en otros casos,usaba el acceso secuencial.

Este tipo de acceso lo usaba cuandoiba a guardar los datos de una estructura(los Type de VB6 equivalen más o menosa una estructura de .NET) con sus valo-res numéricos, de fechas o cadenas (esosí, cadenas de longitud fija).

En el código de ejemplo que se inclu-ye en el ZIP que acompaña a este artícu-lo hay ejemplos de estos tipos de accesoa ficheros que acabo de comentar.

Cómo acceder a los ficheroscon Visual Basic .NET

Ahora le toca el turno a la formade acceder al contenido de los fiche-ros desde Visual Basic para .NET. Enesta ocasión sí veremos ejemplos decómo acceder a ese contenido. Y debi-do a que Visual Basic nos proporcio-na diferentes formas de hacer estatarea, le daremos un repaso a las másimportantes o al menos las que yoconsidero que son las que debemosconocer para usarlas cuando nos sur-ja la ocasión.

Las clases de .NET Framework serán las que siempre usaremos para el acceso al contenido de los ficheros

Acceso a ficheros compatible(o casi) con Visual Basic 6.0La mejor forma de ver cómo se accede alos ficheros con Visual Basic (usando lacompatibilidad con versiones anteriores)es convirtiendo un proyecto de VisualBasic 6.0 a Visual Basic .NET (en nues-tro caso a Visual Basic 2008).

Al convertir las diferentes formas deacceso a ficheros, se usan funciones queestán definidas en el espacio de nombresMicrosoft.VisualBasic. Esas funcionesexisten para dar soporte a las equivalen-tes de las versiones anteriores, pero no serecomienda su uso, ya que hay otras for-mas más eficientes de hacerlo. Y de esasotras formas nos ocuparemos en unmomento. Primero empezaremos por lasque usan las clases propias de .NET Fra-mework y después veremos otras formasde acceso al contenido de los ficherosusando clases definidas especialmentepara los desarrolladores de Visual Basic,entre ellas las que nos permiten accedera ficheros con estructuras específicas ocuyo contenido usa separadores perso-nalizados.

Acceso al contenido de losficheros usando clases de.NETLas clases de .NET Framework seránlas que siempre usaremos para el acce-so al contenido de los ficheros. Sí, ya séque he dicho que también podemosusar clases propias de Visual Basic, peroen el fondo usan las clases definidas enel propio .NET, aunque es posible quela forma de usarlas sean más amigablesque las definidas en el corazón de .NET.

Acceso secuencial

Para el acceso secuencial a ficheros detexto la forma más fácil de hacerlo es pormedio de las clases StreamReader (paraleer) y StreamWriter para escribir.

Estas clases ofrecen varias formas deindicar el fichero al que queremos acce-der, aunque la más simple (y segura-mente la más usada) es indicando elnombre del fichero al que queremosacceder. También nos permite indicar lacodificación usada para acceder a esefichero en concreto. Si no indicamos unacodificación, se usará Encoding.UTF-8,pero si queremos tener compatibilidadcon otras aplicaciones de Windows (porejemplo, con los ficheros creados conVisual Basic 6.0) deberíamos usar la codi-ficación Encoding.Default. La codifica-ción que usemos es importante quesea la adecuada, ya que si usamos unadiferente, es posible que algunoscaracteres como la eñe o las vocalesacentuadas no se lean o guarden comodebieran.

Cuando usamos la clase StreamRea-der, ésta implementa una serie de méto-dos que nos permite leer el contenido

del fichero. Podemos leer el con-tenido completo por medio delmétodo ReadToEnd o bien usar elmétodo ReadLine para leer unalínea completa. Si solo queremosleer un carácter, usaremos elmétodo Read. También podemosleer bloques de caracteres pormedio del método ReadBlock, perolas tres anteriores son las formasmás habituales de leer el conteni-do del fichero.

Cuando usamos ReadToEnd, leemostodo el contenido del fichero, por tan-to, si no tenemos que hacer ningunacomprobación especial, será el métodopreferido para la mayoría de los casosque se nos presenten.

Por otro lado, si usamos los métodosReadLine o Read, tendremos que com-probar que aún hay algo que leer de esefichero antes de usar nuevamente esasfunciones. Esto lo podemos hacer de dosformas (pero siempre dentro de un bucledel tipo While o Do que siga repitiéndosemientras haya algo que leer).

En la versión 2.0 de .NET se agrególa propiedad EndOfStream a la clase Stre-amReader. Esta propiedad devuelve unvalor verdadero si se ha llegado al finaldel fichero, por tanto lo podemos usartal como vemos en el listado 1.

La otra forma es usando el métodoPeek, el cual devuelve -1 si no hay nadamás que leer o bien el valor del carácterleído. Como veremos en un momento,este método tiene un comportamiento“no deseado” en algunas situaciones,por tanto, será preferible usar la pro-piedad EndOfStream, salvo que Peek lousemos directamente después de abrirel fichero.

En el listado 2 vemos cómo usar elmétodo Peek para decidir si seguimosleyendo del fichero.

El código del listado 2 funcionará(o a mí me ha funcionado) solamentedespués de abrir el fichero, pero si yahe leído el contenido completo y deci-do posicionar la secuencia al principiode la misma con el método Seek, elmétodo Peek siempre devolverá -1,incluso si hay datos que se puedan leer.En el listado 3 tenemos un ejemplo quefallará al usar Peek.

Para que el código del listado 3funcione, debemos leer primero algodespués de posicionar la secuencia enel principio o bien usar un bucleDo/Loop While tal como vemos en elcódigo del listado 4. Ese código siem-

dotN

etM

anía

<<

56

dnm.isla.vb<<

En el ZIP con el código de ejemplose incluye un proyecto para VisualBasic 2008 que se ha convertido apartir del equivalente de Visual Basic6.0, al que he hecho pequeñas modi-ficaciones para que funcione demanera similar.

[ ]NOTA

While sr.EndOfStream = Falses = sr.ReadLine()Console.WriteLine(s)

End While

Listado 1. Leyendo secuencialmente ycomprobando con EndOfStream.

While sr.Peek > -1s = sr.ReadLine()Console.WriteLine(s)

End While

Listado 2. Leyendo secuencialmente ycomprobando con Peek.

pre funcionará, ya que el método ReadLine no pro-duce ninguna excepción si se intenta leer despuésdel final del fichero.

Para grabar en un fichero usaremos la clase Stre-amWriter, la forma de instanciar esta clase nos permi-tirá agregar nuevo contenido a un fichero existente obien escribir como si no existiera. En el caso de queindiquemos que queremos agregar contenido y elfichero no existe, simplemente se ignora la acción deagregar, entre otras cosas porque si no existe ¿cómovamos a agregar nada?

Esta clase nos ofrece dos formas de añadir textoal fichero, por un lado tenemos el método WriteLineque escribe el contenido que indiquemos seguido deun final de línea. Por otro lado tenemos el métodoWrite, que escribe lo que indiquemos como argu-mento, pero no añade ningún cambio de línea.

Estos dos métodos están sobrecargados para reci-bir argumentos de diferentes tipos de datos. En el lis-tado 5 vemos un ejemplo de cómo escribir en un fiche-ro de texto.

Acceso binario

El acceso binario a un fichero lo podemos hacer usan-do varias de las clases de acceso a secuencias (en reali-dad sería posible con cualquiera de las clases que se deri-ven de Stream), pero la más usada será FileStream.

El acceso lo haremos siempre usando bloques debytes que estarán en un array de tipo Byte, aunque siqueremos leer o escribir un solo Byte también existenmétodos para hacerlo, pero lo habitual será leer oescribir una serie de bytes.

En el constructor de esa clase podemos indicarcómo queremos acceder, es decir, si queremos abrirel fichero como solo lectura, solo escritura, para agre-gar o como lectura/escritura.

Para leer el contenido usaremos el método Read, elcual lee el número de bytes indicados y los almacenaen un array que previamente debe estar creado y quetenga como mínimo la cantidad que queremos leer. Enel listado 6 vemos un ejemplo que lee 10 bytes del fiche-ro indicado y lo muestra como una cadena.

Para escribir usaremos el método Write al cualtambién le indicaremos lo que queremos escribir pormedio de un array de bytes. Para poder escribir debe-mos instanciar la clase FileStream con algunos de losvalores que permitan escribir en el fichero.

En el listado 7 vemos un ejemplo que crea unfichero (o lo sobrescribe) y guarda una cadena, y enel listado 8 abrimos el fichero y agregamos una cade-na al final del mismo.

dotN

etM

anía

<<

57

dnm.isla.vb<<

Using sr As New StreamReader(fic, _Encoding.Default, True)

Dim s As String‘ Leyendo todo el contenido de una vezs = sr.ReadToEnd()Console.WriteLine(s)‘ Poner el lector al principiosr.BaseStream.Seek(0,SeekOrigin.Begin)While sr.Peek > -1

s = sr.ReadLine()Console.WriteLine(s)

End Whilesr.Close()

End Using

Listado 3. En este código el método Peek devuelve siempre -1.

Using sr As New StreamReader(fic,Encoding.Default, True)Dim s As String

s = sr.ReadToEnd()Console.WriteLine(s)

sr.BaseStream.Seek(0, SeekOrigin.Begin)Console.WriteLine()

Dos = sr.ReadLine()Console.WriteLine(s)

Loop While sr.Peek <> -1

sr.Close()End Using

Listado 4. Alternativa para el uso de Peek y saber quesiempre funcionará.

Using sw As New StreamWriter(fic,False,Encoding.Default)sw.Write(“Una cadena con Write”)sw.WriteLine(“Una cadena con WriteLine”)sw.WriteLine(123456)sw.WriteLine(1234.56)sw.WriteLine(True)sw.WriteLine(DateTime.Now)

sw.Close()End Using

Listado 5. Ejemplo de uso de StreamWriter.

Using fs As New FileStream(fic, _FileMode.Open, FileAccess.Read)

Dim by(0 To 9) As Bytefs.Read(by, 0, 10)

‘ Convertir en una cadena los bytes leídosDim s As String = Encoding.Default.GetString(by)Console.WriteLine(“‘{0}’”, s)

fs.Close()End Using

Listado 6. Leer de un fichero usando el método Read.

dotN

etM

anía

<<

58

dnm.isla.vb<<

Por supuesto, si lo que queremos hacer es lo mos-trado en los listados anteriores, lo mejor sería usar lasclases que vimos en el acceso secuencial, ya que resul-tan más cómodas de usar; el acceso binario debemosdejarlo para casos más concretos. Aunque la claseFileStream la podemos usar de forma más genérica,aunque solo sea para indicar la secuencia a la que que-remos acceder, ya que el resto de clases derivadas deStream suelen definir un constructor que recibe comoparámetro el objeto Stream al que queremos acceder.

Acceso aleatorio

Entre las clases propias de .NET no existe nin-guna que nos de una funcionalidad parecida a la quecomenté de Visual Basic 6.0. Aunque podemos usarel acceso binario para simular el acceso aleatorio (ocasi), ya que básicamente esa forma de acceder al con-tenido de un fichero es usando una longitud fija, yeso es lo que hacen los métodos Read y Write que aca-bamos de ver en el apartado anterior.

Acceso al contenido de los ficheros usando clasespropias de Visual Basic

Para facilitar el trabajo a los usuarios de VisualBasic, y englobados en el objeto My.Computer.FileSys-tem, existen una serie de métodos y propiedades parahacer diferentes tipos de acciones con todo lo refe-

rente al acceso al sistema de archivos. Entre esosmétodos encontramos varios que nos permiten acce-der al contenido de los ficheros.

Esos métodos en realidad devuelven objetos defini-dos en las clases de .NET. Por ejemplo, el método Open-TextFileReader devuelve un objeto del tipo StreamRea-der. Pero como podemos comprobar, viendo el nom-bre del método, resulta evidente qué es lo que hace (almenos si sabemos algo de inglés), y por esa razón pue-de que cualquier usuario de Visual Basic lo utilice antesque otra clase con un nombre menos evidente.

Si nos decidimos a usar OpenTextFileReader, debe-mos saber que en realidad lo usaremos de la mismaforma que usamos la clase StreamReader, ya que ese esel tipo de datos que devuelve ese método. En el códi-go del listado 9 vemos un ejemplo de cómo usar esemétodo para leer el contenido completo con el méto-do ReadToEnd de la clase StreamReader.

Pero si nuestra intención es leer todo el conteni-do de un fichero de una vez y asignarlo a una varia-ble, podemos usar el método ReadAllText, al que leindicaremos el nombre del fichero al que queremosacceder y opcionalmente la codificación a usar. En ellistado 10 vemos un ejemplo.

Si lo que necesitamos es recuperar el contenido deun fichero como un array de tipo Byte, podemos usar elmétodo ReadAllBytes. Este método será el que elijamoscuando necesitemos acceder al fichero en modo binario.

Además de estos métodos para leer la informa-ción existen otros métodos para la acción contraria,es decir, para almacenar datos en el fichero.

El más genérico de esos métodos es OpenTextFi-leWriter, que devuelve una instancia del tipo Stre-amWriter, y para guardar la información usaremos losmétodos de esa clase.

De la misma forma, si queremos guardar un tex-to de forma directa, podemos optar por usar Write-

Using sr As StreamReader = _My.Computer.FileSystem.OpenTextFileReader( _

fic, Encoding.Default)s = sr.ReadToEnd()Console.WriteLine(s)

sr.Close()End Using

Listado 9. Leyendo el contenido de un fichero conOpenTextFileReader

s = My.Computer.FileSystem.ReadAllText(fic,Encoding.Default)

Listado 10. Leer todo el contenido del fichero usando ReadAllText.

Using fs As New FileStream(fic, FileMode.Create,_FileAccess.Write)

Dim by() As Byte

by = Encoding.Default.GetBytes(_“Una cadena usando Write”)

fs.Write(by, 0, by.Length)

fs.Close()End Using

Listado 7. Creamos un nuevo fichero.

Using fs As New FileStream(fic, FileMode.Append,_ FileAccess.Write)

Dim by() As Byte

‘ Posicionarlo al finalfs.Seek(0, SeekOrigin.End)

by = Encoding.Default.GetBytes(_“Una cadena a añadir”)

fs.Write(by, 0, by.Length)

fs.Close()End Using

Listado 8. Añadimos texto a un fichero existente.

dotN

etM

anía

<<

59

dnm.isla.vb<<

AllText. Este método guarda (o agrega) el texto indi-cado en el segundo argumento al fichero que haya-mos indicado en el primero y también podemos ele-gir la codificación que usaremos.

Por último, si queremos guardar en un fichero unarray de bytes, podemos usar el método WriteAllBy-tes. Con este método también podemos indicar siagregamos el contenido a un fichero existente o losobrescribimos completamente.

Para los curiosos (y para los usuarios de otros len-guajes que quieran esta funcionalidad de Visual Basic),decir que todos los métodos de My.Computer.FileSys-tem en realidad están definidos en el módulo Micro-soft.VisualBasic.FileIO.FileSystem, por tanto, agre-gando una referencia al ensamblado Microsoft.Visual-Basic.dll tendremos acceso a todos estos métodos.

Acceso especial al contenido de los ficheros usandoTextFieldParser

Visual Basic define una clase especial que nos vendrábien cuando necesitemos acceder a los ficheros usandodatos de longitud fija (al estilo del acceso aleatorio deVisual Basic 6.0) o cuando el contenido de esos ficherosutilice separadores. Este último caso es realmente útilpara acceder a los típicos ficheros con la extensión .csv,que habitualmente suelen contener la información usan-do una coma como separador de cada columna de datos(una línea equivale a una fila).

En el listado 11 podemos ver un ejemplo de acce-so a un fichero delimitado por comas.

El delimitador (o delimitadores) que queramosusar lo indicaremos como una cadena en el métodoSetDelimiters o bien podemos asignar un array de tipoString a la propiedad Delimiters. Esto nos permiteusar más de un delimitador o delimitadores con másde un carácter, aunque lo habitual en estos casos estener solo delimitadores de un solo carácter.

Si queremos leer ficheros en los que cada líneacontiene la información usando cantidades fijas de

caracteres para representar cada columna, tambiénpodemos usar esta clase, solo que en la propiedad Text-FieldType le asignaremos el valor FieldType.FixedWidth,además tendremos que indicar los anchos de cadacolumna, esto lo podemos hacer de dos formas: asig-nando un array de tipo entero con esas longitudes ala propiedad FieldWidths, o bien usando el métodoSetFieldWidths y pasándole como argumento losanchos separados por coma.

Aclarar que esta forma de leer el contenido de losficheros solo funcionará si cada fila de datos está enuna línea diferente. Y debido a que esta es la forma deusarlo, podemos flexibilizar el acceso (o la creación deesos datos de longitud fija) haciendo que la últimacolumna (o el último dato de cada línea del fichero)tenga una longitud variable. En ese caso, simplemen-te indicaremos un valor -1 como la longitud de la últi-ma columna.

En el código del listado 12 vemos un ejemplo decómo usar esta forma de acceder a los ficheros conlongitud fija.

ConclusionesEn este artículo hemos visto cómo acceder al conte-

nido de los ficheros (o archivos) de disco con Visual Basic,y como hemos comprobado, este lenguaje ofrece variasopciones para hacer esa tarea, no solo usando las clasespropias de .NET Framework, ya que en el espacio denombres del runtime de Visual Basic también dispone deotras opciones. Y como de costumbre, en el ZIP con elcódigo que acompaña al artículo están los proyectos usa-dos para las diferentes pruebas, incluso las realizadas conVisual Basic 6.0 y C#.

Solo me queda recordaros que este mes de sep-tiembre empiezo en Málaga una gira por varias ciu-dades españolas que me permitirá estar en contactodirecto con grupos de usuarios de .NET de diez ciu-dades, principalmente de la costa mediterránea.

¡Nos vemos!

Using tp As New vbio.TextFieldParser(fic, _Encoding.Default, True)

tp.SetDelimiters(“,”)tp.TextFieldType = vbio.FieldType.Delimited

While Not tp.EndOfDataFor Each s As String In tp.ReadFields

Console.WriteLine(s)NextConsole.WriteLine()

End Whiletp.Close()

End Using

Listado 11. Acceso a un fichero delimitado por comas.

Using tp As New vbio.TextFieldParser(fic, _Encoding.Default, True)

tp.TextFieldType = vbio.FieldType.FixedWidthtp.SetFieldWidths(6, 12, 18)

While Not tp.EndOfDataFor Each s As String In tp.ReadFields

Console.WriteLine(s)NextConsole.WriteLine()

End Whiletp.Close()

End Using

Listado 12. Acceso a un fichero con datos de longitud fija.

Al igual que otras aplicaciones .NET, los sitiosWeb ASP.NET pueden aprovechar el trata-miento de excepciones y manejar los errores entiempo de ejecución que puedan surgir. No obs-tante, las excepciones deberían ser lo que sugie-re su nombre: eventos excepcionales en la vidade la aplicación que se lanzan cuando sucedealgo que viola un comportamiento establecido.Luego no debieran usarse para manejar el flu-jo natural de un programa. Si hay una forma dedetectar situaciones inconsistentes, debemosusar esta otra opción y dejar el manejo de excep-ciones como último recurso. Dicho esto, cuan-do sucede una excepción en una aplicaciónASP.NET, el CLR intenta encontrar un bloquede código susceptible de ser capturado. Lasexcepciones navegan por la pila hasta que sealcanza la raíz de la aplicación. Si —en el cami-no— no aparece ningún manejador adecuado,la excepción es entendida como una Unhandled

Exception, lo que origina que el CLR lance unaexcepción a nivel de sistema. En este punto, losusuarios reciben una página estándar de errory la aplicación se detiene. Esa página típica deerror difiere entre usuarios locales y remotos.Los usuarios locales (pongamos que accedien-do vía localhost), reciben una página con la pilade llamadas hasta la excepción y una breve des-cripción del error. La información adicional decódigo fuente puede añadirse a lo anterior si lapágina se está ejecutando en modo depuración(debug). Por razones de seguridad los usuariosremotos reciben una página mucho menos deta-llada que —básicamente— informa de que algoha ido mal.

ASP.NET suministra un par de puntos glo-bales de intercepción para manejar erroresmediante código, ya sea a nivel de página o anivel de aplicación. La clase base Page, exponeun evento Error que puedes sobrescribir en tus

Excepciones en ASP.NET y gestión excepcional de formularios

Dino Esposito

Dino Espositoes mentor asociado

de Solid QualityMentors. Es ponentehabitual en eventos

a nivel mundial. Visitesu blog en:

http://weblogs.asp.net/despos.

([email protected])

Habitualmente desarrollo aplicaciones Web en .NET que poco a poco se van compli-cando en cuanto a estructura y funciones. ¿Cuál es la mejor forma de centralizar el tra-tamiento de excepciones en aplicaciones Web? Por ejemplo, listar últimas excepciones,errores, notificar por email…

todonet@qa

¿Qué es una excepción sino algo excepcional en el ciclo de vida de una aplicación? ¿Ycómo debe manejarse? ¿"In-situ" o de forma centralizada? Este mes discutiremos elmanejo de excepciones en ASP.NET y cómo manejar múltiples formularios.

tod

otN

et.q

a@

dot

netm

ania.c

om

propias páginas y capturar cualquier excepción lan-zada durante la ejecución. De forma similar, exis-te un evento Error en la clase HttpApplication, paracapturar cualquier excepción producida de formageneral, a nivel de aplicación. Para manejar erro-res globalmente hay que introducir algo de códigoen el fichero Global.asax, pero vamos a manejar loserrores a nivel de página primero.

Para capturar un error que suela producirse enuna página concreta, definimos un manejador deevento para el evento Error, tal y como se muestraen el código adjunto:

Nos enteramos de la excepción producida através del método GetLastError del objeto Server.¿Qué debiéramos de hacer en el manejador deerror? Esencialmente, una sola cosa: transferir alusuario a una página apropiada de explicación dela situación. La página de error siempre dará la sen-sación de haber controlado las situaciones inespe-radas y haber sabido manejar la excepción de for-ma profesional.

Además de redirigir al usuario a la página deerror, hay un par de cosas que pueden hacerseopcionalmente. En particular, puede interesarnosgrabar los datos del error en algún mecanismo ade-cuado, o mandar un correo al administrador delsitio. Claramente, el objetivo de tu manejo de erro-res es distinto. Cuando redireccionas a una página,estás pensando en el usuario final y preservando elflujo de la aplicación. Cuando mantienes una bitá-cora de errores o envías un correo, estás pensandoen administración y mantenimiento. Te sugiero quetengas presente la diferencia entre ambos concep-tos a la hora de diseñar la estrategia de manejo deexcepciones.

Puedes redirigir a los usuarios a una página deerror usando el método Redirect del objeto Respon-se. En ese caso, el navegador simplemente realiza otrapetición de URL al servidor Web. Se pierde toda lainformación de la excepción y se debiera almacenaren el objeto Cache o Session, para rellenar adecuada-mente la información de la página de error que se lemuestra al usuario. También puedes pasar esta infor-mación en la query string, ya sea de forma explícita o

mediante algún tipo de código preestablecido. Si uti-lizas códigos internos, la página será responsable deinterpretarlos y dar la respuesta adecuada. Se puedenmantener un número fijo de páginas de error o bienuna sola que se rellene por código en su mayor par-te. Eso es más un asunto de preferencias. Quizá seapreferible pocas páginas, pero, en ocasiones, una solapágina puede añadir complejidad adicional.

Alternativamente a la redirección explícita, pode-mos usar el método Transfer del objeto Server. Si uti-lizamos esto para pasar el control, la información deexcepción se mantiene y la propia página de gestiónde error puede llamar a GetLastError y mostrar infor-mación detallada. Se puede transferir el control a unapágina concreta y mostrar un mensaje de tratamien-to de error específico y personalizado. El control pasaa la página de error y la URL de la ventana del nave-gador no cambia. Finalmente, una vez que la excep-ción está totalmente controlada, se borra el error lla-mando a ClearError.

Un manejador de errores de página solo captu-ra aquellos que se producen en su contexto parti-cular. Eso significa que cada página que requieragestión de errores debe apuntar a un bloque decódigo común, o implementar su propia gestión.Eso no es apropiado para los casos en los que sedesea generalizar el tratamiento de errores paramuchas o todas las páginas de la aplicación, que esel mecanismo que yo prefiero. En este caso, pue-des crear un manejador global de excepciones anivel de aplicación que capture todas las excepcio-nes no manejadas y las dirija a una página especí-fica de error. La implementación es prácticamen-te idéntica a la de los manejadores a nivel de pági-na, excepto que manejaras el evento Error corres-pondiente al objeto HttpApplication que representala aplicación. Para hacerlo así, hay que añadir un fiche-ro Global.Asax a la aplicación y codificar algo similara lo que se muestra en el listado 2 en el manejador pre-determinado Application_Error.

dotN

etM

anía

<<

61

Tod

otN

et.q

a@

dot

netm

ania

.com

Tod

otN

et.q

a@

dot

netm

ania

.com

dnm.todonet@qa<<

protected void Page_Error(object sender, EventArgs e){

// Captura el error Exception ex = Server.GetLastError();:

}

Listado 1

void Application_Error(object sender, EventArgs e) {// Obtiene el objeto Exception que describe el error Exception error = Server.GetLastError();:

// lo escribe en el Event logEventLog log = new EventLog();log.Source = "Your Log";log.WriteEntry(error.Message, EventLogEntryType.Error);

}

Listado 2

Se pueden tener ambos sistemas simultáneamen-te. El manejador a nivel de página se llama previa-mente al manejador de aplicación. Una aproximacióndeseable consiste en manejar los errores globalescomunes a nivel de aplicación y los específicos a nivelde página.

Ten en cuenta que los errores HTTP distintos de500 no son capturados por ninguno de los dos siste-mas, ya que son manejados directamente por el servi-dor Web y no pasan a través del mecanismo de mane-jo de errores. Para estos casos (tales como los errores404) es preferible “mapear” los errores comunes a pági-nas ad hoc usando las características incluidas en elfichero Web.Config.

Como conclusión, mi sugerencia es que tengas unmanejador global para capturar excepciones comunes—tales como referencias nulas o características nosoportadas por el servidor— y páginas específicas para

el manejo de características no soportadas por múlti-ples páginas. En todos los casos, siempre se deberíaredirigir al usuario a páginas explicativas, teniendocuidado de no dar explicaciones adicionales que pue-dan comprometer la seguridad. Al mismo tiempo,escribe en un log lo que suceda. El mejor sitio paracontrolar eso es, sin duda, la función Application_Error.De hecho tu código siempre pasa por ahí.

Concluyo esto comentando que, el hecho de imple-mentar un sistema de gestión de errores, no debe deentenderse en detrimento de la inclusión de bloquestry/catch en el código. Se deberían utilizar bloques ifpara prevenir posibles errores e incluir estructurastry/catch donde prevemos que pueden producirse erro-res conocidos. Para cualquier otra situación que pudie-se suceder, están los manejadores a nivel de página ya nivel de aplicación. En otras palabras, para manejartodo lo que no pueda manejarse de otra forma.

Es una cuestión correosa. La respuesta está llena de con-dicionantes y peros. Sin embargo, la respuesta más sen-cilla y rápida es ésta: la única restricción que tienes esque debes incluir solamente un formulario activo. Si sesatisface este requisito, lo demás se permite. Expliqué-moslo un poco más.

El motor de visualización de ASP.NET hace una com-probación específica del número de controles HTML-Form que va a interpretar. Cuando intentas añadir unsegundo control de este tipo, se genera una excepción.Recordemos que entendemos por eso lo que hay detrásde una etiqueta <form runat=server>.

Se pueden tener tantos formularios de servidor comose quiera, en tanto que solo uno emita código de marcas entiempo de ejecución. La propiedad visible controla si unaetiqueta ASP.NET emite código de marcas. Si tú, median-te programación, modificas el atributo booleano Visible paraetiquetas de servidor, eso está correcto y es aceptable.

Al mismo tiempo, puedes tener cualquier número deetiquetas no-ASP.NET, o sea, etiquetas en HTML clá-sico sin el típico atributo runat=server. En este caso, pue-des tener múltiples formularios lógicos en una sola pági-na ASP.NET. Esto, teniendo en cuenta, que para captu-rar un método post de un formulario no-ASP.NET, nopodemos manejar las facilidades de postback tradiciona-les. No hay ViewState automáticamente creado, y no hayrelleno de valores automático en los controles asociados.Para manejar una petición post de este tipo tienes querecurrir a las técnicas de ASP antiguo, y utilizarRequest.Form o Request. QueryString para leer datos deentrada.

Sin embargo, un formulario plano HTML sí per-mite enviar cierto contenido a otra página. La páginareceptora, no obstante, no podrá procesar el ViewSta-te, independientemente de su extensión (ASPX, ASPo HTML).

dotN

etM

anía

<<

62

dnm.todonet@qa<<T

odot

Net.q

a@

dot

netm

ania

.com

Tod

otN

et.q

a@

dot

netm

ania

.com

Traducido al castellano por Marino Posadas

¿Es posible tener múltiples formularios en una página ASP.NET?

Se pueden tener ambos sistemas simultáneamente. El manejador anivel de página se llama previamente al manejador de aplicación. Una

aproximación deseable consiste en manejar los errores globalescomunes a nivel de aplicación y los específicos a nivel de página

Learning ASP.NET 3.5Jessy Liberty, Dan Hurwitz y Brian MacDonaldEditorial: O'Reilly MediaPáginas: 607Publicado: julio de 2008ISBN: 978-0596518455Idioma: inglés

Ya hemos citado a Liberty a propósito del trabajo de evangelismo y producción dematerial didáctico que realiza para Microsoft en Redmond. Pero es que Jessy, literal-mente, no para. Y como muestra, baste, no un botón, sino 3. Hoy comentamos 2 obrasrecientes y citamos una futura de tan prolífico y didáctico autor. En "Learning ASP.NET3.5", Hurwitz y McDonald colaboran con él para crear una obra didáctica, centrada enla programación Web, y asumiendo un conocimiento básico de ASP.NET por parte dellector, para introducir las novedades de la versión 3.5 de ASP.NET.

El abordaje es paralelo: por un lado se hace énfasis en las nuevas características de estaversión de ASP.NET, y por el otro se pretende remarcar la perfecta integración de la tecno-logía dentro de Visual Studio 2008, como herramienta complementaria y recomendada. Estoincluye un tratamiento completo del desarrollo con AJAX, cobertura de controles, manejode scripting, procesos de instalación y más cosas. Todo con ejemplos comentados y funcio-nales. Un conjunto de buenas clases particulares sobre ASP.NET 3.5.

Programming .NET 3.5Jessy Liberty y Alex HorovitzEditorial: O'Reilly MediaPáginas: 476Publicado: agosto de 2008ISBN: 978-0596527563Idioma: inglés

Aquí, Liberty tiene como colaborador a Alex Horovitz, de quien comentamos al pieuna de sus obras de próxima aparición. El estilo es similar (él dirige ambas obras), y elpropósito, no perder el carácter de obra de aprendizaje, mientras va introduciendo al lec-tor en las (muchas) novedades de .NET 3.5. A través de un tour de force de menos de 500páginas, recorren las 4 principales API contenidas en el producto (WPF, WCF, WF yCardSpace), y ubican cada una de ellas en el contexto de la creación de aplicaciones orien-tadas a servicios, o el más actual concepto de "software + servicios".

Los ejemplos, con un corte similar al de la obra anterior, están escritos en C#, y dis-ponibles en breve en dos sitios Web: el del propio autor y el de la editorial. No obstan-te, es un recorrido práctico por lo fundamental de cada API; no un libro de recetas o detrucos. Para eso, comentaremos algunas novedades el mes que viene.

biblioteca.net

nove

dad

es Programming Silverlight 2.0

Jessy Liberty y Tim Heuer. Editorial: O'Reilly Media. Páginas: 504. ISBN: 978-0596516123.

Fecha de publicación: noviembre de 2008. Idioma: inglés.

Programming ASP.NET MVCAlex Horovitz. Editorial: O'Reilly Media. Páginas: 350. ISBN: 978-0596521851. Fecha de

publicación: octubre de 2008. Idioma: inglés.

TEXTO: MARINO POSADAS

dotN

etM

anía

<<

64

Si alguien te pregunta “¿qué es INETA?”, aparte de decir-le que se una inmediatamente, ¿qué le responderías?

INETA es la asociación Internacional de grupos de usua-rios de .NET. Tiene como función soportar y ofrecer servi-cios a los grupos de usuarios, y ha sido conocida durante muchotiempo por su bureau de oradores (quién es quién y serviciospara desplazarse y asistir a eventos). Actualmente dispone deun montón de nuevos programas que nos permiten ofrecersoporte a los grupos de usuarios en muchas más formas... todasde gran ayuda y valor para los grupos de usuarios. Tambiénestamos ayudando activamente a que la gente se involucre,ofreciendo ayuda en la gestión de sitios Web, proporcionan-do visibilidad, servicios de comunicación y otros para el desa-rrollo de habilidades profesionales como escribir, entre otros.Fundamentalmente estamos dedicados y enfocados a ofrecersoporte a los grupos de usuarios y sus miembros.

¿Qué puedes decirnos de INETA Norte América, susobjetivos y actividades?

Básicamente ¡que es un gran grupo! con un equipo direc-tivo muy proactivo y planes ambiciosos... A destacar, que des-de hace algún tiempo hemos sido conocidos principalmentepor nuestro gabinete de oradores, compuesto por un feno-menal grupo de los mejores oradores de nuestra industria. Noobstante, recientemente hemos crecido con algunos nuevosprogramas que proporcionan servicios a la comunidad de gru-

pos de usuarios. Algunos que me gustaría mencionar son: nues-tro programa de escritores, que ayuda a los miembros de gru-pos de usuarios a obtener reconocimiento en reconocidasrevistas y a realizar artículos; nuestro programa de oradoresvirtuales, que ofrece una forma para los oradores de INETApara abarcar un mayor número de grupos de usuarios de for-ma virtual; también tenemos nuestro programa INETA Live,que permite exhibir presentaciones de grupos de usuarios yoradores a todo el mundo; y nuestro programa CommunityChamps para recompensar a los miembros de grupos de usua-rios por el duro trabajo que realizan soportando y potencian-do a la comunidad de grupos de usuarios. También estamostrabajando en montar una competición de codificación y otrastecnologías relacionadas, con el objetivo de motivar y com-prometer a la comunidad y ayudarles a involucrarse con nue-vas tecnologías. Por último, estamos abriendo INETA a otrosgrupos de usuarios no relacionados con .NET, ya que en elpasado estábamos muy centrados en ellos.

También estamos trabajando en otras áreas o programas,como “competiciones de código”, para lo que pretendemosorganizar una competición anual de desarrollo, actualmenteen consideración. Esto podría proporcionar un reconocimientode alto nivel, así como tener algunos premios realmente impor-tantes. Esperamos poder empezar a anunciar la primer com-petición en un corto espacio de tiempo, y, un detalle impor-tante es que esta actividad está siendo planificada a nivel inter-nacional, junto con Microsoft e INETA Europa. Nuestro obje-tivo es organizar un concurso mundial, donde las mejores par-ticipaciones puedan recibir fama y fortuna. En ellas, ¡hallare-mos a las estrellas de rock del desarrollo!

Como conocereis mejor que nadie, ya que en Europa seorganizó la exitosa competición “INETA Europe SilverlightChallenge”, quién no querrá llevarse el título de honor de serel mejor del mundo en una tecnología concreta.

Y sobre el programa “Community Champs”, ¿podríasexplicárnoslo un poco?

Sí, éste es un programa muy novedoso que INETA estáactualmente lanzando; un programa que reconozca y recom-pense las actividades dedicadas a la comunidad, basado en dostipos de reconocimientos o premios: 1. Premio “community champs”. Todas las tareas que están

implícitas en montar un grupo de usuarios son realmen-te apreciadas por INETA, Microsoft y todos los miem-bros de dicho grupo, pero nadie reconoce dicho esfuer-zo. Este programa está diseñado para hacer esto específi-camente, reconocer estos tipos de esfuerzo: cuando orga-nizas un evento, consigues los oradores, te comunicas conellos, pides bebidas o comida, obtienes patrocinio, etc,¡todo! Con este programa, podrás obtener reconocimientopor todo ello. Los premios se anuncian de forma cuatri-

Entrevista a

David Silverlight

comunidad.net

David SilverlightDavid Silverlight es unreconocido MVP así comoun importante puntal de lacomunidad de desarrolla-dores de Norte América.También es el vicepresi-dente de marketing de

INETA NorAm y el fundador de uninteresante proyecto Web 2.0 denomi-nado Community Credit. Por otro ladoestá gestionando algunos proyectossumamente interesantes que conocere-mos a lo largo de la entrevista.

El pasado sá -ba do 19 de ju -lio organiza-mos el últimoevento antesde las mereci-das vacacio-

nes, en el que contamos con Hadi Hariri,ponente internacional y MVP de Microsoft, yque tuvo un gran éxito de asistencia.

La primera ponencia, a manos de Hadi,nos introdujo en el interesantísimo mundo delas aplicaciones distribuidas con WCF. Desdeel primer momento, Hadi se metió en el bol-sillo a los presentes, demostrando sus tablas eneste tipo de actos y dándonos una clara expli-cación de esta tecnología, y demostrándonossu utilización con varios ejemplos.

La siguiente charla fue una introduccióna ASP.NET AJAX realizada por mí mismopara mostrar cómo la unión de diferentestecnologías pueden hacer cambiar total-mente el enfoque de una plataforma comoes la Web tradicional.

La última ponencia, de nuevo a manosHadi, fue una introducción a las buenas prác-ticas en el desarrollo de software y pruebasunitarias.

Realmente el tiempo se nos echó encimay se nos hizo cortísimo, por lo que no pudi-mos disfrutar todo lo que hubiéramos queri-do de la presencia de Hadi; estoy seguro queno será la última vez que tengamos la suertede contar con su presencia en el grupo.

Nos vemos de nuevo en Tarragona. MarcRubiño.

mestral y justo acabamos de anunciarnuestros primeros ganadores, dando comopremios 10 Xbox 360, algunas suscrip-ciones msdn, etc.

2. Premio “Community Excellence”. Estepremio se otorga a una única persona cada6 meses y es esencialmente un reconoci-miento de toda una vida de logros, reco-nociendo este premio todo el trabajo ydedicación de esta persona. Montando yejecutando eventos, codecamps, competi-ciones, etc. A personas siempre involu-cradas en la comunidad. Esto es un pre-mio basado en la nominación, queriendodecir que uno debe ser nominado poralguien.

Acerca de estos programas, ¿son especí-ficos a INETA Norte América o están abier-tos a todo el mundo?

Bien, aquí debería de decir que, por aho-ra, todos los programas son para INETA Nor-te América, pero algunos están planificadospara ser aplicados a otras regiones, como, porejemplo, el recién mencionado CommunityChamps, que está en su fase inicial. Poste-riormente lo revisaremos, mejoraremos y sitiene éxito, lo extenderemos a otras regionestambién. Lo mismo se aplica a los programasINETA Authors, INETA Live y de oradoresvirtuales.

¿Qué nos puedes decir de tus otros pro-yectos?

He estado involucrado en CommunityCredit desde hace algunos años. CommunityCredit es mi proyecto personal y está muy cla-ramente definido por su tagline; “we give stu-pid prizes to smart people” (damos premiosestúpidos a gente elegante); ello es un reco-nocimiento por las horas dedicadas al desa-rrollo de la comunidad de desarrolladores. Esun programa de puntos que ofrece un montónde premios geek tales como un lanza-misilesUSB, un teclado dynamic pixel, un NintendoWall Graphics, que decora una habitaciónentera como si estuvieras dentro del juegoSuper Mario Brothers. Uno de mis favoritos

es la alarma digital Laser Pistol, que tiene ungran blanco en ella y para apagarla hay quedispararle en él. También tenemos un des-pertador volante, que para apagarlo hay queagarrarlo y bajarlo al suelo... ¡todo muy orien-tado a geeks!

Por otro lado también gestiono XML PIts-top.com, una comunidad de desarrolladores deXML que fundé hace ya tiempo y sigue sien-do un buen recurso para desarrolladores queutilicen XML.

Otro proyecto que me gusta mostrar esRealTechnologyheroes.com, éste es un sitio dehumor inspirado en algunos anuncios comer-ciales como los de Budweiser, en los cuales agra-decen a gente que normalmente no es agrade-cida por su trabajo, pero obviamente cambia-do para computer geeks como nosotros ☺.

David, ¿qué piensas de Silverlight comotecnología?

Es una impresionante tecnología con laque es imposible no emocionarse. Está cam-biando la forma en que construimos aplica-ciones y podemos que va a tener un impactomuy profundo. Creo que uno de los aspectosmás importantes es que está cumpliendo suspromesas. En el pasado, muchas tecnologíashabían prometido el mundo y finalmente nohan entregado nada. Silverlight está definiti-vamente entregando, especialmente con losavances que la versión 2.0 nos ha traído. Unpanorama muy emocionante, sin duda.

También está generando mucha expecta-ción, puedes ver los ejemplos en el sitio Websilverlight.net y ya están yendo más allá de cual-quier cosa vista previamente que se haya hechocon Javascript, AJAX y otras tecnologías deback-end, y lo mejor es que la creencia gene-ral es “bien, lo podría hacer yo mismo con herra-mientas que ya conozco y me gustan", desde queestá tan integrado con .NET y con la versión2.0, el potencial para utilizarlo en aplicacio-nes de negocios es fenomenal.

dnm.comunidad.net<<

Leyenda urbanas entorno a la denominación Silverlight

En la blogosfera se comenta que DavidSilverlight es –según muchos– la personaresponsable del nombre dado a la tecnologíaanteriormente conocida como WPF/E, comopueden ver en la entrada del blog http://jeffbarnes.net/portal/blogs/jeff_barnes/archive/2007/04/18/congratulations-david-silverlight.aspx.También el mismo Tim Sneath le mencionaen su post de cómo le dieron el nombre aSilverlight (http://blogs.msdn.com/tims/archive/

2007/04/18/how-did-we-come-up-with-silverlight.aspx). Además, adjuntamos un postde David, mencionando la denominación delproducto: http://www.community-credit.com/cs/blogs/starbucks_is_my_home/archive/2007/04/16/Microsoft-Silverlight-_2D00_-What-an-Honor_210021002100_.aspx.

En cualquier caso, le proponemos queindague por su cuenta y obtenga sus propiasconclusiones. ¿Leyenda urbana o realidad?

José Luis Latorre

Evento de LoNetCamp

El pasado 1 de julio tuvo lugar en Second -Nug(www.secondnug.com) un evento dedicado a loscontroles grid, en el que José Manuel Alarcónen la parte Web con GridView, y Luis MiguelBlanco en la parte Windows Forms conDataGrid View, abordaron mediante un conjuntode ejemplos prácticos, alguno de los trucos sobreestos controles que tantas consultas generan enlos foros de MSDN.

Al igual que en el resto de ocasiones, esteevento fue grabado para su posterior descargay reproducción en diferido en el siguiente enlace:http://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=es-ES&EventID=1032381570&CountryCode=ES

SecondNug. DataGrid a fondo

dotN

etM

anía

<<

66

desvánMarino Posadas

An Introduction to F# for Functional Programming es unartículo publicado en DevX.com por Adam Granicz que sir-ve de buena introducción, sencilla, pero suficiente, al conceptode la programación funcional. http://www.devx.com/dotnet/Arti-cle/38755.

Silverlight Streaming: Free Video Hosting for All nos mues-tra cómo construir aplicaciones Silverlight que aprovechen losservicios de streaming de vídeo que Microsoft a puesto a dis-posición de la comunidad. Es Cal Schrotenboer, quien loexplica paso a paso en la dirección: http://www.devx.com/RIA/Article/38742.

Introducing Visual Studio .NET 2008- Top 10 Features es un documento querecorre las que, para su autor (Mark

Smith), son las 10 mejores novedades que incorpora Visual Stu-dio 2008. Se puede estar o no de acuerdo, pero siempre nos recuer-da alguna cosa (http://www.developerfusion.co.uk/show/7633).

WORDPRESS.ORG es un sitio dedi-cado a una herramienta relati-

va al uso y mantenimiento de sitios Web y blogs, y los estánda-res asociados con ellas.

useit.com. El sitio Web de Jakob Niel-sen contiene más de lo que parece aprimera vista, pero buena parte de ello

está relacionado con la experiencia de usuario. Ahora que todosnos preocupamos por ese aspecto de la construcción de soft-ware, merece una visita.

Zamzar es un conversor de imá-genes online, para que los usua-rios no tengan que descargarse

ningún software al equipo local. Soporta un montónde formatos, de doumentos, música, imágenes, videoy compresión: http://www.zamzar.com.

documentos en la red

utilidades del mes

sitios del mes

Capas de abstracción de softwareDesde ODBC a ADO.NET Data Services

El conocimiento, como la burocracia, tiende inexorablemente a ramificarse amedida que va creciendo. Y la informática ha crecido mucho, dicen algunos quedemasiado. Que se ha vuelto demasiado compleja y nos vamos a volver locos.Yo, de natural más optimista, no creo que sea así. Al final, como siempre, el hom-bre adoptará una postura práctica, más o menos razonable y sobre todo maneja-ble, que permita salir adelante. Si algo es complejo, tienes que pelearte con elloy puedes fragmentarlo, ya sabes: divide y vencerás.

Así, en un principio, fue el Ensamblador. Más ade-lante, vio el hombre que éste era muy liado y creó los len-guajes de alto nivel: Algol (Alan Perlis), Cobol (GraceHopper, en la foto), Fortram (John Backus) y algunosmás. Y los de medio nivel: C (Brian Kernighan y DenisRitchie). La idea era abstraer las instrucciones de bajonivel en sentencias de más alto nivel, en “ladrillos” cons-tructores más manejables, evitando trabajar directamen-te con la argamasa que nos explicaba Peter Norton en

su “Programación en Ensamblador”. Pero eso no era suficiente. Al hacer el soft-ware más complejo, el número de variables crecía sin control, y se hacía inma-nejable. La programación estructurada mejoraba la situación, pero solo hasta cier-to punto... Y apareció la Orientación a Objetos (Ole-Johan Dahl y KristenNygaard). Y C++ (Bjorn Stroustrup). La idea subyacente era la misma: si pue-do abstraer ese código en formas más manejables la lectura tendrá más sentido;será más fácil, menos propenso al error. Así que pensemos en objetos y doté-mosles de estado (campos), mecanismos para transformarlo y formas de comu-nicación con otros objetos. La semilla estaba plantada.

A partir de ahí, muchos de los avances importantes, han venido de la manode la abstracción (el hardware ya mejorará y lo soportará de forma adecuada). Enlos sistemas operativos de ventanas (X-Windows sobre Unix fue el primero), yaexistían interfaces de usuario que usaban conjuntos de controles. Fueron inge-nieros del M.I.T. los que definieron cómo se hace un sistema operativo de ven-tanas. En 1990, James Martin y J.J. Odell anticipaban el concepto de compo-nentización en su obra “Object Oriented Analysis and Design” (Prentice-Hall)y sus predicciones se han cumplido casi al 100%.

El acceso a datos no iba a ser una excepción. Primero, las API propietariaspara acceder a los servidores. Después, entran en escena las capas de abstracción:ODBC y OLE-DB nos permiten programar sin saber detalles de la implemen-tación del servidor. Seguimos el proceso: pasamos por varios estados tentativos(Clipper, etc.) y de repente se decide que toda la ejecución debe ser administra-da. Se abstrae el API del sistema y se crea un máquina virtual (si algo pasa, le pasasolo a la máquina virtual: otra capa de abstracción). Primero es Java y su plata-forma asociada, luego .NET. En la actualidad más del 90% del software (exclu-yendo sistemas operativos y otros de especial integración con el core), se cons-truye de esa forma. Quedaba por crear otra capa de abstracción que comunicaselos programas ejecutándose en runtime, con los mecanismos de abstracción dedatos. Ese fue el objetivo de ADO y ADO.NET.

Bueno, parece que vamos bien. Ahora hay que comunicarlo todo. Y de for-ma segura. Llegan XML y los servicios Web. Y el Software as a Service. Lo últi-mo, ADO.NET Data Services otra capa de abstracción sobre las anteriores. Ymuy prometedora. Soportada por Visual Studio 2008 y pendiente de una pron-ta actualización a una versión más que manejable. Al fin, el sueño de Martin yOdell hecho realidad. Hace no mucho, Clemens Vasters decía “Hoy, una apli-cación es un servicio con interfaz de usuario”. ¿Dónde estás Ensamblador?

noticias.noticias.noticias.noticias

Smash!ng apps. Encontramosmuchas utilidades en este sitiode aplicaciones gratuitas y,entre ellas, la posibilidad de

descargarnos iconos para la Web. Hay varios conjun-tos disponibles. En realidad todo el sitio merece unrepasito… http://www.smashingapps.com/2008/04/22/free-psd-icons-for-your-web-applications.html.