El evento CellPainting del control DataGridView

Transcripción

El evento CellPainting del control DataGridView
www.dotnetmania.com
nº 43 diciembre 2007 6,50 €
Visual Basic • C# • ASP.NET • ADO.NET • SQL Server • Windows System
dotNetManía
dedicada a los profesionales de la plataforma .NET
Vía libre a la creatividad
El evento CellPainting del control DataGridView
entrevista
Catherine Heller
Technical Evangelist
Microsoft Corporation
eventos
TechEd Europe 2007
Lanzamiento de Biztalk 2006 R2
CEUS 2007
Tablet PC SDK (y II). Reconocimiento de escritura
manual • Más sobre seguridad de acceso a código •
Herramientas genéricas para los componentes:
ficheros y recursos • Depuración en .NET. El depurador
que lo depure... recibirá ayuda del CLR
Laboratorio
ILOG Diagrammer for .NET
TodotNet@QA
Silverlight. Presente y futuro
Opinión
Documentos o ejecutables
editorial
dotNetManía
Dedicada a los profesionales de la plataforma .NET
Vol. III •Número 43 • Diciembre 2007
Precio: 6,50 €
Un codename, por favor
Editor
Paco Marín
([email protected])
Redactor jefe
Marino Posadas
([email protected])
Editor técnico
Octavio Hernández
([email protected])
Redacción
Dino Esposito, Guillermo 'Guille' Som, José
Manuel Alarcón, Luis Miguel Blanco y Miguel
Katrib (Grupo Weboo)
Empresas Colaboradoras
Alhambra-Eidos
Krasis
Plain Concepts
Raona
Solid Quality Learning
Además colaboran en este número
Alberto Población, Daniel Seara, Javier
Roldán y Rodrigo Corral.
Corresponsal para América Latina
Pablo Tilotta
Ilustraciones
Mascota (Clico): Yamil Hernández
Portada: Javier Roldán
Fotografía
Roberto Mariscal
Atención al suscriptor
Pilar Pérez
([email protected])
Edición, suscripciones y publicidad
.netalia
c/ Thomas Edison, 4, 1406
Parque empresarial Rivas Futura
28521 - Rivas Vaciamadrid (Madrid)
www.dotnetmania.com
Tf. (34) 91 666 74 77
Fax (34) 91 499 13 64
Bienvenido al número 43, de diciembre de
2007, de dotNetManía.
La cuenta atrás terminó y Visual Studio
2008 está listo para su fabricación (Ready To
Manufacture, que dicen los anglosajones).
Ésta es ya la versión final, descargable por
los suscriptores de MSDN, aunque también
existen versiones de evaluación y Express
para el resto de clientes. Ahora toca rumorear sobre la próxima versión, de la que queda la duda de si tendrá finalmente el codename Hawaii, como se dijo en un principio.
Aunque aún nos queda lejos —supuestamente hasta 2010 ó 2011—, nos podrían dar
un codename fiable pronto, porque si no ¿de
qué vamos a hablar?, ¿de la innombrable
nueva versión de Visual Studio? Una isla o
lo que prefieran, pero ¡dennos un codename,
por favor!
Lo que sí tiene nombre fiable es la
nueva editorial de tecnologías Microsoft
que acaba de nacer en España: Krasis
Press. Esto es una magnífica noticia para
todos los lectores castellano-hablantes.
En nombre de todo el equipo de dotNetManía quiero desearles la mejor de
las suertes. Ya tienen tres libros y pronto aparecerán más. Los tres han sido
escritos por amigos de esta casa: José
Manuel Alarcón (el padre de la criatura), Octavio Hernández, editor técnico
de dotNetManía y Unai Zorrilla, colaborar habitual de esta revista.
Este mes entrevistamos a una vieja
conocida nuestra: Catherine Heller,
Technical Evangelist de Microsoft Corp.,
a la que Marino Posadas ya entrevistó en
2003 en el Ave Fénix (www.elavefenix.com).
Medio española, medio americana, Catherine empezó su carrera profesional en
Microsoft Ibérica y lleva ya unos cuantos
años desarrollando su actividad en Redmond. Actualmente está trabajando junto al equipo de Windows Live.
El artículo de portada de este mes se
titula “El evento CellPainting del control
DataGridView. Vía libre a la creatividad”.
Si quiere lograr efectos avanzados y un
mayor control sobre el proceso de dibujo de las celdas, debe utilizar de forma
conjunta el evento CellPainting y las clases de GDI+. Luis Miguel Blanco se lo
explica con todo lujo de detalles, como
siempre.
Entre nuestros asuntos pendientes,
Javier Roldán termina la miniserie de
artículos dedicada al reconocimiento de
escritura manual con Tablet PC SDK,
mientras que Alberto Población publica el artículo “Más sobre seguridad de
acceso a código”, una extensión de su
artículo “Seguridad de acceso a código”,
publicado en el número 41, de octubre
de 2007.
Y aún hay más, por supuesto. Espero
que le guste.
Imprime
Gráficas MARTE
ISSN
1698-5451
Paco Marín
<< dotNetManía
Depósito Legal
M-3.075-2004
3
sumario 43
Documentos o ejecutables
10-11
La documentación siempre es un aspecto que exige nuestra atención en los proyectos de software. A
menudo tendemos a pensar que la mejor manera de lograr que nuestros proyectos avancen y poder
mostrar ese avance es realizando la documentación adecuada, buscando el ciclo adecuado para esa
documentación y estableciendo una serie de documentos como estándares. Incluso hay metodologías
bastante populares que se centran en definir qué documentos se deben generar, quién es el responsable de cada documento y por qué manos debe pasar cada uno de ellos. ¿Nos olvidamos de que los
documentos no se pueden ejecutar? ¿Nos olvidamos de que el propósito final de todo proceso de
desarrollo es conseguir software que funciona?
Entrevista a Catherine Heller
12-14
Catherine Heller es española (nacida en Madrid), de padre norteamericano, y con muchos años de
estancia en los dos países. En la actualidad, trabaja como evangelista en el grupo de divulgación de
Windows Live, en Redmond, y anteriormente lo había hecho en el de Visual Studio Tools for Office.
Eso fue antes de pasar en Microsoft Ibérica otra buena parte de su carrera…
Eventos
16-19
TechEd 2007: expectación ante un año pleno de novedades, Lanzamiento de Biztalk 2006 R2 y
CEUS 2007
Tablet PC SDK (y II). Reconocimiento de escritura manual
20-26
En la primera parte de este artículo indicamos el modo de preparar el entorno de desarrollo
necesario para la programación de aplicaciones capaces de aceptar tinta digital para más tarde
reconocerla como escritura manuscrita. Asimismo, utilizamos los principales elementos que para este
fin proporciona el Microsoft Windows XP Tablet PC Edition Software Development Kit.
El evento CellPainting del control DataGridView.Vía libre a la creatividad
27-35
Cuando presentamos a nuestros usuarios un conjunto de datos mediante el control DataGridView,
podemos mejorar la apariencia visual del mismo recurriendo al uso de estilos. No obstante, la mera
utilización de estilos resulta escasa si nuestras pretensiones pasan por lograr efectos avanzados y un
mayor control sobre el proceso de dibujo de las celdas. Es por ello que el empleo combinado del evento
CellPainting, perteneciente a este control, junto al conjunto de clases de GDI+ se va a convertir en
un poderoso recurso a nuestro alcance.
Más sobre seguridad de acceso a código
36-39
En una entrega anterior (dotNetManía nº 41) presentamos los fundamentos de la Seguridad de
acceso a código (Code Access Security, CAS) en .NET Framework, y describimos cómo el CLR
determina los permisos del código y cómo se pueden manipular desde las herramientas
administrativas los permisos concedidos a cada ensamblado. En esta entrega veremos cómo se pueden
solicitar, manipular y limitar estos permisos desde dentro de nuestro código.
Herramientas genéricas para los componentes: ficheros y recursos
40-42
Siguiendo con la idea de las generalizaciones en componentes expuesta en el número anterior, en este
artículo veremos algunos otros ejemplos que pueden resultarle interesantes.
Depuración en .NET. El depurador que lo depure... recibirá ayuda del CLR
43-49
La depuración es una de esas cosas que todos hacemos, o deberíamos hacer, y que a nadie le gusta
tener que hacer; no porque no sea necesaria, sino porque al final terminabas fatal de los nervios
cuando la depuración la realizabas con versiones anteriores de Visual Studio para .NET; por suerte,
esto ya no es así con Visual Studio 2005. En esta serie de dos artículos mostraremos las principales
posibilidades que este último entorno pone a nuestro alcance para facilitarnos la depuración de
nuestros programas.
dnm.todotnet.qa
50-52
Silverlight. Presente y futuro.
dnm.laboratorio.net
53-55
ILOG Diagrammer for .NET
dnm.comunidad.net
56
dnm.biblioteca.net
57
Microsoft Expression Web Plain & Simple
C# 3.0 y LINQ
dnm.desvan
58
<<dotNetManía
noticias noticias noticias noticias
noticias
6
Visual Studio 2008 listo para fabricarse
El lunes 19 de noviembre, Microsoft anunció que Visual Studio 2008 y .NET Framework
3.5 han pasado a fabricación. Al mismo tiempo, la versión definitiva ha sido puesta a
disposición de los suscriptores MSDN para su descarga.
Con más de 250 nuevas características, Visual Studio 2008 incluye mejoras significativas en cada una de sus
ediciones, desde Visual Studio
Express hasta Visual Studio Team
System. Los desarrolladores de todos
los niveles podrán disponer de un
entorno integrado consistente, seguro y confiable para desarrollar aplicaciones para las plataformas más
actuales: la Web, Windows Vista,
Windows Server 2008 y 2007 Office System.
Visual Studio 2008 habilita la
visión de Microsoft acerca de las
aplicaciones cliente inteligentes,
permitiendo a los desarrolladores
crear de manera rápida aplicaciones conectadas que ofrezcan las
experiencias de usuario más ricas y
de más alta calidad. Con Visual Stu-
dio 2008, las empresas encontrarán
más fácil que nunca capturar y analizar la información para tomar
decisiones de negocio correctas.
Visual Studio 2008 permitirá a las
empresas de cualquier tamaño
desarrollar con una alta productividad aplicaciones más seguras y
confiables que aprovechen las bondades de Windows Vista y 2007
Office System.
Visual Studio 2008 introduce
avances significativos para los desarrolladores en tres áreas fundamentales:
• Desarrollo rápido de aplicaciones.
• Colaboración efectiva de
equipos.
• Experiencias de usuario avanzadas.
Visual Studio 2008 ofrece herramientas de desarrollo, posibilidades
de depuración y funcionalidades de
trabajo con bases de datos avanzadas e innovadoras para facilitar la
creación de aplicaciones de las aplicaciones del mañana para una
amplia variedad de plataformas.
Incluye mejoras tales como diseñadores visuales para un desarrollo
más rápido para .NET Framework
3.5, mejoras sustanciales en las
herramientas para el desarrollo de
aplicaciones Web potenciadas por
la tecnología AJAX, y mejoras en los
lenguajes de programación (concretamente las Consultas integradas
en los lenguajes —LINQ—) que
aceleran el desarrollo de aplicaciones que accedan a datos de cualquier
naturaleza.
Silverlight 1.1 Tools Alpha para Visual Studio 2008
disponible para descarga
Microsoft ha anunciado recientemente una versión actualizada de Silverlight 1.1 Tools Alpha que trabaja
con la versión final de Visual Studio
2008. Éste es un add-on para desarrollar aplicaciones Silverlight usando los lenguajes de .NET.
Esta versión tiene las mismas características que el add-on de Silverlight
Tools Alpha que estaba disponible previamente para la beta 2 de Visual Studio 2008; simplemente ha sido actualizada para trabajar con la versión final
de Visual Studio 2008. Estas características incluyen plantillas para los
lenguajes .NET, así como intellisense
en code-behind, edición y generación
de código XAML, soporte de depura-
ción y compatibilidad e
integración con proyectos Expression
Blend.
La próxima preview
de Silverlight sí incluirá
muchas nuevas características, así como significativas mejoras.
Puede encontrar
tutoriales quickstart
que detallan cómo utilizar estas características aquí: http://silverlight.net/QuickStarts/Start.
Puede descargar el add-on desde:
http://www.microsoft.com/downloads/details.aspx?FamilyId=25144C27-
6514-4AD4-8BCB-E2E051416E03&
displaylang=en.
Más información : http://weblogs.
asp.net/scottgu.
Los desarrolladores podrán aprovechar todos esos marcos de trabajo tanto
para el lado del cliente como para el lado
del servidor para crear aplicaciones Web
centradas en el cliente que se integren con
cualquier proveedor de datos en el servidor, se ejecuten bajo cualquier navegador
y tengan acceso total a los servicios de
ASP.NET y a la plataforma Microsoft.
Desarrollo rápido de aplicaciones
Para ayudar a los desarrolladores a crear
software moderno, Visual Studio 2008
ofrece nuevas características de acceso a
datos como LINQ, que harán más sencillo el desarrollo de aplicaciones capaces
de analizar información y tomar decisiones a los programadores individuales.
Visual Studio 2008 ofrece además la
posibilidad de generar código para diferentes versiones de .NET Framework
desde dentro del propio entorno. Los
desarrolladores podrán crear aplicaciones
para .NET Framework 2.0, 3.0 ó 3.5, por
lo que podrán dar soporte a una amplia
gama de proyectos desde el mismo entorno integrado.
Experiencia de usuario revolucionaria
Visual Studio 2008 ofrece a los desarrolladores nuevas herramientas que aceleran la creación de aplicaciones conectadas que funcionen sobre las plataformas
más reciente, incluyendo la Web, Windows Vista, Office 2007, SQL Server 2008
y Windows Server 2008. Para la Web,
ASP.NET AJAX y otras nuevas tecnologías permitirán a los desarrolladores crear una nueva generación de experiencias
eficientes, interactivas y personalizadas.
Colaboración efectiva de equipos
Visual Studio 2008 ofrece características
expandidas que ayudan a mejorar la colaboración en los equipos de desarrollo,
incluyendo herramientas que ayudan a
integrar a los profesionales de bases de
datos y los diseñadores gráficos en el proceso de desarrollo.
Utilizar Microsoft .NET Framework 3.5
.NET Framework 3.5 habilita el desarrollo de aplicaciones conectadas que
ofrezcan experiencias de usuario
impactantes, ofreciendo los bloques
prefabricados para resolver problemas
de programación comunes. .NET Framework 3.5 ha sido creado incrementalmente a partir de .NET Framework
3.0, incluyendo múltiples novedades
y mejoras en áreas como la librería de
clases base, Windows Workflow
Foundation, Windows Communication Foundation, Windows Presentation Foundation y Windows Card Space.
Conjuntamente, Visual Studio y
.NET Framework reducen la necesidad de escribir código de bajo nivel,
reduciendo el tiempo de desarrollo y
permitiendo a los desarrolladores concentrarse en resolver sus problemas
de negocio.
Puede descargarlo desde: http://msdn.
microsoft.com/subscriptions.
Liberado Microsoft Visual Studio 2008 SDK 1.0
El SDK de Visual Studio 2008 (versión 1.0)
incluye herramientas, documentación y ejemplos para permitir a los desarrolladores crear,
probar y desplegar extensiones de Visual Studio 2008. También se puede utilizar el SDK
para crear entornos integrados personalizados
basados en el nuevo Visual Studio 2008 Shell.
Estos productos abren una nueva era en la
extensibilidad de Visual Studio. Los desarrolladores podrán a partir de ahora utilizar el
SDK no solo para crear aplicaciones que extiendan a Visual Studio, sino además para distribuir herramientas y aplicaciones libres de royalties.
El modo aislado de VS 2008 Shell
El modo aislado de Visual Studio Shell ofrece
los fundamentos sobre los cuales los desarro-
lladores pueden crear sus propios entornos
integrados que funcionen en paralelo con
Visual Studio. Utilizar este modo permitirá
acelerar el desarrollo de herramientas de desarrollo propias, ya que será posible aprovechar
el núcleo del entorno integrado de Visual Studio y concentrarse en los problemas específicos de la herramienta en desarrollo.
propio. Cualquier herramienta o lenguaje que
se ejecute dentro de Visual Studio Shell en
modo integrado ejecutará conjuntamente con
Visual Studio 2008 (Estándar o superior) si éste
está instalado en la misma máquina. Utilizar
este modo hará posible que Visual Studio no
sea un prerrequisito en las máquinas de los usuarios que utilicen la herramienta o lenguaje.
El modo integrado de VS 2008 Shell
Novedades clave en el VS 2008 SDK
El modo integrado de Visual Studio Shell ofrece los fundamentos sobre los cuales los desarrolladores pueden integrar sus propias herramientas y lenguajes de programación dentro de
Visual Studio. El shell de modo integrado no
contiene ningún lenguaje de programación, por
lo que constituye la base perfecta para desplegar un entorno de desarrollo para un lenguaje
• Soporte de desarrollo para VS Shell.
• Mejoras en DSL Tools.
• Soporte de desarrollo y pruebas para
paquetes de extensión de Visual Studio en
C++, C# y Visual Basic.
• Nuevos ejemplos y documentación en
diversas áreas.
• Soporte para Windows Vista.
<<dotNetManía
Conjuntamente con la salida deVisual Studio 2008, Microsoft ha puesto a disposición de los usuarios
el SDK de Visual Studio 2008, así como los redistribuibles del nuevo Visual Studio 2008 Shell.
7
<< dnm.directo.noticias
Microsoft SQL Server 2008 CTP de noviembre
Cursos diciembre 2007
Microsoft anunció en el pasadoTechEd IT de Barcelona la nueva
CTP (Community Technical Preview) de noviembre de SQL
Server 2008, la penúltima antes de la versión RTM (Ready To
Manufacture).
Alhambra-Eidos lanza sus cursos
de diciembre
Esta edición de SQL Server 2008 trae
una cantidad significativa de nuevas
funcionalidades, incluyendo compatibilidad con Windows Vista y Windows Server 2008, así como nuevas
características como Resource Governor, Backup Compression y Transparent Data Encryption. Esta CTP también incluye nuevas mejoras en el área
de Business Intelligence tales como
Design Alerts, Block Computation,
Enhaced Report Designer con nuevas
visualizaciones e integración con 2007
Microsoft Office System.
Ésta también es la primera CTP que
ayuda a los clientes a cargar y consumir
cualquier tipo de datos, incluyendo el
nuevo tipo FileStream para documentos no estructurados, y que ofrece
soporte para el almacenamiento de datos
geoespaciales, que puedan ser utilizados por aplicaciones de localización en
el espacio.
Compañías como Barrodale Computing Services (BCS) Ltd., Environmental
Systems Research Institute Inc., I.S. Consulting Inc., Manifold y SpatialPoint han
anunciado su intención de sacar aplicaciones con el soporte de datos geoespaciales en SQL Server 2008.
Para recibir recursos de SQL Server
2008 específicamente seleccionados para
profesionales TI, vaya a http://go.microsoft.com/fwlink/?LinkID=103187 y para
desarrolladores, vaya a http://go.microsoft.com/fwlink/?LinkIsD=103186.
Puede probar también la versión CTP
de SQL Server 2008 Express Edition. Es
una edición de SQL Server 2008 gratuita y totalmente funcional. SQL Server
2008 Express soporta 1 CPU, 1 Gb de
RAM y bases de datos de hasta 4Gb.
Puede descargarse desde: http://www.
microsoft.com/downloads/details.aspx?FamilyId=3BF4C5CA-B905-4EBC-89011D4C1D1DA884&displaylang=en.
Alhambra-Eidos, empresa especializada en
facilitar soluciones a las necesidades empresariales en el ámbito de las Tecnologías de la
Información y las Comunicaciones, lanza para
diciembre su calendario de formación técnica dirigida a profesionales.
En formato blended, que combina la formación presencial tradicional con los avances
de la variedad online, Alhambra-Eidos ha programado las siguientes sesiones formativas para
el mes de noviembre:
Del 10 al 19 de diciembre de 2007
• Sharepoint Services y MOSS 2007
• Seguridad en redes Cisco
Del 11 al 20 de diciembre de 2007
• MCTS SQL 2005
Las horas presenciales se impartirán en las
aulas de:
Alhambra-Eidos
c/Albasanz, 16 (Madrid)
Para más información, contacte con
Alhambra-Eidos en el teléfono 902 313 505
o visite la Web: www.alhambra-eidos.es
<<dotNetManía
Feed your brain
8
Feed your brain (alimenta tu cerebro)
es la frase elegida como eslogan de una
nueva editorial: Krasis Press, que
recientemente presentó su nuevo proyecto especializado en tecnologías
Microsoft en la sede de Microsoft Ibérica, en Madrid, sumándose así a Netalia –editora de esta revista– en la edición de este tipo de contenidos.
Nacida hace siete años, Krasis es un
partner de Microsoft en desarrollo de
productos Web y formación. La editorial nace a raíz de una de sus áreas de
actividad, campusMVP, iniciativa en
formación online cuyo factor diferencial
es que todos los cursos son creados y
tutelados por MVP (Most Valuable Professional). MVP es un galardón que
Microsoft concede anualmente a los
profesionales más destacados de cada
país. Actualmente hay 12 MVP españoles integrados en este proyecto.
Krasis Press nace para paliar la falta de información sobre tecnologías muy
nuevas y el exceso en las más maduras,
y como alternativa a la poca variedad de
libros especializados.
Con distribución nacional, venta
directa a través de www.krasis.com y
www.dotnetmania.com y venta cruzada
con los cursos, Krasis está en negociaciones para la comercialización en
Lationoamérica y EEUU en castellano. La compañía prepara además traducciones al inglés para la venta en
EEUU a través de Amazon. En la
actualidad cuenta con tres obras en el
mercado: “Modelando procesos de
negocio con Workflow Foundation”,
de Unai Zorrilla Castro; “C# 3.0 y
LINQ”, de Octavio Hernández Leal
y “Programación Web con Visual Studio y ASP.NET 2.0”, de José Manuel
Alarcón Aguín.
Dirigidas a programadores, personas
interesadas en la tecnología, centros académicos o de formación y universidades, se
presentan en edición de lujo, en tapa dura
y con distintivas frutas en sus portadas,
que se corresponden con el lema de su
proyecto educativo: Feed your brain.
opinión
Rodrigo Corral
Documentos o ejecutables
Rodrigo Corral es MVP
y MCPD y uno de los
fundadores de Plain
Concepts, donde colabora como arquitecto
de software. Además
trabaja en Sisteplant
como líder técnico en
un proyecto desarrollado sobre .NET 3.0 utilizando Scrum como
metodología de desarrollo. También administra Geeks.ms. Además,
Rodrigo es tutor de
campusMVP. Su blog es
http://geeks.ms/blog/
rcorral.
La documentación siempre es
un aspecto que exige nuestra
atención en los proyectos de
software. A menudo
tendemos a pensar que la
mejor manera de lograr que
nuestros proyectos avancen y
poder mostrar ese avance es
realizando la documentación
adecuada, buscando el ciclo
adecuado para esa documentación y estableciendo una
serie de documentos como
estándares. Incluso hay metodologías bastante populares
que se centran en definir qué
documentos se deben
generar, quién es el responsable de cada documento y
por qué manos debe pasar
cada uno de ellos. ¿Nos olvidamos de que los documentos no se pueden ejecutar?
¿Nos olvidamos de que el
propósito final de todo
proceso de desarrollo es
conseguir software que
funciona?
<< A menudo, de la documentación que mantenemos durante el desarrollo solo un pequeño porcentaje tiene valor para el cliente. Es cierto que habitualmente hemos de entregar cierta documentación, manuales de operación, de administración o de usuario; esta documentación
tiene un claro valor. Este tipo de documentación se debe tratar como
cualquier otro entregable. En el fondo, ésta es la única documentación
que es realmente imprescindible, la que el destinatario del software
necesita, aquella por la que, hipotéticamente, estaría dispuesto a pagar.
Minimizar la documentación que no aporta nada a nuestros clientes,
que solo sirve para soportar nuestro proceso de desarrollo, y sobre
todo el coste de mantenerla, debe ser uno de nuestros objetivos.
El avance de los proyectos de software es algo que siempre ha preocupado a todos los implicados en los mismos. Es algo sobre los que nuestros clientes centran su interés y algo que, como gestores de proyectos,
necesitamos comunicar. Tradicionalmente hemos abordado esta necesidad de mostrar el progreso mediante el uso de diferentes documentos o
artefactos. Todos los que hemos tenido que mantener actualizado “el project” del proyecto sabemos lo difícil que esto es. Es tan difícil, que rara vez
se hace con la disciplina que requiere, de tal modo que habitualmente este
tipo de aproximación no proporciona los resultados esperados.
El enfoque tradicional de mostrar el avance de los proyectos mediante documentos es algo que no funciona bien. Nuestros clientes han descubierto que los documentos rara vez nos muestran el avance real de un
proyecto. Es muy posible haber trabajado mucho y tener una gran cantidad de documentación sobre un proyecto y estar a años luz de que quien
financia el proyecto pueda obtener valor. ¿Quién no conoce algún proyecto en el que tras muchos meses de desarrollo lo único que había es un
montón de documentos? Los documentos por sí mismos no aportan ningún
retorno de la inversión. No se puede hacer nada para obtener valor
para tu negocio solamente con la documentación relacionada con un
proyecto de software. Solo el software que pueden ejecutar y utilizar es susceptible de crear valor para nuestros clientes. Solo el software que funciona debe ser la medida del progreso de los proyectos
de desarrollo. Asumir esto nos obliga a asumir que tendremos que entre-
<< dnm.opinión
gar software con frecuencia a nuestros clientes,
que tendremos que reaccionar de manera ágil al
feedback que nos proporcionen y que a cambio ellos
obtendrán de manera temprana un retorno para
su inversión.
Debemos ser muy tacaños con el esfuerzo que
ponemos en nuestra documentación; si no, corremos el riesgo de ver que todos aquellos requisitos, por poner un ejemplo, que tan detalladamente
documentamos sobre el sistema de gestión que
nuestro cliente quiere, son papel mojado porque
han comprado una nueva unidad de negocios. Y
nosotros ya hemos hecho un gasto del que difícilmente obtendremos algún retorno. La documentación en los proyectos de software pierde su relevancia y
se queda obsoleta muy rápidamente, haciendo que mantenerla actualizada sea muy costoso. A menudo cometemos el error
de tratar de sustituir la comunicación fluida por documentación, y cuando hacemos esto, estamos introduciendo costes e
inflexibilidades en nuestro proceso de desarrollo.
Otro aspecto del desarrollo de software que nos lleva a
generar documentación es la necesidad de mantener los sistemas que desarrollamos. Se suele pensar que la documentación
detallada del sistema nos va a evitar un montón de quebraderos de cabeza. Pero esto solo es cierto si esa documentación
cumple la premisa de estar actualizada. Cuando un desarrollador encuentra una línea en la documentación que no es
correcta o no está actualizada, rápidamente pierde la confianza y vuelve su vista a la única fuente de verdad absoluta: el código fuente. Esto nos lleva a la situación de que solo la documentación que se genera directamente desde el código fuente de manera automatizada tiene verdadero valor.
El código es la única fuente de verdad absoluta sobre un
proyecto de software a nivel de detalle, y el nivel de detalle es
el único útil para modificar, extender o mantener un sistema en
producción. La documentación directamente asociada al código fuente o embebida en él (comentarios que permitan generar documentación, por ejemplo, con NDoc, JDoc o similares) o aquella que se genera de manera automática desde el mismo (por ejemplo, diagramas de clases que solo son otra vista
del código) es la que más valor tiene, pues evoluciona y se mantiene en paralelo al código fuente y siempre está actualizada.
Otra documentación que no está directamente relacionada con el código fuente y que es de gran utilidad, si no imprescindible, es la relativa a arquitectura. Es necesario que un nuevo desarrollador o aquel que resucita el proyecto tras un tiempo puedan comprender qué decisiones de alto nivel guiaron
el desarrollo. Esta documentación sirve para comprender por
qué se tomaron determinadas decisiones que no se cambian
con facilidad a lo largo del proyecto y proporciona una primera aproximación de alto nivel. La arquitectura de una aplicación no suele cambiar a menudo; lo que cambia más frecuentemente es la implementación, el código. Esta documentación es simple de mantener, porque es mucho más estática
que la de diseño detallado.
A menudo nos centramos en documentar olvidando que
la principal fuente de información sobre qué hace una pieza
de software está en el nombre de los componentes, de las clases y de las funciones. La principal documentación con la
que contamos es el estilo de nomenclatura, la coherencia
a la hora de nombrar cosas y una arquitectura general
coherente. Establecer un lenguaje común, la nomenclatura y el estilo que va a guiar del desarrollo es más valioso que cualquier documentación. Mucha documentación
puede emanar de una serie de patrones que se repiten a lo largo del proyecto, tanto a nivel arquitectónico como de diseño,
y estos patrones donde viven es en el código.
Buscando valor para el cliente, cada vez más proyectos
deciden mantener una base de conocimiento sobre nuestro
proyecto, basada en artículos cortos y con ejemplos, tipo
knowledge base, sobre los que se pueda realizar búsquedas
fácilmente. Por eso se están popularizando tanto como repositorios de información sobre proyectos los wikis: no imponen una estructura, son ágiles de mantener, fácilmente actualizables, fácilmente buscables y soportan muchos tipos diferentes de contenido.
También se tiende cada vez más a sustituir la documentación por la refactorización: si una pieza de software
es compleja, tenemos dos posibles estrategias a la hora de
hacerla entendible. La primera es documentarla; la segunda es, a base de refactorización y de mejorar el diseño, simplificarla para hacerla más clara. Se puede ganar mucho en
la legibilidad de nuestro software simplemente eligiendo
buenos nombres, evitando las funciones enormes, limpiando las variables no utilizadas… La ventaja de este enfoque
es que mejora objetivamente el software, haciéndolo más
mantenible y más claro, sin necesidad de un artefacto externo que puede fácilmente quedar desactualizado.
Antes de escribir cualquier documentación debemos
preguntarnos varias cosas: ¿Es realmente imprescindible?
¿Será fácil de mantener? ¿Aporta algún valor claro para
nuestro cliente?
El manifiesto ágil resume lo aquí expuesto de la siguiente manera: “El software que funciona es más importante que
la documentación exhaustiva”. El desarrollo de software va
sobre código fuente y ejecutables, no sobre documentos.
<<dotNetManía
Solo el software que pueden ejecutar y utilizar
es susceptible de crear valor para nuestros clientes.
Solo el software que funciona debe ser la medida del
progreso de los proyectos de desarrollo
11
entrevista
Marino Posadas
entrevista a
Marino Posadas
es director de tecnologías de desarrollo para España
y Portugal de Solid
Quality Learning.
Puedes leer su blog
en http://www.
elavefenix.net.
Catherine Heller
Catherine Heller es española (nacida en Madrid)
de padre norteamericano, y con muchos años
de estancia en los dos países. En la actualidad,
trabaja como evangelista de Windows Live, en
Redmond, y anteriormente, de Visual Studio
Tools for Office. Eso fue después de pasar en
Microsoft Ibérica otra buena parte de su
carrera…
Cuéntanos tu trayectoria anterior en
Microsoft Ibérica y –para los que ya
te conocemos y te vimos marchar-,
qué haces ahora en EE.UU.
Yo empecé en Microsoft, en España,
en el año 2000, como Aplication Development Consultant, y trabajaba con los
ISV en España y les ayudaba a crear su
planificación y arquitectura usando tecnologías de Microsoft. En el 2003 me
salió la oportunidad de ir como Technical Evangelist a un grupo en Microsoft Corporation en Redmond. Mi primer TechEd aquí en Barcelona fue justo antes de trasladarme a Redmond.
<< dnm.directo.entrevista
He seguido todo este tiempo como
evangelista, pero cambiando entre productos. Me pasé dos años enfocada en
Whidbey (concretamente en el área de
Visual Studio Tools for Office), lo que
fue muy interesante, porque anteriormente había sido especialista en servicios Web, en middle tier, en remoting,
COM+…
Especialmente sabiendo que vienes de un background de C++…
Sí, había sido desarrolladora de C++
10 años antes de venir a Microsoft…
Fue muy interesante ver el desarrollo
¿qué resumen das a los lectores de
la revista de cara a aprovechar ese
potencial?
En el TechEd de noviembre del año
pasado di una charla sobre Windows Vista y las áreas en las que yo me centré,
sobre todo Desktop Search. Hay una
manera muy sencilla de poder incorporar búsquedas utilizando el índice del
desktop, utilizando OLE DB Provider for
Windows Search, y eso se utiliza muy
fácilmente desde ADO.NET y está bien
documentado. Es un proveedor algo
especial, dado que es de solo lectura.
mentar interfaces COM. Pero es factible, y también me dediqué a ayudar a
los ISV en ese aspecto.
También me centré en cosas como
ayudar a los desarrolladores a conocer el
impacto de User Account Control (UAC)
sobre sus aplicaciones, porque es una pena
ver cuántos lo deshabilitan cuando es un
mecanismo muy importante para el usuario. Y realmente tampoco es tan complicado tener una aplicación que funcione
bien con UAC. Es más bien conocer un
poco el manifiesto que hay que embeber
y resulta sencillo.
desde el punto de vista del desarrollador de Office y la posibilidad de escribir código para Office desde .NET en
C# y Visual Basic. Con Visual Studio
2005 en el mercado, me cambié a Windows Vista. En esa época todo el mundo hablaba de Indigo y Avalon, pero yo
me puse a mirar las API nativas, que
realmente es lo que venía como parte
del sistema operativo. Fue un año y
medio interesante, volviendo a mis orígenes de C++ y COM, pero también
analizando cómo se podían aprovechar
esas API nativas desde .NET, y los retos
para acceder a ellas. Ya en enero, cuando lanzamos Windows Vista, me cambié a un mundo totalmente diferente,
como es Windows Live.
Respecto a ese año y medio de
análisis de las API nativas de Vista,
Pero hay toda una infraestructura para
quienes quieran integrar sus datos dentro del índice, algo más complicada, ya
que hablamos de tener que implementar interfaces COM desde C++.
Pero el 99,9% de las veces lo que
necesitas es leer, no escribir…
Sí, leer es muy fácil. Cuando es más
complicado y se requiere un nivel técnico mayor es, por ejemplo, cuando
tenemos un formato de archivo propio
y queremos indexar su contenido, o si
queremos que el contenido del archivo
o de ese tipo de archivos se integren en
la experiencia visual del explorador. Por
ejemplo, los Live Icons: ver la imagen
allí, o poderla ver en la vista de presentación preliminar, o poder permitir
que el usuario le asigne propiedades al
archivo… todo esto requiere imple-
Y de ahí pasaste a Windows Live
y su parte programática…
La primera cosa importante a
entender sobre Windows Live es que
es una oferta para el consumidor, no
tanto para la empresa, salvo si ésta quiere integrarlo en sus portales Web dirigidos a usuarios finales. Gran parte de
la oferta hoy sí va dirigida al usuario
final. Estamos empezando a evolucionar hacia una plataforma, y tenemos
una serie de ofertas para el desarrollador que, si bien no abarcan todavía el
abanico de ofertas para el usuario final,
son muy interesantes.
Uno de los nuevos servicios que
sacamos en versión alfa en abril se llama Silverlight Streaming by Windows Live. Es interesante porque es
un servicio que hemos introducido
<<dotNetManía
Catherine Heller junto a Marino Posadas
13
<<dotNetManía
<< dnm.directo.entrevista
14
directamente a nivel de plataforma, no
hay una oferta correspondiente para el
usuario final. Se entiende que esto va
dirigido al desarrollador. Es un servicio que complementa las aplicaciones
Silverlight. Cuando vayamos creando
aplicaciones Silverlight que sean muy
ricas en elementos multimedia, que tengan vídeo, que tengan fotos, imágenes,
esas aplicaciones podrán hacer uso del
servicio de Silverlight Streaming.
O sea, lo que es ahora la oferta
de Silverlight 1.0, porque en la 1.1
cambian muchas cosas…
Sí, pero esto vale tanto para Silverlight 1.0 como para 1.1, porque no afecta directamente esa API de programación sino que se crea un paquete, se
incluyen todos los archivos de la aplicación, se crea un ZIP y se publica, o
se sube ese paquete al servicio. Una vez
allí, lo que se hace es proporcionar una
experiencia de reproducción en una
página Web, con la ventaja que esa aplicación se distribuye a lo largo de toda
nuestra red de entrega de contenido
(CDN, Content Delivery Network). Con
esto, los elementos pesados están en el
límite más cercano al usuario y no necesariamente en servidores centrales que
pueden estar ubicados muy lejos.
Además, tareas como el streaming de
vídeo suelen requerir muchos recursos
de hardware. Todo este trabajo duro lo
hace el propio servicio. Y es una oferta muy interesante porque damos hasta 4Gb de espacio totalmente gratuito,
y hasta que la versión definitiva del servicio salga a la luz (mientras estemos en
alfa y beta), no hay ningún tipo de límite en el uso que se haga de él, es totalmente gratuito. Una vez que lo pongamos en producción pues sí se cobrará,
pero solo a partir de un millón de minutos de streaming al mes. Tenemos el
umbral muy alto, muy generoso…
Para evitar excesos, simplemente, pero para que los usuarios “normales” puedan usarlo sin pagar…
Bueno, esto refleja el objetivo que
tenemos con los términos de uso en
general para los servicios de Silver-
light de plataforma. Queremos definir unos umbrales de uso muy generosos y permitir que por debajo de ese
umbral el uso sea gratuito. Y en algún
momento financiaremos eso a través
de anuncios. Luego queremos también ofrecer un modelo para que por
encima de ese umbral se pueda pagar,
bien por usuario, o por transacción,
o por minuto, dependiendo del servicio o por algún tipo de compartición de ingresos por anuncios; esa es
la idea que tenemos detrás de estos
servicios.
También estamos haciendo una
apuesta muy importante respecto a las
fotografías almacenadas en Windows
Live Spaces. Ahora mismo hay 4 mil
millones de fotografías almacenadas.
Baste pensar que los usuarios –de
media– suben unos 8 millones de fotografías todos los días en todo el mundo. Vemos dónde se está haciendo un
uso muy importante de Spaces: publicar y compartir fotografías. Lo bueno
que tiene Spaces es que se puede crear un space y limitar a que solo tu familia, tus amigos o quien tú decidas acceda a él. Estamos invirtiendo mucho
para hacer que Spaces sea un sitio idóneo para guardar fotografías, para crear experiencias de usuario como Windows Live Photo Gallery, que acabamos de sacar y que tiene una experiencia rica en el cliente para manipu-
lar, personalizar tus fotos, etc. y desde
allí subirlas directamente a tu space.
Una vez en el space, el desarrollador
puede integrar esas fotografías o experiencias que los usuarios ya han subido a su space, pues hay muchos tipos
de experiencias que incorporan esas
fotografías de manera muy interesante. Allí estamos potenciando maneras
fáciles de acceso, como puede ser con
un control Javascript que pongas en
una página y permita al usuario seleccionar fotos o feeds RSS, o una API que
permite subir fotos, borrarlas, etc.
Queremos extender la experiencia de
esas fotografías a otros sitios Web, a
otras aplicaciones.
Bueno, para finalizar, para el que
quiera programar alguna cosa con
Windows Live ¿cuáles serían los primeros pasos a dar?
Lo primero, desde luego, es ir al
sitio Web, que es http://dev.live.com.
Ese es el sitio para toda la información relacionada con el desarrollo utilizando los servicios de Windows Live.
Allí se enlaza a la documentación
MSDN y se ofrecen aplicaciones (las
Quick Applications) que demuestran
cómo combinar varios servicios. En
CodePlex está el código fuente disponible y se puede participar en esa
comunidad para extender esas aplicaciones, y hay muchas más ofertas para
desarrolladores.
Cuando tomamos decisiones,
necesitamos información; esa
información nos ayuda a gestionar mejor los procesos de
nuestras organizaciones y a ser
más competitivos, dándonos
mejores posibilidades de supervivencia en el corto, medio y
largo plazo. Aproximadamente
el noventa por ciento de la
información que necesitamos
está dentro de nuestra propia
organización, pero por desgracia la dispersión de la información (múltiples fuentes de
datos, múltiples formatos, calidad del dato mostrado, etc.)
hace que solo el treinta por
ciento esté accesible en el formato y en el tiempo adecuado;
el resto son datos por tratar o
información no estructurada...
si no lo tienes claro...
GR
d
La revista de la
Gestión del Rendimiento
La revista para la Gestión del Rendimiento
www.gestiondelrendimiento.com
eventos
Marino Posadas
TechEd 2007: expectación
ante un año pleno de novedades
<<
Quien más quien menos tenía la idea de que la
recién concluida edición del TechEd 2007 en Barcelona iba a ser la antesala de las innovaciones que
se esperan para el 2008: Windows Server 2008,
Visual Studio 2008 (cuya disponibilidad final se
anunció durante el evento), SQL Server 2008, Silverlight, etc. Y así fue. Tuvimos ocasión de asistir
a excelentes sesiones (las hubo de todas clases), abrir
los ojos a nuevas tecnologías y como siempre, compartir con una comunidad cada vez más activa.
mantener, como clave del éxito de la compañía.
A partir de ahí, la marabunta… ¡hasta 15
sesiones simultáneas! Siendo grande el foro que
alojó el evento, se tuvieron que habilitar dos
zonas exteriores cubiertas para dar cabida a la
gran cantidad de ponentes que se dieron cita este
año. Y además de las sesiones estándar, estaban
las interactivas (en las que el usuario puede interrumpir al ponente con sus preguntas desde el
principio), que en esta edición tuvieron más éxi-
Somasegar, durante la keynote
Marino Posadas
es director de tecnologías de desarrollo para España y
Portugal de Solid
Quality Learning.
Puedes leer su blog
en http://www.
elavefenix.net.
Fue Soma Somasegar (vicepresidente corporativo de la División de Desarrollo) el encargado
este año de abrir las sesiones con una keynote en
la que fue introduciendo la mayor parte de las
novedades que se espera vayan apareciendo desde ahora hasta finales de 2008 (o hasta el siguiente TechEd, que repetirá ubicación en Barcelona).
Ayudado por Tony Goodhew y Dan Fernandez
en las presentaciones, fue desglosando uno a uno
los elementos clave de cada producto y presentando un ecosistema cada vez más integrado, más
colaborador con su entorno, más fácil de usar: el
mantra habitual que oímos en muchas presentaciones y que Gates trata por todos los medios de
to que nunca. Se presenta un tema (normalmente el mismo que el ponente ha expuesto en una
sesión estándar), y se debate en profundidad discutiendo y aportando cada espectador sus miedos o experiencias en la implementación. En la
foto adjunta, vemos a Francisco González de
Solid Quality Mentors, único ponente español
junto a Catherine Heller, atender al público al
final de su sesión interactiva.
Afortunadamente, los asistentes al evento recibiremos un “post-conference DVD” con todo el
contenido de las ponencias grabado en vídeo junto a las presentaciones PowerPoint y código fuente. Por suerte, otra novedad de este TechEd con-
<< dnm.directo.eventos
Francisco González, único ponente de una compañía
española (Solid Quality Mentors)
sistió en que desde la semana posterior al evento no tenemos que esperar
la llegada del DVD para ver las sesiones que nos perdimos, ya que pueden
verse online desde la página Web de
TechEd Europa (http://www.mseventseurope.com/TechEd/Developers).
Pero había muchas otras formas de
colaboración: la sección Ask The Experts
contaba con mucha más presencia (el
público votó masivamente a favor de esta
iniciativa), se habilitaron –como siempre– zonas wireless (Delegate Work Area
y Communications Network) donde el
personal podía atender sus urgencias corporativas, y la zona de Exhibitors estaba como siempre, llena de curiosos por
ver las ofertas de compañías de terceros,
que este año contaban incluso con una
tienda de ropa con distintos logos de
productos Microsoft.
¿Falta uno? Sí. Falta mencionar la
que fue –quizás– mi entrevista favorita
de este año, con Don Syme, de Microsoft Research (Cambridge), arquitecto
principal del lenguaje funcional F#, que
se incorpora de pleno derecho a la familia de lenguajes soportados por Visual
Studio en la siguiente versión, y que ofrece unas características para el cálculo
matemático como no habíamos visto hasta ahora. Don es un tipo muy accesible,
y nos estuvo enseñando in situ, con su
propio portátil, algunas de las carac-
Don Syme nos explica -en su demo de F#– la potencia del lenguaje
en cálculo matricial
tecto de SQL Server 2000/2005, que
dio un auténtico espectáculo en sus presentaciones sobre filosofía del software), o Jesse Liberty, quien, recientemente fichado por la compañía, se ha
convertido en el alma evangelizadora de Silverlight en Redmond. También estuvimos con otros evangelistas, como la española (de padre norteamericano) Catherine Heller, que
dedica sus esfuerzos actuales a la
divulgación de Windows Live, Joe
Marini, Program Manager del equipo de extensibilidad de Visual Studio,
Dan Fernandez, Lead Product
Manager de herramientas como
PopFly o Visual Studio Express y jefe
de Arturo Toledo, otro de nuestros
entrevistados (ver dotNetManía nº
40) y Damir Tomicic, Presidente de
INETA Group Europe.
terísticas más sobresalientes de este nuevo miembro de la familia .NET.
Iremos publicando estas entrevistas
en los próximos números de la revista.
También hubo lugar para el esparcimiento, tanto en la zona XBox como
después de las jornadas, con cenas para
la comunidad MVP española, dirigida
por Cristina González Herrero, para
las comunidades nacionales por países,
y para certificados Microsoft, donde
hizo de anfitriona Karen Young,
EMEA MVP Regional Manager.
Un TechEd, en suma, más intimista
(sin la super-fiesta final del jueves), más
centrado en el trabajo, con un altísimo
nivel de sesiones, y donde pudimos contactar más directamente que nunca con
aquellos que están haciendo y presentando el software que todos queremos utilizar en el inmediato futuro.
<<dotNetManía
Hall principal de expositores y zonas comunes
Hubo muchos conferenciantes distinguidos,
pero lo mejor es que tuvimos oportunidad de entrevistar a 8 de ellos para dotNetManía. Hablamos con
auténticos clásicos de la tecnología Microsoft, como
Ted Pattison (Presidente
de Ted Pattison Group y
conocido autor del mundo
COM), Pat Helland
(coautor de MTS y arqui-
17
<< dnm.directo.eventos
<<dotNetManía
Lanzamiento de Biztalk
18
La verdad es que desde el principio la
cosa prometía. Pónganse en situación:
Museo Thyssen de Madrid, un evento
de todo un día dedicado exclusivamente a Biztalk, un montón de buenas referencias de implantaciones Biztalk verticalizadas en 3 grupos (banca y seguros, industria y sector público), charlas
técnicas focalizadas en las novedades de
esta revisión de Biztalk, raona como
Partner Platinum presentando un caso
de éxito implantado en Catalana Occidente y una difusión del evento a la base
de datos de Microsoft, formada por
unos 6000 contactos.
La primera de las ponencias que
figuraban en la agenda tras la bienvenida a los asistentes por parte de Fernando Bocigas, responsable del producto en España, corría a cargo de
Fernando García, director de Ventas
de Soluciones de Aplicación en Microsoft, que bajo el título “Seis tendencias tecnológicas que marcarán la próxima década” contextualizó de manera general el estado actual de la tecnología, y auguró los principales retos
a los que tendremos que hacer frente
en un futuro inmediato como responsables de IT y como usuarios que conviven en el día a día con la información. La verdad es que aquí, como en
otros ámbitos, Microsoft marca tendencias, así que no es arriesgado aventurar que darán en el clavo y que, efectivamente, la evolución lógica que se
nos presentó (¿les suena “mundo interconectado”?) será acertada.
Tras Fernando García, de nuevo fue
el turno de Fernando Bocigas, con una
ponencia llamada “Extendiendo el negocio conectado”, en la que se hizo un repaso de cuál ha sido la evolución del producto desde sus orígenes (cómo han cam-
2006 R2
biado las cosas, afortunadamente, desde
aquel Biztalk 2000 “intratable”) hasta la
actual versión 2006 R2. Sorprende ver
cómo progresivamente se va ganando la
aceptación de las compañías, pasando de
500 clientes en la primera versión hasta
aproximadamente 7000 con la, hasta la
fecha, última versión con datos fiables,
Biztalk 2006. En este caso, Microsoft fue
prudente y se reservó el dar una fecha estimada de la previsión de calado de R2 para
cuando alcance la etapa de madurez, aunque nada hace indicar que la tendencia al
alza se frene.
Biztalk como integrador de una cadena de fabricación de componentes
para el interior del automóvil; una
implantación en un centro de salud
para la comunicación de diferentes
áreas y departamentos; un caso real
de utilización del adaptador SWIFT
para transacciones seguras dentro del
entorno de banca… El caso de éxito
por el que raona fue invitado al evento consistía en la comunicación de la
compañía de seguros Catalana Occidente con el Ministerio de Justicia con
la finalidad de hacerle llegar datos
Las exposiciones no defraudaron y nos mostraron
Biztalk como una realidad que funciona y que
goza de un merecido respeto en las compañías
en las que ha sido implantado
Y, por fin, el plato fuerte del día:
casos de éxito de implantaciones reales de Biztalk 2006. Los hubo para
cada una de las verticales que, por parte de Microsoft, acudían al evento:
industria, sector público y bancaseguros. Por este orden, los diferentes partners que acudieron al evento
fueron exponiendo sus desarrollos,
presentando 2 casos de éxito para cada
vertical. Pudimos ver un sinfín de
problemáticas diferentes con un
denominador común: Biztalk. Entre
los casos destacados se mostraron un
requeridos de las pólizas de vida, en
virtud de la ley 20/2005 sobre la creación del Registro de Contratos de
Seguros de Cobertura de Fallecimiento.
La verdad es que las exposiciones
no defraudaron y nos mostraron Biztalk como una realidad que funciona
y que goza de un merecido respeto en
las compañías en las que ha sido
implantado. Déjenme hacerles una
confesión: en los numerosos años que
llevo haciendo implantaciones de Biztalk, jamás me he encontrado con un
<< dnm.directo.eventos
cliente que se haya sentido defraudado por el resultado final, ni en cuanto a expectativas de rendimiento ni en cuanto a capacidad de integración.
Llegó el momento de recobrar fuerzas con el
cóctel programado para afrontar la recta final del
evento con las energías renovadas. Respecto a lo
acontecido por la tarde, poco tenemos que comentar: tres diferentes charlas, eminentemente técnicas, en las que sin grandes pretensiones se nos
detalló el funcionamiento de los adaptadores RFID
y EDI mejorados para esta última versión, y una
última charla que cerraba el día y que rezaba algo
así como “Extendiendo SOA desde la Empresa al
Mundo” (previsible, muy previsible…).
Y esto fue todo. Al final, menos asistencia de la
prevista: 75 participantes entre partners, clientes e
invitados. Una impecable organización, en la que
los tiempos se cumplieron rigurosamente, y un
buen sabor de boca respecto a los incrementales
esfuerzos por parte de Microsoft por situar Biztalk
en el lugar que le corresponde como herramienta
de integración de primer nivel.
Suriel Hilario
Project Manager de Raona
CEUS 2007
El pasado 30 de octubre, cerca de 320 personas asistieron a la tercera edición de CEUS 2007, la III Conferencia de Usuarios de SharePoint, en Madrid. Esta
edición sirve para consolidar dichas conferencias entre
la comunidad y confirma el éxito de la plataforma de
moda de Microsoft. Prueba de ello fue el número de
asistentes, que superó al del año pasado, confirmando el interés de la plataforma SharePoint. El día se
dividió en dos formatos totalmente diferentes de presentaciones.
La mañana estuvo presidida por presentaciones de
empresas usuarias de SharePoint, que junto al cliente
final, nos mostraron casos de éxito con SharePoint; en
la presentación daban a conocer a todo el aforo su experiencia, implementación y sensaciones con el producto. Entre estas empresas se encontraban raona junto a
su cliente Criteria Caixa Corp, Getronics con Ancert
y K2, Renacimiento con el Ministerio de Presidencia
e Informática el Corte Inglés con Caja Mediterráneo.
Todas estas presentaciones fueron de carácter práctico,
con la puesta en marcha del proyecto y las peculiaridades de cada uno. Enmedio, y después del descanso, intervinieron distintos responsables de Microsoft, que nos
dieron algunos detalles del futuro de SharePoint, enfocado en las búsquedas, lo que anuncia la salida del nuevo SharePoint Search Server. Por parte de Microsoft,
contamos con la presencia de Rafael Sánchez, jefe de
producto de SharePoint, y con Sarah Hammon, responsable de producto SharePoint en Europa.
Las sesiones de la tarde, en cambio, fueron sesiones mucho más técnicas, más enfocadas hacia un
tema específico. Se contó con un total de siete salas,
y en cada una de ellas tuvieron lugar tres presentaciones de unos 55 minutos cada una. Con este formato de presentaciones y con la disponibilidad de
salas, los asistentes se dividieron entre las sesiones
más interesantes para cada uno de ellos. Se trataton temas muy diversos, desde migraciones de SharePoint 2003 y CMS 2001 a SharePoint 2007, hasta integraciones de BI, Microsoft Dynamics, Business Data Catalog, workflows con SharePoint Designer y definición de arquitecturas de alta disponibilidad. Los ponentes de estas presentaciones pertenecían a las distintas empresas patrocinadoras del
evento y otros voluntarios, así como personal de
Microsoft. Todas las presentaciones estarán disponibles públicamente en breve para las personas que
no puedieron asistir al evento.
Entre las novedades, la nueva versión de Microsoft Search Server 2008. Esta versión del nuevo buscador para SharePoint ya se encuentra liberada en su
versión release candidate para que cualquiera de los
usuarios pueda descargarla y probarla.
Sergio Holgado
Software Engineer de Raona
plataforma.net
Javier Roldán
Tablet PC SDK (y II)
Reconocimiento de escritura manual
En la primera parte de este artículo indicamos el modo de preparar el
entorno de desarrollo necesario para la programación de aplicaciones
capaces de aceptar tinta digital para más tarde reconocerla como escritura manuscrita.Asimismo, utilizamos los principales elementos que para
este fin proporciona el Microsoft Windows XP Tablet PC Edition Software Development Kit.
Fco. Javier Roldán
Huecas
es ingeniero superior
informático. Con una
experiencia laboral de
ocho años como profesional del sector de
las TI, en la actualidad
trabaja como ingeniero de sistemas y responsable de proyectos
en una importante
empresa industrial de
ámbito nacional.
[email protected]
Estos elementos, flexibles y de sencilla incorporación a nuestros proyectos, eran el control InkEdit y el control InkPicture. El primero permitía la
captura de trazos de tinta digital y su reconocimiento de manera automática, todo ello sin escribir una sola línea de código. Por otro lado, el control InkPicture permitía la captura automática de
trazos de tinta digital; sin embargo, para el reconocimiento de los trazos como escritura era necesario un poco de programación.
En el presente artículo iremos más allá y estudiaremos la manera de hacer que cualquier control
(como por ejemplo un Panel, un RichTextBox o un
ListBox, por solo poner unos ejemplos) sea capaz de
aceptar trazos de tinta digital y reconocerlos como
escritura manual. Asimismo, veremos los principales métodos existentes para mejorar la efectividad del
reconocimiento, tales como el uso de los factoids (cadenas predefinidas que proporcionan al reconocedor
información sobre el tipo de texto a reconocer) y
wordlists (listas predefinidas de palabras).
Para finalizar, analizaremos el uso de lo que se
conoce como gestures, gestos especiales no reconocidos como palabras y que permiten la ejecución de acciones a medida.
damos. Al igual que el control InkPicture, la clase InkOverlay no proporciona por defecto métodos automáticos para el reconocimiento de la escritura manual; sin embargo, del mismo modo podremos suplir esta ausencia mediante la clase Recognizers y un poco de programación.
Pasemos por tanto a ver cómo usar la clase
InkOverlay. Para ello, crearemos un nuevo formulario a imagen y semejanza del formulario usado en la primera parte de este artículo, con la diferencia de que sustituiremos el control InkPicture
por un simple Panel. Para aquellos que no hayan
podido leer esa primera parte, el formulario se
compone básicamente de un control Panel sobre
el que escribiremos trazos de tinta digital, un TextBox en el que mostraremos el resultado de inten-
La clase InkOverlay
La clase InkOverlay nos permite añadir características de tinta digital a cualquier control que deci-
Figura 1. Formulario InkOverlay.
<< dnm.plataforma.net
this.inkOverlay = new
InkOverlay(this.panelEscritura);
this.inkOverlay.Enabled = true;
Como podemos observar, en la primera línea de código simplemente creamos una instancia de la clase InkOverlay, a la que le pasamos en el constructor el control con el que queremos asociarlo. En la segunda línea activamos
dicha instancia.
Si ejecutamos la aplicación de nuevo, observaremos que hemos convertido el Panel en un control capaz de
recibir trazos de tinta digital; pero que
(al igual que ocurría con el control
InkPicture) éste no es capaz de reconocerlos como texto de manera
automática. Utilizando el mismo código que el usado en el artículo anterior
para el control InkPicture, pero sustituyendo la referencia a la clase InkPicture por la clase InkOverlay, haremos
posible que el texto manuscrito sobre
el control Panel sea reconocido y mos-
trado en el cuadro de texto. Del mismo
modo, podremos borrar, seleccionar, escalar y mover cada trazo dibujado con solo
using
using
using
using
using
using
using
using
añadir el código necesario a los botones
de la interfaz de usuario. Puede verse el
código completo en el listado 1.
System;
System.Collections.Generic;
System.ComponentModel;
System.Data;
System.Drawing;
System.Text;
System.Windows.Forms;
Microsoft.Ink;
namespace InkOverlayTest
{
public partial class FormInkOverlay : Form
{
private InkOverlay inkOverlay;
public FormInkOverlay()
{
InitializeComponent();
}
private void FormInkOverlay_Load(object sender, EventArgs e)
{
this.inkOverlay = new InkOverlay(this.panelEscritura);
this.inkOverlay.Enabled = true;
}
private void buttonEscribir_Click(object sender, EventArgs e)
{
this.inkOverlay.EditingMode = InkOverlayEditingMode.Ink;
}
private void buttonBorrarTrazo_Click(object sender, EventArgs e)
{
this.inkOverlay.EraserMode = InkOverlayEraserMode.StrokeErase;
this.inkOverlay.EditingMode = InkOverlayEditingMode.Delete;
}
private void buttonBorrarPunto_Click(object sender, EventArgs e)
{
this.inkOverlay.EraserMode = InkOverlayEraserMode.PointErase;
this.inkOverlay.EditingMode = InkOverlayEditingMode.Delete;
}
private void buttonSeleccionar_Click(object sender, EventArgs e)
{
this.inkOverlay.EditingMode = InkOverlayEditingMode.Select;
}
private void buttonReconocimiento_Click(object sender, EventArgs e)
{
Recognizers reconocedores = new Recognizers();
if (reconocedores.Count != 0)
{
Recognizer reconocedor = reconocedores.GetDefaultRecognizer();
RecognizerContext contextoReconocedor =
reconocedor.CreateRecognizerContext();
<<dotNetManía
tar reconocer los trazos como texto y
una serie de cuatro botones que nos
permitirán escribir trazos, modificarlos
y borrarlos. Por último, dispondremos
de un botón que lanzará el evento de
reconocimiento de escritura. Puede verse como queda dicho formulario en la
figura 1.
Si ejecutamos la aplicación e intentamos realizar algunos trazos sobre el
Panel, veremos que (como era de esperar) nada sucede. Esto es debido a que
el control Panel, al contrario de lo que
ocurría con el control InkEdit o InkPicture, no espera que sobre él se dibujen trazos de tinta digital, por lo que
detecta los eventos del ratón (o puntero) como simples eventos de pulsación
y arrastre.
La solución pasa por “superponer”
sobre el control Panel (o cualquier otro
sobre el que queramos escribir) un control que es capaz de capturar y mostrar
trazos de tinta digital. Dicho control se
implementa a través de la clase InkOverlay. Para ello, añadimos el siguiente código al evento Load del formulario:
21
<< dnm.plataforma.net
RecognitionResult resultadoReconocedor;
RecognitionStatus estatusReconocimiento;
contextoReconocedor.Strokes = inkOverlay.Ink.Strokes;
if (contextoReconocedor.Strokes.Count > 0)
{
resultadoReconocedor =
contextoReconocedor.Recognize(out estatusReconocimiento);
if (estatusReconocimiento == RecognitionStatus.NoError &&
resultadoReconocedor != null)
{
String resultado = resultadoReconocedor.TopString;
if (resultado != null && resultado.Length > 0)
{
this.textBoxTextoReconocido.Text = resultado;
}
}
}
}
else
{
MessageBox.Show(“No existen reconocedores instalados”);
}
}
Figura 2. Reconocimiento sin factoids.
to_Click, justo tras la línea donde creamos el RecognizerContext:
contextoReconocedor.Factoid =
Factoid.Number;
O bien esta otra línea, totalmente
equivalente a la anterior:
}
contextoReconocedor.Factoid =
“NUMBER”;
}
<<dotNetManía
Listado 1. Código de reconocimiento de escritura con InkOverlay.
22
Mejorando el
reconocimiento
varias herramientas, entre las que se
encuentran los factoids y las wordlists.
A estas alturas, si ha seguido de manera práctica el artículo, con total seguridad ya habrá probado la sorprendente
eficacia del reconocedor implementado en el Microsoft Windows XP Tablet
PC Edition 2005 Recognizer Pack. Sin
embargo, existen situaciones en las que
es muy difícil para cualquier reconocedor automático de texto averiguar qué
es lo que el usuario exactamente ha querido escribir.
Pensemos, por solo poner un par de
ejemplos, en aquellos casos en los que
es necesario que la aplicación reconozca letras sueltas, o palabras sin ningún
sentido en cualquier idioma, como
nombres de usuario o contraseñas. Para
poder enfrentarnos con éxito a este tipo
de casuísticas, el Microsoft Windows
XP Tablet PC Edition Software Development Kit pone a nuestra disposición
Factoids
Si ahora ejecutamos la aplicación y
escribimos de nuevo el número 51, nos
lo reconocerá sin problemas. Sin
embargo, si probamos a escribir el
carácter ‘1’ de un tamaño considerablemente mayor que el ‘5’, es posible
que el reconocedor nos interprete el
texto como la cadena “s1” (figura 3).
Los factoids son constantes de tipo
string que asignadas a la propiedad Factoid de la clase RecognizerContext que
proporcionan información contextual
al reconocedor que permite mejorar la
efectividad de reconocimiento.
Para entenderlo mejor, veamos un
sencillo ejemplo. Supongamos que en la
aplicación de ejemplo del apartado anterior quisiéramos reconocer únicamente
cifras numéricas introducidas por el usuario. Pues bien, si ejecutamos la aplicación
e intentamos escribir el número 51 pero
de un modo un tanto simplificado, el
reconocedor lo interpretará como la
cadena de texto “si” (ver figura 2).
Para solucionar este contratiempo,
añadimos la siguiente línea de código
dentro del evento buttonReconocimien-
Figura 3. Reconocimiento usando factoids.
Hemos mejorado el reconocimiento, sin embargo no hemos alcanzado el
<< dnm.plataforma.net
objetivo de que la aplicación reconozca todo el texto introducido por el
usuario exclusivamente como números. Para forzar al reconocedor a que
interprete los trazos introducidos únicamente dentro del contexto especificado por la propiedad Factoid, debemos incorporar la siguiente línea de
código a nuestra aplicación:
contextoReconocedor.RecognitionFlags=
RecognitionModes.Coerce;
minar el formato de cada factoid en función del idioma que estemos utilizando. Asimismo, debemos tener en cuenta que no todos los factoids existen en
todos los idiomas, por lo que es recomendable tener muy claro en qué idioma estamos trabajando y usar los factoids que correspondan.
En la tabla 1 se presentan los principales factoids, divididos en dos grandes grupos: dependientes e independientes de idioma. No se han incluido,
por encontrase fuera del alcance de este
artículo, los factoids de idiomas orientales (japonés, chino y coreano).
Wordlists
Existen situaciones en las que el uso
de factoids es del todo inadecuado, y sin
embargo el reconocimiento por defecto sigue siendo deficiente. Pensemos
por ejemplo aquellos casos en los que
la aplicación deba reconocer palabras
sin sentido que combinen letras y
números, como por ejemplo nombres
de usuario y contraseñas.
Si volvemos al ejemplo inicial e
intentamos reconocer por ejemplo la
cadena “ ss5lo10”, pero además no
haciendo distinción alguna mientras
Factoids independientes de idioma
Digit
Dígito simple.
Email
Direcciones de correo electrónico.
Web
Diferentes tipos de URL. Los valores por defecto del reconocedor
incluyen el factoid Web, por lo que no existe mayor diferencia entre
usar este factoid y no usarlo.
Default
Devuelve al reconocedor a sus valores por defecto.
En idiomas occidentales, esto incluye el diccionario de sistema, el
diccionario de usuario, los signos de puntuación y los factoids Web
y Number.
En idiomas orientales, incluye todos los caracteres soportados por el
reconocedor.
None
Desactiva todos los factoids y diccionarios.
No debe usarse el modo Coerce con este factoid.
Figura 4. Forzando el uso de factoids.
Factoids dependientes de idioma
Filename
Rutas de fichero de Microsoft Windows. No incluye los caracteres / “ < > |.
SystemDictionary
Activa en exclusiva el diccionario de sistema.
Wordlist
Currency
Activa en exclusive la lista de palabras.
Cantidades monetarias en libras, euros, dólares y yenes, escritos en
función del idioma.
Fechas escritas en función del idioma.
Todos los números, incluyendo ordinales, símbolos matemáticos y unidades de medida (mm, kg,…), todos ellos en función del idioma. También están incluidos los factoids Date, Time, Telephone y Currency.
Date
Number
OneChar
Un carácter ANSI.
Percent
Un número seguido del símbolo %. Existirá un espacio entre el número y el símbolo de porcentaje en función del idioma.
PostalCode
Códigos postales en función del idioma.
Telephone
Números de teléfono en función del idioma.
Time
Horas y minutos escritos en función del idioma.
UpperChar
Una letra mayúscula.
Tabla 1. Principales factoids
<<dotNetManía
Sin embargo, debemos usar con cuidado la combinación de la propiedad Factoid y el modo de reconocimiento Coerce, ya que tal y como hemos comentado,
el modo Coerce fuerza a reconocer únicamente aquellas cadenas de texto que
concuerden exactamente con la definición
del factoid. Así por ejemplo, el factoid Email
en modo Coerce solo reconocerá cuentas
de correo electrónico completas; es decir,
que contengan el carácter @ y un dominio
totalmente cualificado (por ejemplo
[email protected]), no permitiendo el reconocimiento de textos que no
cumplan estrictamente estos requerimientos, como por ejemplo aliases (JavierRoldan) o cuentas de correo sin dominios
totalmente cualificados, comunes en algunas implementaciones de mensajería interna (javier.roldan@midominio).
Es importante señalar que mientras
algunos factoids, como por ejemplo Email
y Web, son idénticos en cualquier idioma, otros, como por ejemplo Telephone y PostalCode dependen del idioma
utilizado. Es fundamental por tanto exa-
23
<< dnm.plataforma.net
Gestures
escribimos entre el ‘5’ y la ‘s’, el ‘1’ y la
‘l’ y el ‘0’ y la ‘o’, parece imposible que
ninguna aplicación (o incluso persona)
pueda reconocer ese texto (figura 5).
Figura 6. Reconocimiento
mediante wordlists
Figura 5. ¿Reconocimiento imposible?
Sin embargo, existe un modo de
hacer que este reconocimiento funcione, y es proporcionando al reconocedor
una lista de palabras posibles a introducir por el usuario. Es lo que se conoce
como el uso de wordlists.
Añadiremos el siguiente código
dentro del evento buttonReconocimiento_Click, justo tras la línea donde creamos el RecognizerContext y en sustitución del código añadido en el apartado
anterior (ver listado 2):
private void buttonReconocimiento_Click(object sender, EventArgs e)
{
Recognizers reconocedores = new Recognizers();
if (reconocedores.Count != 0)
{
Recognizer reconocedor = reconocedores.GetDefaultRecognizer();
RecognizerContext contextoReconocedor =
reconocedor.CreateRecognizerContext();
contextoReconocedor.Factoid = Factoid.WordList;
WordList wordList = new WordList();
wordList.Add(“ss5lo10”);
contextoReconocedor.WordList = wordList;
contextoReconocedor.RecognitionFlags = RecognitionModes.Coerce;
RecognitionResult resultadoReconocedor;
RecognitionStatus estatusReconocimiento;
contextoReconocedor.Strokes = inkOverlay.Ink.Strokes;
<<dotNetManía
contextoReconocedor.Factoid =
Factoid.WordList;
WordList wordList =
new WordList();
wordList.Add(“ss5lo10”);
contextoReconocedor.WordList =
wordList;
contextoReconocedor.RecognitionFlags=
RecognitionModes.Coerce;
24
Podremos comprobar que la aplicación es capaz de reconocer los trazos introducidos sin mayor problema
(figura 6).
Teniendo en cuenta que es posible
añadir en tiempo de ejecución tantas
palabras como deseemos a la propiedad
WordList, esto convierte su utilización en
prácticamente obligada en todos aquellos casos en los que sea factible su uso.
Finalizaremos el artículo haciendo
un breve recorrido por el uso de los gestures. Los gestures son gestos o trazos
especiales que no son reconocidos como
palabras y que permiten la ejecución de
acciones a medida.
El Microsoft Gesture Recognizer
soporta dos tipos de gestures: de sistema
(SystemGesture) y de aplicación (ApplicationGesture).
Los SystemGesture son gestos definidos y soportados por defecto y que en su
mayoría son mapeados a eventos de ratón;
como por ejemplo el gesto Tap, que es
if (contextoReconocedor.Strokes.Count > 0)
{
resultadoReconocedor =
contextoReconocedor.Recognize(out estatusReconocimiento);
if (estatusReconocimiento == RecognitionStatus.NoError &&
resultadoReconocedor != null)
{
String resultado = resultadoReconocedor.TopString;
if (resultado != null && resultado.Length > 0)
{
this.textBoxTextoReconocido.Text = resultado;
}
}
}
}
else
{
MessageBox.Show(“No existen reconocedores instalados”);
}
}
Listado 2. Usando wordlists para el reconocimiento de palabras complejas.
<< dnm.plataforma.net
Digit
Dígito simple.
Tap
Clic de ratón.
DoubleTap
Doble clic de ratón.
RightTap
Clic con el botón derecho del ratón.
Drag
Arrastre con el botón izquierdo del ratón.
RightDrag
Arrastre con el botón derecho del ratón. Se consigue haciendo un tap
largo y luego arrastrando sin levantar el puntero de la pantalla.
HoldEnter
Sin equivalente en el ratón.
HoldLeave
No implementado.
HoverEnter
Equivalente a pasar el ratón por encima.
HoverLeave
Equivalente a dejar de pasar el ratón por encima.
Tabla 2. SystemGesture disponibles
mapeado a un clic de ratón. La lista de
SystemGesture disponibles y su mapeo a
eventos de ratón se presenta en la tabla 2.
Por otra parte, los ApplicationGesture son gestos que podemos incluir (o
no) libremente en nuestra aplicación.
Para implementar este tipo de gestures,
debemos añadir el siguiente código al
evento Load del formulario:
A continuación, el código establece
qué tipo de gestures deseamos que sean
reconocidos mediante el uso del método SetGestureStatus de la clase InkOverlay. En el ejemplo activamos el reconocimiento de todos los gestures. Es
posible activar el reconocimiento de
solamente ciertos gestures; para ello, sustituiríamos la línea de código anterior
por una o más líneas equivalentes a las
que vemos a continuación:
Los gestures son
gestos o trazos
especiales que no
son reconocidos
como palabras y
que permiten la
ejecución de
acciones a medida
this.inkOverlay = new
InkOverlay(this.panelEscritura);
this.inkOverlay.CollectionMode =
CollectionMode.InkAndGesture;
this.inkOverlay.SetGestureStatus(ApplicationGesture.ChevronDown, true);
this.inkOverlay.SetGestureStatus(ApplicationGesture.ChevronUp, true);
this.inkOverlay.SetGestureStatus(ApplicationGesture.Check, true);
this.inkOverlay.SetGestureStatus(
ApplicationGesture.AllGestures,
true);
this.inkOverlay.Enabled = true;
Como puede observarse en el código, inicialmente creamos un InkOverlay
asociado al panel sobre el que deseamos
escribir, para luego establecer su propiedad CollectionMode al valor CollectionMode.InkAndGesture. Esto nos permite indicar que tanto los trazos de tinta como los gestos deben ser reconocidos como tal.
Por último, asociamos el método
inkOverlay_Gesture al evento Gesture del
objeto inkOverlay y lo activamos. El
método inkOverlay_Gesture, que sim-
plemente muestra en el cuadro de texto el texto asociado al gesture reconocido, se muestra a continuación:
Podemos ver el código completo en
el listado 3. No se ha incluido el código asociado a los botones de edición de
trazos ni de reconocimiento de escritura, ya que éste se muestra íntegramente en el listado 1.
void inkOverlay_Gesture(object sender, InkCollectorGestureEventArgs e)
{
this.textBoxTextoReconocido.Text = e.Gestures[0].Id.ToString();
}
<<dotNetManía
this.inkOverlay.Gesture += new
InkCollectorGestureEventHandler(
inkOverlay_Gesture);
25
<< dnm.plataforma.net
using
using
using
using
using
using
using
using
System;
System.Collections.Generic;
System.ComponentModel;
System.Data;
System.Drawing;
System.Text;
System.Windows.Forms;
Microsoft.Ink;
namespace InkGestureTest
{
public partial class FormGestures : Form
{
private InkOverlay inkOverlay;
public FormGestures()
{
InitializeComponent();
}
private void FormGestures_Load(object sender, EventArgs e)
{
this.inkOverlay = new InkOverlay(this.panelEscritura);
this.inkOverlay.CollectionMode = CollectionMode.InkAndGesture;
this.inkOverlay.SetGestureStatus(ApplicationGesture.AllGestures, true);
this.inkOverlay.Gesture += new InkCollectorGestureEventHandler(inkOverlay_Gesture);
this.inkOverlay.Enabled = true;
}
void inkOverlay_Gesture(object sender, InkCollectorGestureEventArgs e)
{
this.textBoxTextoReconocido.Text = e.Gestures[0].Id.ToString();
}
}
}
Listado 3. Implementación de los gestures.
Si ejecutamos la aplicación y probamos a trazar
gestos reconocidos como ApplicationGesture, veremos cómo de manera inmediata el texto asociado al
gesture será mostrado en el cuadro de texto habilitado al efecto.
<<dotNetManía
Conclusión
26
Figura 7. Gesture DoubleCurlicue.
Con esta segunda parte damos conclusión a nuestro
artículo relacionado con el desarrollo de aplicaciones capaces de aceptar tinta digital y de reconocer la
escritura manuscrita, que esperamos haya resultado
útil e informativo para los lectores.
plataforma.net
Luis Miguel Blanco
El evento CellPainting
del control DataGridView
Vía libre a la creatividad
Cuando presentamos a nuestros usuarios un conjunto de datos mediante el
control DataGridView, podemos mejorar la apariencia visual del mismo recurriendo al uso de estilos. No obstante, la mera utilización de estilos resulta
escasa si nuestras pretensiones pasan por lograr efectos avanzados y un mayor
control sobre el proceso de dibujo de las celdas. Es por ello que el empleo
combinado del evento CellPainting, perteneciente a este control, junto al conjunto de clases de GDI+ (la API de programación gráfica de .NET Framework),
se va a convertir en un poderoso recurso a nuestro alcance, que nos permitirá aplicar ese “toque especial” al dibujo de las celdas, para que luzcan con
todo su esplendor. Porque ellas lo valen.
CellPainting. Control total
del dibujo de celdas
Luis Miguel Blanco es
redactor de dotNetManía. Es consultor en
Alhambra-Eidos.Ha
escrito varios libros y
decenas de artículos
sobre la plataforma
.NET
(lalibreriadigital.com)
propiedades encontraremos también aquellas que
nos permitirán realizar todo el dibujo de la celda
y su contenido al completo. La tabla 1 muestra las
propiedades más destacables de esta clase.
Se trata de un evento que se produce para cada
celda que va a dibujarse, con la particularidad de
que el desarrollador
Propiedad
Descripción
dispone de pleno
Índice de la colección de columnas del control, que indica la columcontrol sobre toda la ColumnIndex
na sobre la que se produce el evento.
operación de dibujo
de la celda, siendo RowIndex
Índice de la colección de filas del control, que indica la fila sobre la
posible aplicarle efecque se produce el evento.
tos gráficos tales como
CellBounds
Objeto Rectangle con la posición y dimensiones de la celda a pintar.
degradados (fundidos)
Estado de la celda: seleccionada, visible, solo lectura, etc.
de colores, texturas, State
imágenes, etc.
Graphics
Objeto Graphics conteniendo el contexto de dispositivo gráfico sobre
CellPainting reciel que realizar la operación de dibujo.
be como parámetro
Valor para pintar en la celda.
un objeto DataGrid Value
ViewCellPainting
EventArgs , que nos
servirá para obtener la
información principal
sobre la columna, fila
y valor de celda.
Además, entre sus
FormattedValue
Valor formateado para pintar en la celda.
CellStyle
Estilo de la celda.
Handled
Propiedad booleana que permite informar al control si la operación de dibujo ha sido realizada manualmente mediante el código suministrado por el
programador, o deberá ser el control quien realice este proceso.
Tabla 1. Propiedades de la clase DataGridViewCellPaintingEventArgs
<<dotNetManía
<< dnm.plataforma.net
28
Es momento, por lo tanto, de
ponernos manos a la obra y crear un
nuevo formulario, al que añadiremos
un DataGridView que nos sirva para experimentar con esta característica. Como
es habitual, todos los ejemplos de este
artículo se encuentran disponibles en
el sitio Web de la revista.
En este ejemplo aplicaremos la operación de dibujo manual a los campos
ListPrice y Color, pertenecientes a la
consulta SQL que mostraremos en el
control de cuadrícula. Como paso previo, en el evento Load del formulario,
después de asignar el DataSet con los
datos al DataGridView, crearemos para
los mencionados campos sendos estilos
con un tipo de letra que destaque notablemente del resto de columnas, lo que
vemos en el listado 1, donde adicionalmente se configura el ajuste de tamaño
automático para filas y columnas, de
modo que el contenido de estos campos se muestre correctamente.
A continuación pasamos a escribir
el código de CellPainting, donde nuestro objetivo consistirá en pintar las
mencionadas celdas, dotándolas de un
efecto de fundido de colores que conseguiremos gracias al uso de un objeto
de la clase PathGradientBrush, que se
encuentra ubicada en el espacio de
nombres System.Drawing.Drawing2D. Un
objeto PathGradientBrush, brevemente
descrito, rellena una porción de la
superficie del formulario tomando
como base a una figura (por ejemplo,
el rectángulo correspondiente a una celda del control), y le aplica un color central que será rodeado por otro conjunto de colores situados en un array. La
forma en que los colores se distribuirán
y fundirán al aplicar este objeto se
determina gracias a un array de coordenadas (objetos Point), que en este caso
estará compuesto por los mismos puntos de coordenadas que el rectángulo
de la celda a pintar.
Entre los diversos estados que puede tomar una celda se encuentran los
correspondientes a normal y seleccionado. El estado actual de una celda se
// obtención de datos
SqlConnection cnConexion = new SqlConnection();
cnConexion.ConnectionString = “Data Source=localhost;” +
“Initial Catalog=AdventureWorksDW;” +
“Integrated Security=True”;
//....
string sSQL;
sSQL = “SELECT ProductKey, SpanishProductName, ListPrice, EndDate, Color “;
sSQL += “FROM DimProduct “;
sSQL += “WHERE ListPrice IS NOT NULL”;
SqlCommand cmdComando = new SqlCommand(sSQL, cnConexion);
SqlDataAdapter daAdaptador = new SqlDataAdapter(cmdComando);
DataSet dsAdvWorks = new DataSet();
daAdaptador.Fill(dsAdvWorks, “DimProduct”);
// establecer la fuente de datos para el DataGridView
this.dgvGrid.DataSource = dsAdvWorks;
this.dgvGrid.DataMember = “DimProduct”;
// cambiar el tipo de letra a las columnas
// que vamos a usar en el evento CellPainting
DataGridViewCellStyle styListPrice = new DataGridViewCellStyle();
styListPrice.Font = new Font(“Comic Sans MS”, 16, FontStyle.Bold);
styListPrice.Format = “C”;
this.dgvGrid.Columns[“ListPrice”].DefaultCellStyle = styListPrice;
DataGridViewCellStyle styColor = new DataGridViewCellStyle();
styColor.Font = new Font(“Papyrus”, 16, FontStyle.Bold);
this.dgvGrid.Columns[“Color”].DefaultCellStyle = styColor;
// establecer ajuste de altura automático para las filas
this.dgvGrid.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
// establecer ajuste de anchura automático para las columnas
this.dgvGrid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
// ocultar la primera columna del control
this.dgvGrid.Columns[“ProductKey”].Visible = false;
Listado 1
obtiene consultando la propiedad DataGridViewCellPaintingEventArgs.State; a
la hora de pintar la celda, podremos
asignarle un conjunto de colores distinto según el mencionado estado.
En el momento de pintar la celda,
necesitaremos un objeto de la clase
Graphics, que representa el contexto de
dispositivo gráfico o superficie sobre la
que vamos a dibujar. El acceso a este
objeto lo conseguimos gracias a la pro-
piedad DataGridViewCellPaintingEventArgs.Graphics, realizando el dibujo de
la celda mediante una llamada a su
método FillRectangle, que recibe como
parámetros el objeto PathGradientBrush
para aplicar el fundido de colores, y el
rectángulo de la celda, que está en la
propiedad DataGridViewCellPaintingEventArgs.CellBounds. El contorno o
línea delimitadora de los bordes de la
celda será dibujado utilizando el méto-
<< dnm.plataforma.net
private void dgvGrid_CellPainting(object sender,
DataGridViewCellPaintingEventArgs e)
{
// comprobar que la fila y columna están dentro del rango
// y que la columna corresponde a una de las que vamos
// a pintar
if (e.ColumnIndex > 0 && e.RowIndex >= 0 &&
(this.dgvGrid.Columns[e.ColumnIndex].Name == “Color” |
this.dgvGrid.Columns[e.ColumnIndex].Name == “ListPrice”))
{
// crear un array con las coordenadas
// sobre las que aplicaremos los colores con fundido
// basadas en la posición y dimensión de la celda
Point[] aPuntos = new Point[] {
new Point(e.CellBounds.X,e.CellBounds.Y),
new Point(e.CellBounds.X, e.CellBounds.Y +
e.CellBounds.Height),
new Point(e.CellBounds.X + e.CellBounds.Width,
e.CellBounds.Y + e.CellBounds.Height),
new Point(e.CellBounds.X + e.CellBounds.Width,
e.CellBounds.Y)};
PathGradientBrush pgbBrush;
Color[] aColores;
//
//
//
if
{
aColores = new Color[] {
Color.LightYellow,
Color.DarkTurquoise,
Color.MediumSpringGreen,
Color.LightSteelBlue};
pgbBrush = new PathGradientBrush(aPuntos);
pgbBrush.CenterColor = Color.Lavender;
pgbBrush.SurroundColors = aColores;
DataGridViewCellPaintingEventArgs
necesarias para esta operación: el objeto Graphics; la propiedad FormattedValue, más recomendable que su homóloga Value, fundamentalmente para
aquellos casos de columnas con valores numéricos o de fecha formateados;
CellBounds, como superficie o rectángulo sobre la que dibujar el texto; y
finalmente los valores del estilo –propiedad CellStyle–, que contienen el
tipo de letra y su color.
• Como última acción en el código de
este evento, tenemos que asignar el
valor true a la propiedad DataGridViewCellPaintingEventArgs.Handled,
puesto que es necesario informar al
control de que nosotros hemos sido
crear el objeto brush con efecto de fundido
utilizando una combinación de colores diferente
en función de si la celda está o no seleccionada
((e.State & DataGridViewElementStates.Selected) ==
DataGridViewElementStates.Selected)
}
else
{
aColores = new Color[] {
Color.BlanchedAlmond,
Color.LightSalmon,
Color.LightYellow,
Color.DarkOrange};
pgbBrush = new PathGradientBrush(aPuntos);
pgbBrush.CenterColor = Color.LawnGreen;
pgbBrush.SurroundColors = aColores;
}
// aplicar el objeto brush con el efecto de colores fundidos
// y dibujar un borde para el rectángulo de la celda
e.Graphics.FillRectangle(pgbBrush, e.CellBounds);
<<dotNetManía
do Graphics.DrawRectangle, aplicando
un color al borde sobre el rectángulo
de la celda.
Pero esto no es suficiente, ya que
solamente hemos dibujado el borde y
colores de fondo de la celda. Aún nos
queda el texto que representa el valor
de la celda, que obtenemos de la propiedad Value o FormattedValue, pertenecientes al parámetro DataGridViewCellPaintingEventArgs del evento. Sin
embargo, no podemos utilizar directamente esta propiedad; recordemos que
el evento CellPainting nos obliga a realizar manualmente todas las operaciones de dibujo, por lo que deberemos
convertir a modo gráfico la cadena a
dibujar siguiendo estos pasos:
• Tras comprobar que existe realmente un valor a dibujar, tenemos que calcular las dimensiones del texto (de
tipo Size) utilizando el método estático TextRenderer.MeasureText, al que
pasaremos como parámetro el valor
de la celda y el tipo de letra que usaremos para dibujarlo. Para este último, emplearemos el objeto Font situado en el estilo de la columna correspondiente a la celda.
• A continuación, empleando el también
método estático TextRenderer.DrawText, será cuando realmente dibujemos el texto, pasando como parámetro aquellas propiedades del objeto
29
<< dnm.plataforma.net
TextRenderer.DrawText(e.Graphics,
e.FormattedValue.ToString(),
e.CellStyle.Font,
e.CellBounds,
e.CellStyle.ForeColor,
TextFormatFlags.Top);
e.Graphics.DrawRectangle(
new Pen(Color.DarkMagenta, 3), e.CellBounds);
// si la celda tiene valor
if (e.Value != null)
{
// calcular el tamaño del texto
Size szTexto;
szTexto = TextRenderer.MeasureText(
e.Value.ToString(), e.CellStyle.Font);
Listado 3
mos dibujando celdas para dos columnas diferentes mediante CellPainting.
Supongamos que es necesario aplicar
una alineación distinta para cada una de
ellas. Esta es una situación que podemos solventar en el evento Load del formulario, asignando a la propiedad Tag
de los estilos creados para estas columnas el valor o combinación de valores
de TextFormatFlags que necesitemos para
establecer la alineación o efectos para el
texto.
La propiedad DataGridViewCellStyle.Tag es de tipo object, lo cual la convierte en un estupendo “cajón de sas-
// dibujar el texto
TextRenderer.DrawText(e.Graphics,
e.FormattedValue.ToString(),
e.CellStyle.Font,
e.CellBounds,
e.CellStyle.ForeColor);
}
e.Handled = true;
}
}
Listado 2
los encargados de realizar la operación de dibujo de la celda; de lo contrario, el control hará caso omiso de
nuestro código, realizando él solito las
operaciones de dibujo.
El listado 2 muestra el código del
evento CellPainting que acabamos de
explicar en los párrafos anteriores.
La figura 1 muestra la rejilla resultante de la aplicación de este proceso de
dibujo personalizado con CellPainting,
donde podemos observar las celdas que
hemos pintado tanto en estado normal
como seleccionado.
<<dotNetManía
Cambiando la alineación
en el contenido de las celdas
30
El método TextRenderer.DrawText, como
acabamos de comprobar, dibuja el texto centrado en la celda de manera predeterminada, pero supongamos que es
necesaria una alineación diferente. Para
conseguir dicho objetivo, añadiremos
Figura 1. Celdas pintadas mediante el evento CellPainting.
a DrawText como último parámetro el
tipo enumerado TextFormatFlags, cuyos
valores podemos utilizar de forma combinada para crear diferentes efectos de
formato, alineación, recorte de fuente,
etc. Por ejemplo, si queremos que el
texto de la celda quede alineado a la
parte superior de la misma, utilizaremos el código del listado 3.
Pero en el DataGridView que estamos
desarrollando para este ejemplo esta-
tre” para almacenar valores de cualquier
tipo, en función del problema a resolver en las más diversas situaciones.
Por lo tanto, como hemos dicho, si
para cada estilo asignamos por separado los valores de alineación a la propiedad Tag, posteriormente la aplicación de
dichos valores en CellPainting se simplifica enormemente cuando dibujamos
el texto con el método DrawText, como
vemos en el listado 4.
<< dnm.plataforma.net
private void Form1_Load(object sender, EventArgs e)
{
//....
styListPrice.Tag = TextFormatFlags.Right |
TextFormatFlags.VerticalCenter;
//....
styColor.Tag = TextFormatFlags.Left |
TextFormatFlags.VerticalCenter;
//....
}
zeColumnsMode. Esta acción tiene como efecto que el
usuario pueda cambiar el ancho de las columnas, y al
reducir su tamaño, el texto de estas quede oculto en
algunos casos. El efecto conseguido por el recorte del
texto puede no resultar muy agradable, por lo que si
aplicamos el valor TextFormatFlags.WordEllipsis, agregando este efecto a los demás ya existentes que se utilizan en el método DrawText, el resultado será la visualización de puntos suspensivos en aquellas celdas que
no puedan mostrar su contenido al completo. Este efecto lo podemos ver en la figura 3.
private void dgvGrid_CellPainting(object
sender, DataGridViewCellPaintingEventArgs e)
{
//....
TextRenderer.DrawText(e.Graphics,
e.FormattedValue.ToString(),
e.CellStyle.Font,
e.CellBounds,
e.CellStyle.ForeColor,
(TextFormatFlags)e.CellStyle.Tag);
//....
}
Figura 3. Puntos suspensivos en las celdas
que no muestran su texto al completo.
Listado 4
En la figura 2 podemos apreciar el resultado de
esta técnica para alinear los valores.
Y ya para terminar con el tipo TextFormatFlags,
vamos a comentar otro efecto realmente curioso. El
valor NoClipping de esta enumeración tiene como finalidad no recortar los extremos del texto cuando reducimos el
tamaño de la celda. Si combinamos este
valor con HorizontalCenter, como muestra el listado 5, obtendremos el interesante efecto de la figura 4, donde los
extremos de texto de la celda “invaden”
las celdas adyacentes.
Figura 2. Pintando celdas con distinta alineación desde CellPainting.
<<dotNetManía
Otros efectos sobre el contenido
32
Vamos a continuación a introducir una nueva variante en este escenario de trabajo. Imaginemos que no utilizamos el ajuste automático de anchura de columnas
para el control, por lo que borramos la línea de código que hace uso de la propiedad DataGridView.AutoSi-
TextRenderer.DrawText(e.Graphics,
e.FormattedValue.ToString(),
e.CellStyle.Font,
e.CellBounds,
e.CellStyle.ForeColor,
TextFormatFlags.HorizontalCenter |
TextFormatFlags.NoClipping);
Listado 5
<< dnm.plataforma.net
CellPainting en las cabeceras de columna. Indicando el orden de los registros
con una imagen propia
Para aplicar el evento CellPainting en las cabeceras
del control, emplearemos la misma lógica que en las
celdas de datos, pero debemos tener en cuenta que el
comportamiento de una cabecera, cuando el usuario
hace clic sobre ella, consiste en ordenar sus celdas
mostrando además un pequeño icono que
indica el orden establecido.
Si aplicamos una operación de dibujo personalizado a la celda de cabecera
con CellPainting, al hacer clic en ella para
ordenar sus datos éstos efectivamente se
ordenarán, pero el icono informativo del
tipo de orden no se mostrará, ya que
cuando realizamos el dibujo de una celda con este evento, como ya sabemos, la
responsabilidad de pintar hasta el último
elemento necesario recae sobre el programador.
Dado que el código a utilizar para pintar una celda de cabecera es muy parecido al de una celda normal de datos, dentro del listado 6, en lo que se refiere al
código del evento CellPainting, nos centraremos sólo en aquellos aspectos aplicables para este caso concreto.
Podemos ver, en primer lugar, la
necesidad de comprobar que el índice de
la columna sea mayor o igual a cero, el
de la fila menor de cero, y el nombre de
la columna a dibujar corresponda a la
que necesitamos pintar de forma personalizada.
<<dotNetManía
Figura 4. Los extremos del texto en las celdas
no se recortan.
A continuación, debemos averiguar el nombre de la
columna pulsada, disponible en la variable sCabeceraPulsada, que hemos declarado con ámbito a nivel de la
clase del formulario. Dicha variable la asignamos en otro
evento: ColumnHeaderMouseClick, provocado cuando el
usuario hace clic en una cabecera de columna.
Después de dibujar el título de la celda alineado a
la izquierda, comprobaremos si la columna va a ordenarse en alguna dirección. En caso afirmativo, disponemos de dos imágenes agregadas al proyecto como
recursos incrustados (este valor lo establecemos en la
ventana de propiedades de la imagen, dentro de la propiedad “Acción de generación”). Según el orden, obtendremos la imagen correspondiente, asignándola a una
variable de tipo Bitmap.
No obstante, es posible que la celda necesite dibujarse, pero no porque se haya pulsado la cabecera, en
cuyo caso la propiedad DataGridView.SortOrder contendrá el valor None, y la variable Bitmap estará a null.
Por dicho motivo, tenemos que comprobar que exista realmente una imagen a dibujar, y en ese caso, dibujarla en la parte derecha de la celda utilizando el método Graphics.DrawImage, calculando la posición en la
cual dibujar a partir del tamaño de la propia imagen
y las propiedades del rectángulo de la cabecera.
33
<< dnm.plataforma.net
string sCabeceraPulsada = string.Empty;
//....
private void Form1_Load(object sender, EventArgs e)
{
//....
this.dgvGrid.EnableHeadersVisualStyles = false;
// crear un estilo para las cabeceras del control
DataGridViewCellStyle styCabecera = new DataGridViewCellStyle();
styCabecera.BackColor = Color.BlanchedAlmond;
styCabecera.ForeColor = Color.DarkBlue;
styCabecera.Alignment = DataGridViewContentAlignment.MiddleLeft;
styCabecera.Font = new Font(“Century Schoolbook”, 10,
FontStyle.Bold);
styCabecera.Padding = new Padding(10);
Figura 5. Cabecera de columna
con dibujo personalizado de icono
de orden y fundido de colores.
La figura 5 muestra el control en ejecución, donde podemos observar la celda de cabecera con las operaciones que
acabamos de describir.
CellPainting en las cabeceras
de fila. Indicando el número de
fila a todo color
<<dotNetManía
Y si hemos podido pintar con alegres y
gráciles colorines una cabecera del control, las cabeceras de las filas no van a
ser menos, ni se van a librar de nuestro
arrebato artístico, así que tomando nuestros botes de pintura y pinceles digitales, pongámonos a trabajar.
La técnica que vamos a emplear,
como puede intuir el lector, será muy
similar a los otros casos anteriores, con
la salvedad de que ahora vamos a dibu-
34
Al realizar el dibujo
de una celda
mediante CellPainting,
la responsabilidad de
pintar hasta el último
detalle recae sobre
el programador
this.dgvGrid.ColumnHeadersDefaultCellStyle = styCabecera;
// ampliar la anchura de la columna
// sobre la que vamos a dibujar la cabecera
this.dgvGrid.Columns[“ProductKey”].Width += 40;
}
// cada vez que hacemos clic en la cabecera
// guardamos el nombre de la columna pulsada
private void dgvGrid_ColumnHeaderMouseClick(object sender,
DataGridViewCellMouseEventArgs e)
{
sCabeceraPulsada = this.dgvGrid.Columns[e.ColumnIndex].Name;
}
private void dgvGrid_CellPainting(object sender,
DataGridViewCellPaintingEventArgs e)
{
// comprobar si la cabecera a pintar es la que necesitamos
if (e.ColumnIndex >= 0 &&
e.RowIndex < 0 &&
this.dgvGrid.Columns[e.ColumnIndex].Name == “ProductKey”)
{
//....
// dibujar el título de la cabecera
// alineado a la izquierda
TextRenderer.DrawText(e.Graphics,
e.FormattedValue.ToString(),
e.CellStyle.Font,
e.CellBounds,
e.CellStyle.ForeColor,
TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
// si la cabecera pulsada es la que necesitamos,
// en función del tipo de ordenación,
// obtener la imagen del recurso incrustado en el proyecto
Bitmap bmpImagen = null;
if (sCabeceraPulsada == “ProductKey”)
{
switch (this.dgvGrid.SortOrder)
{
case SortOrder.Ascending:
bmpImagen =
<< dnm.plataforma.net
case SortOrder.Descending:
bmpImagen =
new Bitmap(GetType(), “FlechaAbajo.png”);
break;
}
}
// pintar la imagen en la celda de la cabecera
// si realmente se ha establecido un orden
if (bmpImagen != null)
{
e.Graphics.DrawImage(bmpImagen,
e.CellBounds.Right –
(bmpImagen.Width + e.CellStyle.Padding.Left),
e.CellBounds.Y + e.CellStyle.Padding.Top);
}
e.Handled = true;
}
}
Listado 6
private void dgvGrid_CellPainting(object sender,
DataGridViewCellPaintingEventArgs e)
{
// si la celda a pintar es cabecera de fila
if (e.ColumnIndex < 0 && e.RowIndex >= 0)
{
// calcular el número a pintar en la celda
int nNumeroFila = e.RowIndex + 1;
//....
// crear la fuente a usar para dibujar el número
Font oFont = new Font(“Comic Sans MS”, 12, FontStyle.Italic);
// calcular el tamaño del texto
Size szTexto =
TextRenderer.MeasureText(nNumeroFila.ToString(), oFont);
// dibujar el número
TextRenderer.DrawText(e.Graphics,
nNumeroFila.ToString(),
oFont,
e.CellBounds,
e.CellStyle.ForeColor);
e.Handled = true;
}
}
Listado 7
jar el número de cada fila, por lo que
tendremos que calcular dicho valor
basándonos en la propiedad DataGridViewCellPaintingEventArgs.RowIndex, y
comprobar que la celda sobre la que
vamos a realizar las operaciones pertenece a una fila; o lo que es lo mismo, al
tomar el parámetro DataGridViewCellPaintingEventArgs del evento CellPainting, la propiedad ColumnIndex deberá
ser menor que cero, y la propiedad
RowIndex mayor o igual que cero.
Los efectos de colores fundidos y
cálculo de coordenadas para pintar el
objeto PathGradientBrush serán los mismos que en los anteriores ejemplos, por
lo que el cambio en este caso concreto
consistirá en crear un tipo de letra explícitamente para dibujar el número en la
celda. Por este motivo, en el listado 7
se exponen aquellas instrucciones que
representan cambios con respecto a los
anteriores ejemplos.
Para comprobar la aplicación de este
efecto sobre esta parte del control, veamos la figura 6.
Figura 6. Personalizando el dibujo
de las cabeceras de fila.
Acabando la pintura
Llegamos al punto final de este artículo, en el que hemos realizado un repaso del evento CellPainting del control
DataGridView, como medio para aplicar
ciertos efectos avanzados de presentación sobre las celdas del control a fin de
lograr un resultado más agradable a la
vista de nuestros usuarios.
Que ustedes lo disfruten.
<<dotNetManía
new Bitmap(GetType(), “FlechaArriba.png”);
break;
35
plataforma.net
Alberto Población
Más sobre seguridad
de acceso a código
En una entrega anterior (dotNetManía nº 41) presentamos los fundamentos de la Seguridad de acceso a código (Code Access Security, CAS)
en .NET Framework, y describimos cómo el CLR determina los permisos del código y cómo se pueden manipular desde las herramientas
administrativas los permisos concedidos a cada ensamblado. En esta
entrega veremos cómo se pueden solicitar, manipular y limitar estos
permisos desde dentro de nuestro código.
Atributos para solicitud
y rechazo de permisos
Un primer paso que podemos dar en nuestros
programas es el de “decorar” el código fuente
con una serie de atributos en los que se especifican los requisitos que tiene el ensamblado en
cuanto a los permisos que necesita para poder
funcionar. Cuando especificamos los requisitos
de seguridad mediante atributos, se dice que estamos haciendo operaciones de seguridad declarativas, en contraposición a las que se realizan
mediante sentencias de código ejecutable, que se
denominan imperativas.
En su modalidad más simple, la solicitud de
permisos puede tener este aspecto:
Alberto Población lleva
27 años desarrollando
software. Cuenta entre
otras con las certificaciones MCSE, MCDBA,
MCITP, MCSD, MCPD y
MCT, además de ser
MVP de C#. En la actualidad trabaja como consultor independiente,
dedicándose principalmente a la formación,
asesoramiento y desarrollo de aplicaciones.
using System.Security.Permissions;
...
[assembly:
UIPermission(SecurityAction.RequestMinimum,
Window=UIPermissionWindow.AllWindows)]
Estos atributos, que afectan a todo el ensamblado, se pueden introducir en cualquiera de los
fuentes que se compilan para formar dicho ensamblado; pero es costumbre, para facilitar su locali-
zación, agruparlos dentro del archivo AssemblyInfo.cs (o .vb).
En el ejemplo anterior hemos utilizado un
permiso del tipo UIPermission, es decir, una solicitud de permiso de interfaz de usuario. En los
argumentos hemos especificado SecurityAction.RequestMinimum, indicando que el programa
necesita como mínimo este permiso para poder
funcionar. Si las políticas de seguridad del sistema no concediesen a este ensamblado los permisos que hemos señalado como “mínimos”, el
ensamblado no llegaría a cargarse, y el sistema
mostraría directamente un error de seguridad,
sin siquiera arrancar el programa.
El parámetro Window=UIPermissionWindow.AllWindows especifica en mayor detalle el tipo concreto de UIPermission que estamos solicitando. Para
cada subtipo de Permission, los argumentos disponibles son diferentes y permiten matizar las características y alcance del permiso correspondiente.
Cabe señalar que también es posible solicitar
de golpe un conjunto de permisos completo. Por
ejemplo, para solicitar el conjunto “Full Trust”:
[assembly: RegistryPermission(
SecurityAction.RequestMinimum,
Name=”FullTrust”)]
<< dnm.plataforma.net
[assembly: FileIOPermission(
SecurityAction.RequestOptional,
Unrestricted=true)]
[assembly: RegistryPermission(
SecurityAction.RequestRefuse,
Unrestricted = true)]
Con el primero de estos atributos
estamos indicando al sistema de seguridad que deseamos utilizar el permiso de FileIO si las políticas de seguridad lo permiten para este ensamblado, pero que el programa puede
funcionar sin este permiso. Esto puede ser útil, por ejemplo, para un programa que grabe una bitácora (log) de
sus operaciones en un archivo en disco, pero que en caso de no tener ese
permiso puede seguir funcionando;
eso sí, sin grabar el log.
El segundo atributo expresa que
no deseamos disponer de permiso de
acceso al Registro de Windows,
incluso aunque las políticas de seguridad lo consientan para nuestro
ensamblado. De esta forma garantizamos que el programa nunca pueda
modificar el Registro, incluso aunque presente un mal funcionamiento o un uso indebido de alguna función de librería que pudiera realizar
ese tipo de operación.
La asignación final de permisos que
recibe el ensamblado consiste en los
Mínimos, más los Opcionales que permita la política de seguridad, menos los
Rechazados.
Hay que señalar que, en caso de que
no se solicite ningún permiso opcional,
el sistema interpreta que se solicita “Full
Trust” como permiso opcional, y por
tanto se conceden todos los permisos
que permita la política, salvo los rechazados expresamente. Por este motivo,
es buena costumbre incluir un atributo como el siguiente:
[assembly: FileIOPermission(
SecurityAction.RequestOptional,
Unrestricted=false)]
Con esto indicamos que solicitamos como Opcional “ningún permiso”, con lo que ya no se aplica lo indicado en el párrafo anterior, y los únicos permisos concedidos son los que
solicitemos expresamente mediante
el resto de los atributos. De esta forma, el programa no recibe ningún
permiso superfluo.
(“Ensamblado 2”) que graba ciertos
datos en disco. Este ensamblado, al
igual que el anterior, habrá recibido
los permisos que le correspondan; por
ejemplo, podría tener permiso de escritura en disco. Para realizar físicamente la grabación, esta DLL utiliza las
rutinas contenidas en el espacio de
nombres System.IO, que se encuentran
compiladas dentro de una de las DLL
que se suministran con .NET Framework, y que en la figura hemos llamado “Ensamblado 3”.
Solicitud de permisos
(“Demand”)
Hemos visto que un ensamblado
puede solicitar y recibir una serie de
permisos. Los permisos que ha recibido el ensamblado entrarán en juego en el momento en que el código
que se ejecuta realice una operación
que requiera dichos permisos. ¿Cómo
se determinan y se controlan estas
operaciones? Veámoslo, apoyándonos
en la figura 1.
Supongamos que tenemos un programa ejecutable, que en la figura
denominamos “Ensamblado 1”, que
conforme con las políticas del sistema
ha recibido permiso de ejecución pero
no de escritura en disco. Este programa realiza una llamada a una DLL
Figura 1
Esta librería, en última instancia,
tendrá que utilizar los servicios de invocación a la plataforma (P/Invoke) para
Instrucciones de control de seguridad
Solicitar permisos
Demand
Afirmar permisos
Assert
Restricción de permisos
Deny
PermitOnly
Desactivar llamadas en la pila
RevertAssert
RevertDeny
RevertPermitOnly
RevertAll
Comparar permisos
IsSubsetOf
Combinación de permisos
Union
Intersect
<<dotNetManía
De forma similar a la solicitud de
permisos mínimos, se pueden añadir
solicitudes de permisos Opcionales y
Rechazados:
37
<< dnm.plataforma.net
using System.Security.Permissions;
// ...
public void Escribir(string fichero)
{
FileIOPermission permiso = new FileIOPermission(
FileIOPermissionAccess.Write, fichero);
try
{
permiso.Demand();
// Aquí, si la solicitud tiene éxito,
// usamos P/Invoke para llamar a la API
}
catch (SecurityException ex)
{
// Si falla el Demand(), se produce esta excepción
}
}
<<dotNetManía
Listado 1
38
llamar a las API de Windows que realizan la grabación mediante código no
manejado. Antes de hacer el salto a
dicho código no manejado, el programa hace una llamada al código de seguridad de .NET que se denomina “solicitud de permiso” (“Demand”). En el
listado 1 tenemos un ejemplo que muestra una solicitud de este tipo.
Cuando se ejecuta el Demand(), el
motor de seguridad realiza un recorrido por la pila de llamadas (stack walk),
comprobando si todos los llamantes de
esta rutina tienen el permiso solicitado. En el ejemplo de la figura 1, la solicitud sube en primer lugar al Ensamblado 2, que efectivamente tenía permiso de escritura, con lo que la solicitud continúa subiendo por la pila. Al
llegar al Ensamblado 1, el CLR determina que dicho ensamblado no tiene
permiso de escritura, por lo que se produce una excepción de seguridad y la
escritura no llega a realizarse.
El resultado final es que no se produce ninguna escritura en disco, a pesar
de que las DLL que contienen instrucciones de grabación tienen permiso para
ello, debido a que el llamante inicial tiene prohibida dicha escritura por las
políticas de seguridad de .NET.
Estas solicitudes también se pueden hacer de forma declarativa en lugar
de imperativa, a nivel de clase o de
método:
[FileIOPermission(
SecurityAction.Demand,
Write = “C:\\Fichero”)]
public class ClaseConPermiso
{...}
Afirmación de permisos
(“Assert”)
Vayamos más allá y supongamos que
realmente sí que deseamos realizar la
grabación anterior. Por ejemplo, el
Ensamblado 2 podría contener unas
rutinas de registro en bitácora (logging)
que graben en un archivo una traza de
las operaciones realizadas, y deseamos
que esa traza quede grabada siempre
que un ejecutable llame a esta librería,
aunque el ejecutable en sí no tenga permiso para escribir en disco. Esto se
logra mediante la operación llamada
“Assert”, tal como muestra el ejemplo
del listado 2.
Volviendo al ejemplo de la figura 1,
y suponiendo que el Assert() se ha
introducido en el Ensamblado 2, cuando se produce el Demand() en el Ensamblado 3 y “sube” a la trama anterior de
la pila, se encuentra que en dicha trama se ha realizado una afirmación del
permiso solicitado, y en consecuencia
se da dicho permiso por concedido,
teniendo éxito el Demand() sin llegar a
subir hasta el Ensamblado 1.
private void GrabarTraza()
{
const string fichero = C:\\log.txt”;
FileIOPermission permiso = new
FileIOPermission(
FileIOPermissionAccess.Write,
fichero);
permiso.Assert();
// Aquí se hace la grabación
FileIOPermission.RevertAssert();
}
Listado 2
Lógicamente, este proceso solo
tendrá éxito si la política de seguridad
concede el permiso solicitado al ensamblado que realiza el Assert.
Solo puede haber un único Assert
activo por cada trama de la pila. Una
vez que el Assert ya no se necesita, se
desactiva mediante RevertAssert(),
como se ve en el ejemplo del listado 2.
Hay que actuar con precaución al
escribir ensamblados que utilicen el
Assert, ya que por esta vía se pueden abrir
agujeros de seguridad. Por ejemplo, en el
listado 2 hemos especificado como const
string el nombre del fichero en el que se
graba el log. Si en lugar de eso hubiéramos aceptado este fichero como parámetro del método, el programa llamante (que, recordemos, no tiene permisos
para grabar en disco) podría pasar por esta
vía una ruta cualquiera y “engañar” al sistema de seguridad consiguiendo grabar
en disco un archivo de su elección, aprovechándose de los permisos que tiene
concedidos el Ensamblado 2.
Rechazo de permisos
(“Deny”)
La operación “Deny” funciona del
modo contrario que Assert. Cuando
ejecutamos un Deny(), estamos forzando que se produzca una excepción
cuando el código más abajo en la pila
realice un Demand() del permiso objeto del Deny, incluso aunque el ensam-
<< dnm.plataforma.net
blado llamante sí que tenga el permiso en cuestión. El ejemplo del listado 3 rechaza el permiso de utilizar
reflexión sobre miembros no visibles
de un tipo.
public void Metodo()
{
ReflectionPermission permiso =
new ReflectionPermission(
ReflectionPermissionFlag.
TypeInformation);
permiso.Deny();
// Usar reflexión para acceder a
// miembros públicos
ReflectionPermission.RevertDeny();
}
Prueba de los programas bajo condiciones de seguridad restringida
Cuando estamos desarrollando programas, normalmente los ejecutables se crean sobre nuestro
disco local y desde ahí los ejecutamos. La política de seguridad predeterminada les otorga entonces el conjunto de permisos “Full Trust”. Por lo tanto, al ejecutarlos no ejercitamos las distintas
limitaciones de seguridad a las que se refiere este artículo.
Si deseamos probar y depurar nuestros programas bajo condiciones de seguridad limitada,
podemos crear una carpeta en nuestro disco y asignar a los archivos cargados desde esa carpeta una política restrictiva, añadiendo el atributo “Exclusive”, para que no reciban además los
permisos predeterminados. Una forma de asignar estos permisos consiste en utilizar el comando CASPOL:
md c:\pruebas
caspol -ag 1 -url file:///C:/pruebas/* Internet -n Pruebas -exclusive on
Para probar nuestro programa, copiaremos el ejecutable a esta carpeta y lo ejecutaremos
desde ahí, con lo cual se verá limitado a los permisos asignados, que en el ejemplo anterior son
los de la Zona Internet.
[PermissionSet(
SecurityAction.LinkDemand,
Name = “FullTrust”)]
public void Metodo(...){...}
validez de su código en dichos entornos mediante el atributo AllowPartiallyTrustedCallers:
Listado 3
[assembly: AllowPartiallyTrustedCallers]
Si este código se introdujera en el
Ensamblado 2 de la figura 1, y detrás
del Deny se llamara a una subrutina del
Ensamblado 3 que tratara de usar reflexión sobre miembros privados de una
clase, se produciría una excepción de
seguridad, aún en el caso de que tanto
el Ensamblado 3 como el 2 tuvieran
concedido dicho permiso.
“LinkDemand”
La operación “LinkDemand” opera de
forma similar al Demand que hemos
mencionado más arriba, con la diferencia de que LinkDemand() solo comprueba el llamante inmediato, en lugar
de recorrer toda la pila comprobando
si la totalidad de los llamantes tienen el
permiso solicitado.
Por ejemplo, para comprobar que
el llamante tiene “Full Trust”:
Adicionalmente, el Demand recorre la pila cada vez que es invocado,
debido a que los llamantes podrían ser
distintos, mientras que el LinkDemand
se resuelve en tiempo de compilación
Just-In-Time (JIT), por lo que solo se
comprueba una vez.
El atributo AllowPartiallyTrustedCallers
Todo ensamblado que tiene un nombre fuerte (strong name) recibe implícitamente un LinkDemand del conjunto de permisos Full Trust. Esto
provoca el que dichos ensamblados
no puedan ser llamados desde programas que no tengan confianza completa. Si el programador ha tenido en
cuenta al desarrollar el ensamblado
las implicaciones de seguridad de los
entornos que tienen confianza parcial, puede declarar expresamente la
La consecuencia de aplicar este atributo es que se elimina el mencionado
LinkDemand y el ensamblado deja de
requerir que sus llamantes tengan permisos Full Trust.
Conclusión
Cuando escribamos librerías que utilicen
llamadas a código no gestionado, y sea
previsible que éstas puedan ser llamadas
desde código que no tenga confianza completa, es recomendable que introduzcamos dentro las peticiones de permisos (con
“Demand”) que sean oportunas de conformidad con las operaciones que realice
dicho código no manejado, a fin de evitar
que los programas que llamen a nuestra
librería y no tengan confianza completa
puedan aprovecharse de ella para saltarse
las políticas de seguridad.
La librería de MSDN contiene la referencia completa de las clases que manejan la Seguridad de acceso a código. Véanse estos enlaces:
http://msdn.microsoft.com/library/SPA/cpguide/html/cpconsecurecodingguidelines.asp
http://msdn2.microsoft.com/es-es/library/system.security(VS.80).aspx
<<dotNetManía
Documentación
39
plataforma.net
Daniel Seara
Herramientas genéricas para los
componentes: ficheros y recursos
Siguiendo con la idea de las generalizaciones en componentes expuesta en el número anterior, en este artículo veremos algunos otros ejemplos que pueden resultarle interesantes.
Manipulando archivos (o ficheros)
Más tarde o más temprano, nuestros componentes necesitarán acceder a archivos físicos en disco.
Consideremos entonces una clase que encapsule
dichas acciones: FileIO.
En este caso, las acciones serán inmediatas, sin
mucha cosa que hacer más que la tarea específica.
Para facilitar el acceso, hagamos que los métodos de
esta clase sean accesibles directamente, sin necesidad de instanciar la misma. Para ello, nos aseguraremos de que la clase no sea heredable, utilizando
NotInheritable como modificador en la declaración
de la clase, y tenga un único constructor privado,
para que no se puedan crear instancias.
Public NotInheritable Class FileIO
Private Sub New()
End Sub
End Class
Public Shared Function GetFileContent( _
ByVal path As String) As String
Try
‘ Se evalúa si el usuario tiene permiso de acceso
Dim permission As New _
System.Security.Permissions.FileIOPermission(_
System.Security.Permissions.FileIOPermissionAccess.Read,_
path)
permission.Demand()
‘ Mediante using, nos aseguramos de que se libere
‘ adecuadamente el recurso
Using fi As New System.IO.StreamReader(path, _
System.Text.Encoding.Default)
Dim s As String = fi.ReadToEnd
fi.Close()
Return s
End Using
Catch ex As Exception
Throw
Finally
End Try
End Function
Listado 1
Leyendo contenido del disco
Daniel Seara es mentor
de Solid Quality Mentors
y director del área de
desarrollo .NET. Es MVP
desde 2003 y ponente
habitual de INETA y
Microsoft.
Lo importante en este caso es:
1. Asegurarse de que el usuario tiene derechos
de lectura sobre el elemento requerido.
2. Disponer adecuadamente del recurso de
acceso a disco.
Es muy útil disponer de métodos para recuperar y almacenar información privada del usuario para cada aplicación. Para ello, es más seguro
utilizar IsolatedStorage.
Y de una forma muy similar, implementamos
escrituras (listado 2).
<< dnm.plataforma.net
El código importa el espacio
System.IO.IsolatedStorage
para facilitar el acceso a los
objetos definidos en él.
][
NOTA
Es importante tener en cuenta
que se pueden duplicar estas
funciones para que utilicen
arrays de bytes u objetos
MemoryStream para manipular
datos binarios.
]
Public Shared Function GetPrivateContent( ByVal name As String) _
As String
Try
Using isoFile As _
IO.IsolatedStorage.IsolatedStorageFile = _
IsolatedStorageFile.GetStore(IsolatedStorageScope.User _
Or IsolatedStorageScope.Assembly _
Or IsolatedStorageScope.Domain, Nothing, Nothing)
Using isoStream As New IsolatedStorageFileStream( _
name, IO.FileMode.Open, isoFile)
Using Reader As New IO.StreamReader(isoStream)
Dim sReturn As String = Reader.ReadToEnd
Reader.Close()
isoStream.Close()
isoFile.Close()
Return sReturn
End Using
End Using
End Using
Catch ex As Exception
Throw
End Try
End Function
Listado 2
Listado 3
Otro elemento interesante a generalizar es la obtención de recursos, tan-
Public Enum SourceAssemblyEnum_
As Integer
CallerAssembly
InitialAssembly
End Enum
Y, nuevamente, una clase que permita acceder directamente los métodos,
sin necesidad de instanciarla.
Public NotInheritable Class_
Resources
Shared Sub New()
End Sub
End Class
[ ]
NOTA
En este caso, el constructor
es Shared. La diferencia es
que, si necesitáramos hacer
algo la primera vez que se utiliza un método de esta clase,
podríamos hacerlo allí. No es
este el caso, pero quería dejar
claro cómo se hace.
Public Shared Sub WritePrivateContent( _
ByVal name As String, ByVal content As String)
Using isoFile As IO.IsolatedStorage.IsolatedStorageFile = _
IsolatedStorageFile.GetStore( _
IsolatedStorageScope.User _
Or IsolatedStorageScope.Assembly _
Or IsolatedStorageScope.Domain, _
Nothing, Nothing)
Using isoStream As New IsolatedStorageFileStream( _
name, IO.FileMode.Create, isoFile)
Using writer As New IO.StreamWriter(isoStream)
writer.Write(content)
writer.Close()
isoStream.Close()
isoFile.Close()
End Using
End Using
End Using
End Sub
Recursos
pleja, puede que sean del componente
que se está ejecutando o del proceso que
lanza la ejecución.
Definamos un enumerador que nos
permita identificar de dónde queremos
extraer los recursos:
to sean textos como de formato binario. En muchas oportunidades necesitaremos de ellos y, cosa aún más com-
Utilizando el enumerador podremos identificar de dónde obtener el
recurso. Necesitamos entonces el nombre del mismo y ya podremos hacerlo
(siempre, los recursos se obtienen como
un stream) (listado 4).
Una vez que obtenemos el stream,
convertirlo a texto es simplemente
transformarlo de acuerdo a la codificación, que en general es la predeterminada en el proceso (listado 5).
<<dotNetManía
[
NOTA
41
<< dnm.plataforma.net
Public Shared Function GetResourceStream( _
ByVal name As String, _
Optional ByVal Source As SourceAssemblyEnum = _
SourceAssemblyEnum.CallerAssembly) _
As System.IO.Stream
Dim ass As System.Reflection.Assembly = Nothing
Select Case Source
Case SourceAssemblyEnum.CallerAssembly
ass = System.Reflection.Assembly.GetCallingAssembly
Case SourceAssemblyEnum.InitialAssembly
ass = System.Reflection.Assembly.GetEntryAssembly
End Select
‘ La propiedad FullName retorna varios datos.
‘ De ellos, el primero es el nombre del ensamblado,
‘ que es lo que necesitamos
Dim sName As String = ass.FullName.Split(“,”c)(0)
Dim str As System.IO.Stream = _
ass.GetManifestResourceStream( _
String.Format(“{0}.{1}”, sName, name))
‘ Si el recurso no existe no se obtiene nada
‘ Por lo tanto, sigue siendo Nothing
If str Is Nothing Then
‘ Esta excepción hereda de
‘ Solid.Tools.ExceptionHandler.BaseException
Throw New KeyNotExistException
End If
Return str
End Function
Listado 4
<<dotNetManía
Public Shared Function GetResourceString( _
ByVal name As String, _
Optional ByVal source As SourceAssemblyEnum = _
SourceAssemblyEnum.CallerAssembly) As String
42
‘ Utiliza GetResourceStream para obtener el recurso
Dim str As System.IO.Stream = _
GetResourceStream(name, source)
With str
‘ Se obtienen todos los bytes
Dim bytes(CInt(.Length)) As Byte
.Read(bytes, 0, CInt(.Length - 1))
Dim textConverter As System.Text.Encoding = _
System.Text.Encoding.Default
Try
‘ Se transforman a cadena de caracteres
Return textConverter.GetString(bytes)
Catch ex As Exception
‘ Hereda de
‘ Solid.Tools.ExceptionHandler.BaseException
Throw New ResourceNotFoundException(ex)
End Try
End With
End Function
Listado 5
Es muy útil disponer de métodos para
recuperar y almacenar información
privada del usuario para cada
aplicación. Para ello, es más seguro
utilizar IsolatedStorage
¿Y qué pasa con My?
Sí, claro, obviamente puede utilizarse sin problemas, pero las
funciones anteriores sirven para obtener cualquier recurso,
no solo los incluidos en el proyecto actual (ensamblado actual).
Y hablando de My, les dejo un pequeño procedimiento para
cargar los iconos que necesite un formulario en controles ImageList desde los recursos de la aplicación. En el ejemplo se
asume que toda imagen cuyo nombre termine en “16” es para
un determinado ImageList (podría repetirse para “32”, etc.
para cargar distintos ImageList).
Sub LoadImageLists()
Dim myRes As Resources.ResourceSet = _
My.Resources.ResourceManager.GetResourceSet( _
System.Threading.Thread.CurrentThread.CurrentUICulture,_
False, _
True)
Dim myEnum As IDictionaryEnumerator = _
myRes.GetEnumerator()
Do While myEnum.MoveNext
If myEnum.Key.ToString.EndsWith(“16”) Then
img16.Images.Add( _
myEnum.Key.ToString.ToUpper.Replace(“16”, “”), _
System.Drawing.Icon.FromHandle( _
CType(myEnum.Value, Drawing.Bitmap).GetHicon))
End If
Loop
End Sub
Listado 5
Y basta por ahora. Espero en la próxima comenzar con
algunas cosas algo más complejas.
¡Saludos!
<< dnm.inicio
inicio
Guillermo «Guille» Som
Depuración en .NET
El depurador que lo depure... recibirá ayuda del CLR
Guillermo “Guille”
Som
Es Microsoft MVP de
Visual Basic desde 1997.
Es redactor de dotNetManía, mentor de Solid
Quality Iberoamericana,
tutor de campusMVP,
miembro de Ineta Speakers Bureau Latin America, y autor de los libros
“Manual Imprescindible
de Visual Basic .NET” y
“Visual Basic 2005”.
http://www.elguille.info
La crispación a la que me refería antes se debe a que
con las primeras dos versiones de Visual Studio para
.NET, cuando depurábamos una aplicación y deteníamos (o se detenía) la ejecución del programa, normalmente porque se producía un error, lo primero
que querías hacer era solucionar la causa del error, y
para solucionarlo lo habitual era que modificaras el
código. Y aquí es cuando empezaban los problemas.
Con la versión inicial (llamémosla Visual Studio 2002),
no podías modificar nada del código durante la depuración. Si tus antecedentes de programador eran porque usabas Visual Basic 6.0, esa crispación llevaba
implícita una implementación de ICabreante (ver dotNetManía nº 16 y 18 para saber más sobre las interfaces), y es que en Visual Basic 6.0 la depuración era
muy cómoda; éste permitía modificar el código, cambiar por dónde debía continuar la ejecución y otras
facilidades que resultaban útiles a la hora de realizar
esa tarea tan, digamos, desagradable.
La excusa que nosotros mismos nos poníamos era
que “bueno, lo acepto, ya que en Visual Basic 6.0 la
ejecución es sobre código casi interpretado y .NET
debe hacerlo sobre código compilado, por tanto...
acepto pulpo como animal de compañía”, y... ¡te tenías
que aguantar! ¡Qué remedio!
Después llegó Visual Studio 2003, y la cosa cambió un poco; no mucho, la verdad, pero al menos permitía (y sigue permitiendo) modificar el código. El
problema es que esos cambios no serían tenidos en
cuenta hasta la próxima vez; es decir, para que fuesen
aplicados esos cambios tenías que detener la depuración (o parar la ejecución, que para el caso es lo mismo) y empezar de nuevo. La interfaz que definía esta
segunda versión de Visual Studio era IDesesperante;
pero ya casi te habías acostumbrado y casi no la implementabas.
Y entonces empezaron los rumores: Visual Studio 2005 (por entonces conocido como Whidbey)
tendría algo que los programadores de Visual Basic
pre-.NET ya tenían desde hacía años: Edit & Continue (editar y continuar). ¡Bien! ¡Una buena noticia!
Pero la noticia no solo era buena, sino fabulosa. Esa
característica de editar y continuar estaría implementada en el propio corazón de .NET: el CLR. Esto
suponía que todos los lenguajes de .NET se beneficiarían de esa característica. Y lo mejor de todo es que
si el motor de ejecución permitiría detener la ejecución, hacer cambios y seguir ejecutando la aplicación,
lo haríamos sobre código compilado; es decir, todo
el proceso sería más fiable que si fuese interpretado
o simulado por el entorno de desarrollo, que era lo
que en un principio parecía que iba a ocurrir (inicialmente se rumoreaba que solo iba a ser posible
usarlo en Visual Basic).
Por fin salió a la calle Visual Studio 2005, y pudimos comprobar que era cierto: podemos detener la
<<dotNetManía
La depuración es una de esas cosas que todos hacemos, o deberíamos hacer,
y que a nadie le gusta tener que hacer; no porque no sea necesaria, sino porque al final terminabas fatal de los nervios cuando la depuración la realizabas con versiones anteriores de Visual Studio para .NET; por suerte, esto ya
no es así con Visual Studio 2005. En esta serie de dos artículos mostraremos
las principales posibilidades que este último entorno pone a nuestro alcance para facilitarnos la depuración de nuestros programas.
43
<< dnm.inicio
ejecución de la aplicación, hacer cambios en el código fuente y seguir ejecutando sin tener que volver a
empezar de cero. Y los que habitualmente usábamos
Visual Basic 6.0 incluso vimos muchas mejoras, ya que
el entorno de Visual Studio 2005 nos permite hacer
ciertos cambios en el código que no podíamos hacer
con VB6. Pero no voy a seguir haciendo comparaciones con Visual Basic 6.0; me voy a centrar en qué
es lo que podemos hacer y también en lo que no podemos hacer (ya que no podemos hacer todo lo que se
nos podría antojar: debemos tener en cuenta que todo
el proceso se realiza en tiempo de ejecución y durante ese tiempo, el CLR debe almacenar el estado de la
ejecución, almacenar en la pila lo que está ejecutando y otras muchas comprobaciones más, sobre todo
cuando se produce una excepción y hay un bloque
try/catch de por medio). Pero no empecemos con las
pegas, veamos los beneficios y ya iremos encontrándonos con las cosas que podemos y no podemos hacer
en nuestro camino hacia la tarea tediosa, pero necesaria de conseguir que nuestras aplicaciones estén
libres de fallos.
Los previos para la depuración
Cuando vamos a depurar aplicaciones con Visual Studio 2005, en realidad no tenemos que hacer casi nada
antes, pero al menos debemos permitir la depuración. Para permitir la depuración debemos ejecutar
nuestro código en modo Debug, ya que, (salvo que
usemos la versión Express) todos los proyectos de
Visual Studio 2005 permiten dos modos de compilación y ejecución: Debug y Release. Por regla general, (salvo que la hayamos ocultado), esas opciones
están en la barra de herramientas (botonera) de la
parte superior del entorno integrado, como podemos
ver en la figura 1.
hemos incluido código de gestión de la excepción en
el bloque correspondiente a la parte catch. Pero el
incluir un try con su correspondiente catch cuando
estamos depurando puede que no nos permita hacer
todo lo que nos gustaría hacer, ya que si tenemos un
bloque try/catch el error será interceptado y no sabremos a ciencia cierta dónde se produjo... o casi; al menos
en un proyecto grande, ya que ese bloque try/catch
que detecte el error puede que no esté donde a nosotros nos hubiera gustado que estuviera. Pero esta es
otra historia a la que volveré más tarde.
Si sabemos dónde se puede producir el error, podemos agregar un punto de interrupción antes del lugar
donde ocurrirá (ese lugar seguramente lo habremos
descubierto en una ejecución anterior). Podemos agregar un punto de interrupción pulsando la tecla [F9]
sobre la línea en la que queremos que se detenga la ejecución del programa. Al llegar a un punto de interrupción, la ejecución del programa se detiene, y podemos inspeccionar los valores de las variables, cambiar
dichos valores, ejecutar el código línea a línea (o instrucción a instrucción) y hacer muchas cosas más. Esas
“muchas cosas más” son las que en realidad son novedades en la forma de depurar de Visual Studio 2005,
ya que en las versiones anteriores también podemos
poner puntos de interrupción, inspeccionar las variables, etc. Ahora iremos viendo esas nuevas posibilidades de depuración con más detalle.
Sólo mi código
Cuando estamos depurando y ejecutando paso a
paso la aplicación (ahora veremos cómo), lo lógico es
que solo queramos inspeccionar nuestro código, es
decir, el código que nosotros hemos escrito. Esto lo
haremos marcando la opción “Habilitar Sólo mi código” en las opciones de depuración (“Herramientas”
> “Opciones” > “Depuración”, ver figura 2). De esta
Figura 1. Opciones de inicio en modo Debug en Visual Studio 2005
<<dotNetManía
Puntos de interrupción
44
Cuando estamos en “modo de depuración”, si se
produce una excepción (error) en tiempo de ejecución,
la ejecución (valga la redundancia) se detiene en el lugar
que se produce dicha excepción. Si tenemos un bloque
try/catch, dicha ejecución no se detendrá, al menos si
forma, el depurador no tendrá en cuenta el código
que no esté considerado como “mi código”.
Según la documentación de Visual Studio, éste es
el proceso que se sigue para determinar qué se considera como “mi código” (transcribo literalmente):
En una versión de depuración estándar, se desactiva
la optimización y se crean símbolos de depuración para
todos los módulos. Cuando se ejecuta una versión de depu-
<< dnm.inicio
Figura 2. Opciones de depuración: “Habilitar Sólo mi código”
Aunque esto no es totalmente cierto, al menos si lo tomamos al pie de la letra; ya que podemos añadir un proyecto a nuestra solución, indicar que no se generen los
símbolos de depuración (normalmente creando el fichero con la extensión .pdb) e incluso generarlo en modo
optimizado y aún así se considera que es parte de “mi
código”. Bueno, en realidad no se considera como “nuestro”, pero el IDE de Visual Studio nos advierte de que
si realmente no queremos que sea nuestro, pues... que
lo indiquemos, tal como vemos en la figura 3.
El aviso mostrado en la figura 3 nos indica que
en nuestro proyecto tenemos código que no está marcado para depurar o que está marcado para ser optimizado, pero en realidad ese aviso solo se mostrará
si no generamos los símbolos de depuración. La selección de la casilla de optimización no afecta y no será
causante de que se muestre ese mensaje.
ración, se considera que esos
módulos pertenecen a “mi
código”. Si se llama a una función de biblioteca que se optimiza y no tiene símbolos de
depuración, se considera que
no es “mi código”. “Solo mi
Figura 3. Advertencia de que si queremos hacer ciertas cosas,
código” le impide detenerse en
que lo indiquemos decuadamente
el código de biblioteca, opción
que puede desear en la mayoría
de los casos.
¿Cómo configurar el proyecto para generar o no los símAhora veremos qué significa esto y cómo podebolos de depuración?
mos definir parte de “nuestro código” como si no fuera “mi código” con idea de no detenernos en él cuanSi no queremos generar el fichero con la extendo estemos depurando.
sión .pdb, que es el causante de que se pueda depurar
Como veremos, (y tal como nos indica la ayuda
el código, tendremos que indicarlo en las opciones
de Visual Studio), tener habilitada la opción de “Solo
avanzadas de generación del código. Según trabajemi código” nos permite centrarnos en el código que
mos con Visual Basic o con C#, el nombre de esa
nosotros hemos escrito y que es el que en realidad nos interesa depurar. También nos ahorraremos mensajes extras del entorno de desarrollo cuando lo que se va a ejecutar está en
librerías externas o en librerías que no están
generadas con la opción de depuración.
Como hemos visto en la sección anterior,
podemos indicar al depurador de Visual Studio
que solo ejecute el código considerado como
“nuestro”.
¿Qué se considera como código nuestro? Tal
como nos indica la documentación de Visual Studio, cualquier código que tengamos referenciado en nuestro proyecto y no tenga símbolos de
depuración se considera que no es nuestro; todo
lo demás sí se considerará como nuestro código.
Figura 4. Opción de generación de símbolos
de depuración en C#
<<dotNetManía
Excluir código para la depuración
45
<< dnm.inicio
opción será diferente, pero ambas están en el mismo
sitio, o casi, al menos si tenemos en cuenta de que en
Visual Basic las opciones de generación está en la ficha
“Compilar”, mientras que en C#, esa ficha se llama
“Generar”.
Independientemente de cómo se llamen las opciones o dónde se encuentren, si no queremos que se
generen esos ficheros de depuración, lo que tenemos
que hacer es indicar el valor none en las opciones de
generación. En la figura 4 se muestra esa opción para
C# y en la figura 5 para Visual Basic.
miento se excluirá. Hay que tener en cuenta que este
atributo solo se tendrá en cuenta si hemos seleccionado la opción “Habilitar Sólo mi código”.
• DebuggerHidden. Este atributo solo se puede indicar
a nivel de procedimiento (ver el comentario anterior para saber qué se considera un procedimiento) y nos servirá para ocultarlo al depurador; de esa
forma, no podremos navegar por él en el proceso
de depuración, independientemente del valor que
hayamos asignado a la opción “Habilitar Sólo mi
código”.
• Por último, el atributo DebuggerStepThrough impedirá que Visual Studio tenga en cuenta el elemento al que se aplica el atributo (que puede ser una clase o un procedimiento), pero en el sentido de que
no podremos ir paso a paso por el código al que está
aplicado. A diferencia de DebuggerHidden, podemos
poner puntos de interrupción, por ejemplo, en el
cuerpo del procedimiento, y en ese caso se detendrá
la ejecución al llegar a ese punto de interrupción;
pero no nos permitirá la “navegación” paso a paso
(ahora veremos cómo podemos ejecutar el código
paso a paso). En realidad, ese punto de interrupción
solo se tendrá en cuenta si no tenemos habilitada la
opción “Habilitar Sólo mi código”.
De los tres atributos de ocultación de código al
depurador, DebuggerHidden es el único que siempre
oculta el código.
Figura 5. Opción de generación
de símbolos de depuración en C#
Indicar partes del código para excluirlo
de la depuración
<<dotNetManía
Si dejamos seleccionada la opción de generación de
símbolos de depuración y queremos excluir parte del
código del proceso de depuración, podemos usar ciertos atributos definidos en el espacio de nombres System.Diagnostics. Dependiendo de qué comportamiento queramos, podremos usar uno de estos tres
atributos:
46
• DebuggerNonUserCode. Este atributo le indica a Visual
Studio de que el elemento al que se aplica no se considere como código del usuario, es decir, no se tenga
en cuenta como “mi código”. Si el atributo lo aplicamos a una clase, la clase completa se excluirá del proceso de depuración. Si lo aplicamos a un procedimiento (método, constructor, etc.), solo ese procedi-
De los tres atributos de ocultación de
código al depurador, DebuggerHidden es
el único que siempre oculta el código
Ejecución paso a paso
Cuando estamos depurando una aplicación, usaremos los puntos de interrupción para que la ejecución se detenga al llegar a ellos. Una vez que hayamos detenido la ejecución del programa, podremos
ir navegando línea a línea o procedimiento a procedimiento, esto es lo que se conoce como ejecución
paso a paso.
<< dnm.inicio
[
Cambiar las combinaciones de tecla
Tal como he comentado en la nota, las teclas usadas para ejecutar en modo depuración son las predeterminadas de cada configuración de Visual Studio.
De todas formas, si preferimos usar otras combinaciones de teclas, siempre podremos modificarlas y elegir las que más nos gusten. Esto lo haremos cambiando
las combinaciones de las teclas desde las opciones de
configuración de Visual Studio. Si la tecla elegida ya
está asignada a otra opción, el propio entorno nos avisará, tal como vemos en la figura 6.
Figura 6. Al elegir una combinación de teclas,
si ya se está usando, nos avisará
Siguiente instrucción a ejecutar
Mientras estamos ejecutando paso a paso, la
siguiente instrucción (o línea) a ejecutar estará resaltada en amarillo y con una flecha en la parte izquier-
NOTA
Las teclas de depuración paso a paso cambian según la configuración de Visual Studio
Es importante resaltar que las teclas [F10] y [F11] son las predeterminadas para la configuración del
entorno de desarrollo para Visual C#,Visual Web Developer o la conocida como Configuración general
de desarrollo. Sin embargo si hemos seleccionado la configuración del entorno de desarrollo para Visual
Basic, esas teclas serán [Mayús]+[F8] y [F8], respectivamente.
Es importante saber que la configuración del entorno no depende del lenguaje, es decir, si trabajamos
con proyectos de Visual Basic y de C# las teclas siempre serán las mismas, ya que es el tipo de configuración
elegido el que asignará las teclas de depuración no el lenguaje usado.
La tecla [F9] se usa siempre, independientemente de la configuración seleccionada.
Como truco, comentar que yo (que normalmente uso Visual Basic para desarrollar) siempre suelo configurar el entorno de trabajo usando la configuración general, de esa forma uso siempre las teclas [F10] y
[F11] para navegar por el código.
]
<<dotNetManía
Cuando seleccionamos la opción “Paso a paso
por instrucciones” del menú “Depurar” o usamos la
tecla [F11], iremos “navegando” por cada una de las
instrucciones del código; si una de esas instrucciones es un procedimiento, entraremos en el procedimiento y podremos ir inspeccionando cada una
de las instrucciones que haya. Como ya comenté
antes, por procedimiento se entiende cualquier cosa
que no sea una clase (o tipo); es decir, una propiedad también es un procedimiento, y por tanto hay
veces que se hace tedioso este tipo de navegación
por el código, ya que se ejecutarán todas y cada una
de las instrucciones que tengamos
en “nuestro código”. Si no queremos entrar en los procedimientos,
es decir, ejecutarlos, pero no ir paso
a paso por cada una de las instrucciones incluidas en él, podemos
usar la opción “Paso a paso por
procedimientos” o bien usar la tecla
[F10]. Si estamos usando esta última forma de navegar por el código, siempre podremos usar la otra
opción para entrar en el procedimiento que nos interese.
Recordemos los atributos mencionados antes, ya que si hemos usado el atributo DebuggerStepThrough
solo podremos detenernos en ese
código si hemos puesto un punto de
interrupción; y aunque hayamos puesto ese punto de interrupción, una vez
en él, no podremos utilizar ninguna de las dos formas
de navegar por el código, ya que el IDE se saltará todo
el código que haya a continuación (saltar en el sentido
de no ir paso a paso), y seguirá por el código en el que
hayamos permitido la navegación.
47
<< dnm.inicio
ción a lo mejor no es tan importante, pero lo de la declaración sí que lo es, ya que no nos dará ningún error de
duplicidad de declaración. Esto es bastante útil, ya que
nos permite deshacer todo lo que hemos hecho para
probar nuevamente a ver por qué ese código no funciona como esperamos.
Inspeccionar el contenido de las variables
Figura 7. La línea de ejecución actual se resalta
en amarillo y los puntos de interrupción en rojo
da, tal como vemos en la figura 7. En esa misma figura vemos en rojo los puntos de interrupción.
En la figura 7 también podemos apreciar que los
dos puntos de interrupción del método Saludo tienen
una marca de advertencia y no están en rojo en la barra
de la izquierda; esto es así porque ese método está
marcado con el atributo DebuggerHidden.
La flecha amarilla indica qué es lo que se ejecutará
a continuación, es decir, que el código que se resalta
aún no se ha ejecutado, y si necesitamos cambiar la
localización de la siguiente instrucción a ejecutar, podemos cambiarla moviendo esa flecha a otra posición
dentro del código. Por supuesto, no podemos mover
ese indicador a cualquier parte, solo donde esté permitido; por ejemplo, si quisiéramos cambiarlo a otro
método, no nos lo permitiría: el cursor cambiará a un
signo de prohibido, tal como vemos en la figura 8.
Mientras estamos en modo depuración, con el código
detenido, podemos ver los valores que tienen todas las
variables que están en el ámbito actual. Es decir, si estamos en un método, podremos ver qué valores tienen
las variables que tengamos declaradas y que estén accesibles en ese punto del programa. Esos valores los podemos ver de dos formas distintas: una de ellas es seleccionando la variable a inspeccionar; si es una variable
simple, por ejemplo, una cadena, automáticamente se
mostrará una ventana emergente (tooltip) con el valor.
Esa ventana permite editar el valor, de forma que podemos cambiarlo in situ. Si la variable a inspeccionar tiene aplicado algún método o propiedad, entonces no
veremos el valor; bueno, sí que lo veremos, pero tendremos que ser finos a la hora de posicionar el cursor
del ratón en la variable. En cualquier caso, siempre nos
quedará la opción de seleccionar la variable al completo para poder mostrar el valor que contiene.
<<dotNetManía
Figura 8. El indicador de la siguiente instrucción
a ejecutar no nos permitirá cambiar de método
48
Cuando cambiamos la siguiente instrucción a ejecutar a una línea anterior a la que se está ejecutando
actualmente, todo el código que ya se haya ejecutado
se volverá a ejecutar. Esto es lógico, pero si en ese código tenemos declaraciones de variables o instanciamos
algún objeto, esas declaraciones volverán a ejecutarse
o el objeto volverá a instanciarse. Lo de la instancia-
Figura 9. La ventana de inspección de variables
<< dnm.inicio
Por fortuna para los que tenemos poco pulso, están
las ventanas de inspección de variables, en las que (tal
como podemos apreciar en la figura 9), tenemos dos
fichas en las que el propio entorno de desarrollo va agregando las variables que estén actualmente en un ámbito más próximo a la ejecución del programa. En el montaje de la figura 9 vemos esas dos fichas de la ventana de
inspección. En la ventana “Automático” se mostrarán
las variables que estén más cercanas a la posición de la
instrucción que se está ejecutando (habitualmente serán
las variables de la línea actual y la anterior), mientras
que en la ficha “Variables locales” se mostrarán todas
las variables del procedimiento actual. Como vemos en
esa figura, se muestran los valores de las variables, además
de que en esas ventanas también podemos cambiar los
valores de las variables.
Si en lugar de inspeccionar una variable simple
queremos ver el contenido de un objeto por referencia, por ejemplo, de un array, en ese caso se nos mostrará la información de una forma diferente, ya que
el contenido no es un solo valor. En la figura 10 podemos apreciar cómo se muestra el contenido de un array
de tipo string; en este caso, podemos acceder a los
valores individuales tanto de forma directa como desde la ventana de inspección.
Inspección personalizada de variables
Como vemos en las figuras 9 y 10, además de las
dos ventanas de inspección mencionadas, también
podemos utilizar otras con las variables u objetos que
Figura 11.Ventana de inspección rápida
Conclusiones
Con lo explicado en este artículo, tendremos una visión
general de parte de lo que la depuración con Visual
Studio 2005 (o superior) nos ofrece, aunque aún quedan cosas importantes de las que hablar. Pero eso será
en el próximo número de dotNetManía, en el que
veremos cómo utilizar todo lo relacionado con editar
y continuar y otras cosas relacionadas con la depuración y detección de errores, mientras tanto... ¡que lo
depure bien!
<<dotNetManía
Figura 10. La inspección de los arrays
nos permite acceder a los elementos individuales
nos interesen. Por ejemplo, si en una variable usamos
el método ToString() no se mostrará el valor de forma automática: para ver ese valor tendremos que crear lo que se conoce como una inspección rápida; la
forma de hacerlo (además de usando el menú contextual) es seleccionando la variable y pulsando
[Mayús]+[F9]. Esa acción hará que se abra un cuadro de
diálogo en el que se mostrará el resultado de la llamada a ese método además de permitirnos agregar
ese código a una ventana de inspección. En la figura
11 vemos ese cuadro de diálogo y los botones que nos
permiten agregar lo que estamos inspeccionando a la
ventana de inspección personalizada. También vemos
que hay un botón para actualizar el valor; esto es útil
si en lugar de mostrar lo que inicialmente habíamos
seleccionado queremos cambiar de idea y ver otras
propiedades u otros métodos, ya que en esa ventana
tendremos acceso a los elementos del objeto que estamos inspeccionando (en este ejemplo es una variable
de tipo entero, pero esa variable puede ser cualquiera de las que tengamos definidas en el procedimiento que actualmente se está ejecutando, e incluso de
otros procedimientos, al menos si están en ámbito).
49
todonet@qa
[email protected]
Dino Esposito
Dino Esposito
es mentor de Solid
Quality Learning. Es
ponente habitual en
los eventos de la
industria a nivel
mundial.Visite su
blog en: http://weblogs.
asp.net/despos.
(todotNet.QA@
dotnetmania.com)
Silverlight. Presente y futuro
Demasiadas promesas alrededor de Silverlight 1.0. La comunidad de desarrolladores esperaba mucho
de esta versión, pero existen muchas cosas para las que producto no ha sido diseñado y que hoy día
no pueden realizarse. Muchas de las expectativas generadas acerca de Silverlight se harán realidad
solamente cuando la próxima versión –en preparación para el verano de 2008– esté disponible. En
esta columna responderé a preguntas frecuentes sobre Silverlight y su relación con otras tecnologías
ricas para aplicaciones Web.
Parece que la mayoría de desarrolladores se centra en lo que Silverlight no puede hacer todavía,
en lugar de hacerlo en lo que sí puede hacerse con la versión 1.0 ya liberada. Así que mi pregunta es lógica: ¿cuál es el propósito de Silverlight 1.0? Soporta una pequeña porción de WPF y no
dispone de utilidades para desarrolladores, tales como controles o librerías de ayuda.Yo incluso
me preguntaría si es realmente utilizable… ¿nos puede dar su visión sobre esto?
Silverlight 1.0 no es producto para desarrolladores
Web. Sí que es, no obstante, un producto que juega un papel estratégico en la lucha y esperamos que
derrocamiento del ya vetusto Adobe Flash. Puedes
imaginártelo como una cabeza de puente lanzada en
el campo de batalla para proporcionar beneficios en
un futuro, pero no precisamente en este momento.
Más concretamente, la funcionalidad que Silverlight
puede ofrecer hoy –versión 1.0, como hemos dicho–
se limita a las capacidades multimedia y a mostrar
documentos WPF muy simples.
El fin último es decirle al mundo que Microsoft
ha sacado un anti-Flash, que cuenta, al menos, con
algunas pocas ventajas sobre éste. Primero, la descarga de documentos WPF no es una caja negra para
buscadores como Google u otros. Segundo, puede
reproducir formatos de creación pública, incluyendo WMV, WMA, MP3 y cualquier formato codificado en VC-1, la forma de codificación de la mayoría
de las películas en DVD. Y, finalmente, puede programarse utilizando un lenguaje estándar, no propietario, como Javascript. Para reproducir una película desde una página Web, ahora podemos olvidarnos de cualquier reproductor externo (como
Media Player) y usar solo Silverlight. Y Silverlight
es multiplataforma, soporta varios navegadores y se
inserta mediante una etiqueta <OBJECT>.
Para preparar un documento Silverlight, no se
necesitan obligatoriamente herramientas ad hoc.
Todo lo que hay que crear es un fichero XAML,
que no es más que un fichero con sintaxis XML.
Puedes usar las herramientas de la suite Expression
o incluso Visual Studio 2008. Pero en muchos casos
sencillos, el Bloc de notas es suficiente. Un fichero XAML describe su salida mediante un subconjunto de elementos de Windows Presentation
Foundation. Pero este subconjunto soportado es
extremadamente limitado, y no incluye campos de
entrada, elementos ubicables, estilos o enlace a
datos. Las capacidades limitadas de Silverlight 1.0
se derivan de estas características.
Silverlight se presenta en ocasiones, y se percibe a menudo, como la herramienta que hará posible a los desarrolladores construir aplicaciones ricas
para Internet (Rich Internet Applications, RIA) que
serán distribuidas vía Web, pero con características
prácticamente idénticas a las aplicaciones de escritorio Windows. Este es el destino final donde nos
exista una versión beta hasta primavera. Esta versión dispondrá de una gran cantidad de potentes características
programables para capacitar la creación de una auténtica capa de presentación basada en lenguajes administrados y objetos. Esta es la situación actual.
Asumiendo que he comprendido bien el rol y las perspectivas de Silverlight, yo diría que
WPF y Silverlight podrían eventualmente convertir las aplicaciones ASP.NET y AJAX en
obsoletas. ¿Qué le parece esa predicción?
No es algo tan descabellado. Sin embargo, yo creo firmemente que los dos mundos, Windows y Web, van a
permanecer separados durante la mayor parte del futuro predecible. Al mismo tiempo, eso sí, la llegada de WPF
y Silverlight genera posibilidades de interacción entre la
Web y Windows que ahora mismo son impracticables o
sencillamente imposibles.
Una vez que la próxima versión de
Silverlight esté disponible, podrás desarrollar para la Web con la mayoría de
las facilidades que tenemos hoy día en
el escritorio. Podrías incluso llegar al
punto de utilizar el mismo documento WPF para alimentar aplicaciones
Web y Windows en un sistema multicapa. Tengamos en cuenta, no obstante, que esto no sucede gratis, pero es
un escenario que el uso de patrones de
diseño adecuados (p.e., el modelo Vista-Presentador) puede hacer posible.
No estoy seguro de que la llegada
de Silverlight vaya a revolucionar el
mundo del desarrollo Web en la plataforma Microsoft hasta el punto de
eliminar a ASP.NET. Como Adobe Flash, se puede usar
Silverlight de dos formas: como el entorno o contexto
entero de una aplicación Web, o como un reproductor
de contenidos especiales en una página ASP.NET estándar. Según mi criterio, es esta segunda opción la que
será más ampliamente adoptada. En otras palabras,
todavía veo la Web del futuro cercano hecha de páginas
HTML con algunas islas WPF en su interior.
Silverlight 1.1 (o cual sea su nombre/número final)
va a ser una plataforma mucho más potente para la Web.
Basado en el conjunto de características conocido hoy,
con el añadido de un rico conjunto de etiquetas WPF,
Silverlight 1.1 incorporará un CLR muy ligero en el
navegador (en modo multiplataforma) para procesar lenguajes administrados (como C#, Visual Basic .NET, Javascript administrado o IronPython), una versión reducida
de .NET Framework –que incluirá extensiones LINQ–,
manejo de excepciones y clases ad hoc para manejar llamadas remotas a servicios. Al final, WPF y Silverlight
forman un poderoso dúo, pero tengo la sensación de que
la adopción amplia del producto estará condicionada a
las herramientas de programación que los equipos de
Microsoft pongan a nuestra disposición.
Todavía veo la Web del futuro cercano
hecha de páginas HTML con algunas
islas WPF en su interior
Probablemente, necesitaremos Silverlight para continuar con la exitosa programación basada en ASP.NET
con controles de servidor y extensiones del lado del cliente. Si Microsoft puede llegar a ofrecer esto, mi predicción es que la mayoría de los desarrolladores adoptarán
Silverlight como una poderosa herramienta para construir aplicaciones Web todavía más potentes. Por otro
lado, estamos en esta situación debido a una extraña conjunción astral: casi todos los navegadores soportan un
mismo (y potente) conjunto de características programables. Para que WPF y Silverlight destronaran a
ASP.NET y AJAX, todos los desarrolladores de todas las
plataformas deberían estar de acuerdo. Tecnológicamente
hablando, no hay nada que lo impida, pero, en la práctica, yo no apostaría por ello. Aunque sí veo un montón
de interacción entre ambos tipos de aplicaciones.
<<dotNetManía
llevará Silverlight, pero todavía está lejos de donde nos
encontramos hoy. La siguiente versión, actualmente etiquetada como Silverlight 1.1 y en fase alfa, probablemente nos lleve donde esperamos. Pero Silverlight 1.1
se espera para después del verano, y probablemente no
[email protected] [email protected]
<< dnm.todonet@qa
51
<<dotNetManía T o d o t N e t . q a @ d o t n e t m a n i a . c o m T o d o t N e t . q a @ d o t n e t m a n i a . c o m
<< dnm.todonet@qa
52
Intenté insertar un documento XAML en una página ASP.NET y no sucedió nada incluso en
máquinas equipadas con la última versión de Silverlight. ¿De qué forma puedo consumir
contenido XAML desde una página ASP.NET?
Silverlight no es una aplicación preparada para consumir cualquier contenido XAML servido a un navegador.
Si apuntas tu navegador a una URL que proporciona un
stream XAML, no deberías esperar ningún comportamiento especial en el navegador. La manera de usar Silverlight es ligeramente diferente.
Lo primero, inyectas una etiqueta <OBJECT> en una
página Web que apunte al motor de Silverlight para la
plataforma del navegador. El motor de Silverlight está
actualmente disponible para plataformas Mac y Windows y está siendo desarrollado para sistemas Linux por
el grupo Mono, en el marco de un proyecto que se conoce como Moonlight.
El motor de Silverlight se define en un script llamado
Silverlight.js, que debes enlazar a la página. Este fichero es parte del SDK de Silverlight. Contiene objetos de
ayuda, que pueden ser instanciados e inicializados para
que todo funcione como se espera. En una página Web
ASP.NET AJAX, usaríamos el siguiente código:
<script type="text/javascript">
function pageLoad()
{
var parent = $get("host");
createSilverlightHost(parent);
}
</script>
En una página HTML, simplemente ejecutas el código en el manejador del evento onLoad de esa página o
puedes situar un bloque <script> dentro de la etiqueta
<body>. La función CreateSilverlightHost() es una función definida por el usuario que inicializa la ventana Silverlight. Esta función debe ser vinculada a la página de
alguna forma. Normalmente, situamos el cuerpo de la
función en un script separado. A continuación inicializamos una ventana Silverlight:
function createSilverlightHost(parentElement)
{
Silverlight.createObject(
"xaml/customerview.xaml",
parentElement,
"SilverlightControl1",
{
width:'350',
height:'120',
background:'#111111',
version:'1.0'
},
{
onError:null,
onLoad:null
},
null);
}
El parámetro indica el contenedor de la ventana Silverlight, donde el contenido Silverlight será mostrado, en
la página. La ventana Silverlight recibe un ID –que es SilverlightControl1 en el código– para poder comunicar con
el resto de la página vía Javascript. Finalmente, se definen
el tamaño y la apariencia de la ventana. El contenido XAML
se identifica mediante una URL. El fichero es descargado
y procesado en forma local en el navegador del cliente.
Como el XAML se referencia mediante URL, nada impide que una aplicación ASP.NET genere dinámicamente el
contenido utilizando un manejador HTTP.
¿Hay algún sitio Web público que utilice Silverlight?
Desde luego que sí, ya empiezan a aparecer los primeros sitios que utilizan Silverlight 1.0 para los anuncios o contenidos multimedia1. De todos ellos, me gustaría señalar que http://www.tafiti.com es un ejemplo
de sitio potenciado mediante Silverlight. Tafiti semeja el comportamiento de Google y utiliza el motor de
Live Search para recoger información a partir de una
cadena de consulta. Su interfaz de usuario está enteramente basada en Silverlight, aunque en este momento contiene un montón de código de script. Así que,
después de todo, deberías considerar Tafiti como una
representación de las funciones que obtienes hoy de
Silverlight, pero no todavía del código que escribirás
cuando la versión siguiente esté disponible.
Traducido al castellano por Marino Posadas
1
Un sitio Web con tales características es http://www.mlb.com. Pero Dino seguramente no es aficionado al béisbol (N. del E. T.)
<< dnm.laboratorio.net
Octavio Hernández
Laboratorio.net
ILOG Diagrammer for .NET
Este mes presentamos ILOG Diagrammer for .NET, un marco de trabajo para la
edición y visualización de diagramas y cuadros de mando sacado recientemente
al mercado por la multinacional ILOG (http://www.ilog.com), que permite crear
sofisticadas y atractivas interfaces visuales para las aplicaciones Windows y Web
basadas en .NET Framework.
Nombre: ILOG Diagrammer for .NET
Versión: 1.0
Fabricante: ILOG
Sitio Web: http://www.ilog.com/
Categoría: Componentes de interfaz de
usuario
Precios:
• Licencia de desarrollo: 2.500 EUR.
• Licencia de despliegue: contactar con
ILOG
Octavio Hernández es
Development Advisor
de Plain Concepts,
editor técnico de
dotNetManía y tutor
de campusMVP.
Es MVP de C# desde
2004, MCSD y MCT.
ILOG Diagrammer for .NET es un potente conjunto de herramientas, componentes y librerías para
el desarrollo de aplicaciones de edición gráfica,
visualización, supervisión y monitorización para la
plataforma .NET, que simplifican sensiblemente
tareas como crear diagramas que permitan establecer o mostrar la relación entre objetos o monitorizar los parámetros de negocios o sistemas dinámicos de la más diversa índole. Las figuras 1 y 2
muestran ejemplos de tales actividades: mientras
que en la figura 1 se presenta una aplicación que
permite crear y manipular gráficamente diagramas
BPM (Business Process Management), en la figura 2
se muestra una aplicación que simula la monitorización en tiempo real del comportamiento del
tráfico en túneles subterráneos al estilo de los
recientemente inaugurados en Madrid. Estas dos
aplicaciones forman parte de los ejemplos que se
entregan con el producto.
Como complemento de las librerías que componen el SDK de ILOG Diagrammer for .NET, desarrollado al 100% en C#, la instalación del producto
integra dentro de Visual Studio 2005 dos nuevos tipos
de proyectos, las Aplicaciones ILOG Diagrammer y
las Librerías de Símbolos ILOG Diagrammer. Mediante el primer tipo de proyectos es posible crear de una
manera visual e interactiva proyectos que incluyan diagramas de los más diversos tipos; al estilo de como hace
Visual Studio cuando diseñamos un formulario Windows Forms, en la medida en que vamos arrastrando
elementos desde el Cuadro de herramientas hasta el
lienzo de diseño el add-in de ILOG Diagrammer va
generando el código fuente necesario para reproducir
el diagrama en tiempo de ejecución. Durante el diseño
de los diagramas, el Cuadro de herramientas de Visual
Figura 1. Editor BPM
Studio (figura 3) se enriquece con un amplio conjunto de símbolos gráficos pre-programados que están a
nuestra disposición desde el primer momento. Estos
símbolos no representan otra cosa que clases, por lo
que podemos aplicar sobre ellos los patrones familiares de desarrollo basados en el modelo PEM (Propie-
<<dotNetManía
Ficha técnica
53
<< dnm.laboratorio.net
Figura 2. Monitor de tráfico en túneles
• Modelado de diagramas de clases UML:
también se ofrecen controles para
representar los elementos y conectores típicos de la notación UML (Unified Modeling Language).
• Facilidad de creación de nuevos
controles gráficos. ILOG Diagrammer for .NET incluye un amplio conjunto de primitivas (rectángulos, elipses, rutas, líneas, curvas, arcos, textos,
imágenes, escalas y otros) y de contenedores comunes (lienzos, paneles
apilados o adosados, visores con desplazamiento) que pueden ser utilizados directamente o en combinación
con otros gráficos para crear nuevas
variaciones. El producto también permite importar gráficos en formato
SVG.
• Representación avanzada de grafos. El núcleo de la implementación
dades-Eventos-Métodos). El resto ya seguramente lo imagina el lector: los símbolos de la librería de ILOG Diagrammer
siguen un modelo de arquitectura abierta, y el segundo tipo de proyectos antes
mencionado permite precisamente desarrollar nuevas librerías de símbolos para
reutilizar en nuestros propios proyectos
o distribuir a terceros.
Características principales
<<dotNetManía
A continuación se enumeran las principales características del producto que
podrían ser de interés para los lectores:
54
• Amplia gama de controles listos para
su uso. El amplio conjunto de controles gráficos incluidos de serie en ILOG
Diagrammer for .NET permite satisfacer un amplio rango de necesidades
de los diseñadores gráficos en muchos
dominios de aplicación diferentes. Estos
controles incorporan un conjunto de
comportamientos e interacciones predeterminadas; en todos los casos, es
posible redefinir las propiedades y
métodos virtuales correspondientes
para crear nuevas variaciones. Los controles incorporados de serie en ILOG
Diagrammer for .NET se orientan a
los siguientes tipos de aplicaciones:
Figura 3. El Cuadro de herramientas de VS2005 durante la edición de diagramas
• Modelado y monitorización de procesos de negocio: se ofrece el conjunto
completo de símbolos de la notación BPMN (Business Process Modeling Notation).
• Monitorización de negocios: el producto incluye múltiples tipos de controles para el desarrollo de cuadros
de mando y paneles de monitorización para negocios, incluyendo
barras de progreso, relojes, visores
de gráficos comerciales y botones.
de ILOG Diagrammer for .NET
incluye una implementación eficiente de una estructura de datos para
representar grafos, entidades complejas que constan de nodos y enlaces que los interconectan. Esta estructura de datos es ideal para representar redes, procesos, flujos y cualquier
tipo de diagramas técnicos o de negocio. Cualquier control gráfico puede
servir como nodo de un grafo, y el
producto ofrece una amplia variedad
<< dnm.laboratorio.net
Noticias
• Infragistics (www.infragistics.com) acaba de sacar al mercado NetAdvantage for
.NET volumen 3, una nueva edición de la popular suite de herramientas de interfaz
de usuario para Windows y la Web. Entre las novedades más significativas de esta edición están la inclusión de nuevas metáforas de navegación asociadas a la experiencia
de usuario de Windows Vista y la adición de nuevas posibilidades de exportación a
XPS y PDF para permitir nuevos escenarios de compartición de documentos y generación de informes, en lo que respecta a NetAdvantage for ASP.NET. Asimismo, la
empresa ha presentado la CTP (Community Technology Preview) de Aikido, un nuevo
marco de trabajo para ASP.NET basado en AJAX.
• Iron Speed (www.ironspeed.com) ha puesto a disposición del público Iron Speed
Designer v. 5.0, una nueva versión de este potente generador de generación automática de aplicaciones Web, que incorpora una cantidad realmente impresionante de
novedades que harán el producto aún más útil y productivo para sus usuarios.
• Business Objects (www.businessobjects.com) acaba de anunciar Crystal Reports
2008, nueva versión (la duodécima) de la conocida herramienta de creación y ejecución de informes que permitirá a los usuarios alcanzar una mayor productividad, condensar una mayor cantidad de información en un informe evitando así la proliferación
de éstos, aumentar la interactividad de los informes e integrar objetos de Flash, Flex
y Xcelsius para producir informes más impactantes.
En el marco de esta sección, dotNetManía describirá en próximas ediciones las características
principales de estos productos.
• De rejilla. Caracterizado por el
hecho de que no se dibujan los
conectores; puede utilizarse en
cualquier caso en que se desee simplemente disponer gráficamente un
conjunto de elementos.
• Editores personalizables. Entre sus
ejemplos, el producto incluye tres editores independientes completos y con
código fuente incluido: un editor de
diagramas, un editor de
diagramas de clases UML
y el ya mencionado editor
de diagramas BPMN.
• Despliegue para el
escritorio o para el
navegador. Las aplicaciones creadas con ILOG
Diagrammer for .NET
pueden ser desplegadas
como aplicaciones Windows Forms o (con mínimos cambios) como aplicaciones ASP.NET con
soporte Ajax (basado en
las extensiones de Microsoft e independientes de
Figura 4. Editor de diagramas UML como
otro proveedor específiaplicación Web.
co). Este nivel de flexibilidad es especialmente útil si una misma aplicación
debe ejecutarse en diferentes plataformas. La figura 4 muestra al editor de
diagramas de clases UML ejecutándose como una aplicación Web.
Conclusión
En este artículo hemos descrito las principales posibilidades que ofrece ILOG
Diagrammer for .NET, un potente marco de trabajo en código manejado para
el desarrollo de interfaces gráficas interactivas para Windows y la Web. El alto
precio de salida del producto está sin
duda más que justificado por la calidad y
las prestaciones que ofrece; invito al lector a descargar la versión de evaluación
[1] y comprobarlas por sí mismo.
Referencias
[ 1]
Sitio Web del producto:
http://www.ilog.com/products/
diagrammernet.
<<dotNetManía
de tipos de conectores: rectos, curvilíneos, ortogonales, etc. para enlazar los nodos entre sí. Adicionalmente, el producto incluye toda una
serie de servicios avanzados como la
detección de intersecciones entre
conectores o la interconexión entre
diferentes grafos.
• Distribución automática de grafos.
ILOG Diagrammer for .NET ofrece un conjunto sofisticado de algoritmos para la distribución automática de los nodos y los conectores, que
a la vez que intentan satisfacer objetivos generales como la minimización
del área de dibujo necesaria, la minimización de la cantidad de intersecciones entre conectores, entre otros,
permiten al usuario de una manera
rápida distribuir los nodos del grafo
en dependencia del tipo de diagrama
que desea crear. Entre los algoritmos
de distribución disponibles están:
• Jerárquico. Generalmente utilizado
en aplicaciones de ingeniería eléctrica (diagramas de circuitos), ingeniería industrial (diagramas de procesos), gestión de software (diagramas UML, diagramas de flujo).
• Arbóreo. Ideal para la representación de diagramas organizativos,
diagramas de bases de datos o
mapas de sitios Web.
• Guiado por fuerza (force directed).
Utilizado en diagramas de redes de
telecomunicaciones o redes semánticas, entre otras aplicaciones.
55
comunidad.net
European Silverlight Challenge
El concurso de desarrollo de Silverlight se ha ampliado a toda Europa, aumentando también los premios. INETA Europa (http://europe.ineta.org), en colaboración con Microsoft, ha preparado esta competición que ya ha empezado y que
finalizará el día 31 de enero de 2008.
La competición se realizará en dos fases:
1. Competiciones Nacionales. Estas se realizarán de forma local en cada país
bajo la supervisión y apoyo del equipo de INETA.
2. Competición Europea (Gran Final). En ella participarán solo los participantes que hayan obtenido el primer premio con su aplicación ganadora.
Si crees en tu talento, apúntate y participa en la competición “European Silverlight Challenge” y gana, además del reconocimiento de la comunidad, fabulosos premios por un valor total de 160.000€ (según precio de mercado), incluyendo tickets para el MIX 2008 (con viaje y estancia incluidos), suscripciones
MSDN, etc.
El objetivo de la competición es desarrollar una aplicación, módulo o componente .NET en la que su interfaz de usuario esté desarrollada con la tecnología Silverlight. Esta participación deberá acatar la licencia MS-PL para poder
ser distribuida y utilizada gratuitamente por grupos de usuarios de INETA o de
cualquier otra comunidad en sus sitios Web y comunidades técnicas online.
Más información en http://silverlightchallenge.eu. Para participar en la competición española: http://desafiosilverlight.bcndev.net.
3º Aniversario GUSE.NET
Durante los días 23, 24 y 25 de noviembre se celebró el III Aniversario de
Gusenet, en Santa Pola (Alicante). Como
ya viene siendo habitual en este evento,
intentamos combinar las sesiones técnicas con un poquito de ocio que además
pueda ser compartido por nuestras parejas, con el objetivo de pasar un fin de semana completo, con diversas cenas, comidas,
visitas organizadas por la ciudad, etc.
Tuvimos una agenda interesante, en la que pudimos contar con excelentes ponentes,
y compuesta por dos sesiones sobre novedades que vamos a encontrar en Visual Studio 2008 y una mesa redonda sobre el pasado, presente y futuro del grupo, con aportaciones interesantes que empezaremos a poner en práctica en próximos eventos.
Centrándonos en las sesiones técnicas, comenzamos con una charla de nuestro
amigo “Guille”, que nos habló de las novedades de VB9, consiguiendo, además de
transmitir de forma muy clara dichas novedades, hacer una sesión muy amena, cargada de bromas y risas. Y cómo no, aprovechó para vender algún libro, camisetas
cuyo importe será donado a DotNetSolidario, y hacer algunos regalos.
A continuación pudimos contar con David Salgado, de Microsoft Ibérica, quien
nos habló principalmente de AJAX, haciendo una sesión muy interesante y participativa, donde invitó al público a hacerle todo tipo de preguntas, incluidas aquellas que no
iban directamente relacionadas con el tema en cuestión, consiguiendo así una excelente comunicación con el público, que pudo resolver cualquier duda que planteó.
CSLA.NET: introducción al framework de desarrollo CSLA.NET 3.0
El pasado 21 de noviembre tuvimos la enorme fortuna de poder contar con
la presencia de uno de los
grandes del mundo .NET,
Rockford Lhotka, que
aprovechando una estancia en Barcelona nos ha
honrado con una charla en
la que pudimos ver la
nueva arquitectura CSLA
3.5 (en desarrollo actualmente), con lo que fuimos honrados doblemente: con el gran speaker que es (además de
un gran escritor y arquitecto de software), así como con
la posibilidad de echar un vistazo al nuevo CSLA 3.5.
La sesión transcurrió sin problemas, totalmente en inglés
y con asistencia de público internacional vía Live Meeting. Por último, se regalaron dos de los últimos libros
sobre CSLA por parte de Lhotka al público, todo un
detalle por su parte. La sesión de firma de libros destapó
más de un fan de Lhotka oculto entre el público.
La experiencia se podría calificar de genial. Además
de que desde los inicios de la vida de BcnDev, sobre principios del 2006, teníamos muchas ganas de realizar una
sesión sobre CSLA, al final la ha realizado el mismísimo
Lhotka. Si tenéis la oportunidad de asistir a alguna sesión
suya, online o presencial, recomendamos altamente la
asistencia.
Yo, Robot
Si desarrollas con tecnología Microsoft, debes saber que no
solo puedes crear aplicaciones comerciales con Visual Studio, también puedes divertirte y mucho. En esta charla veremos algunas aplicaciones de Microsoft Robotics Studio y
LEGO Mindstorm, cómo trabajar con Visual Studio .NET
y un WiiMote, cómo controlar un helicóptero utilizando
Visual Studio y alguna sorpresita más.
El viernes 14 de diciembre tendrá lugar en el salón de
actos del Hospital Juan Ramón Jiménez de Huelva el
evento "Yo, Robot".
Registro: http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032358807&Culture=es-ES.
Como siempre, después del evento colgaremos los
materiales disponibles en nuestra sección de eventos
(http://www.onobanet.com/eventos/eventos.aspx).
biblioteca.net
Microsoft Expression Web Plain & Simple
Katherine Murray
Editorial: Microsoft Press
Páginas: 256
Publicado: octubre de 2007
ISBN: 978-0735625198
Idioma: inglés
Estamos trabajando con Expression Web desde su aparición, y la impresión es positiva, así que una obra sobre este tema (una de las primeras) merece la pena citarse, especialmente cuando viene directamente “de la casa”.
Es una obra cortita, que se lee –casi- del tirón, y decimos casi, porque merece la pena
perderse un poco en algunos de los ejercicios prácticos que presenta, para adquirir soltura con un producto que, una vez controlado, puede ser muy productivo. Que nadie
espere análisis en profundidad, pero es una obra idónea para los que se están iniciando
con las capacidades de la herramienta (que son bastantes). Cubre todas las tareas fundamentales para la creación de sitios profesionales y se deja ver la experiencia de la autora
(a más de la de usuario): tiene más de 40 libros publicados. Su lectura resulta didáctica y
divertida.
C# 3.0 y LINQ
Octavio Hernández Leal
Editorial: Krasis Press
Páginas: 290
Publicado: noviembre de 2007
ISBN: 978-8493548919
Idioma: castellano
novedades
Es un placer comentar esta obra por varias razones (algunas personales): es una de las
primeras en su género que se publican en castellano; algunas partes de su contenido las
habrá podido leer el lector en esta revista; y –además– se trata del Editor Técnico de dotNetManía. Una obra corta, pero, a diferencia de la anterior, intensa. Hay que decir también que, debido al formato de publicación que utiliza Krasis –con muy cuidada encuadernación en cartoné–, las casi 300 páginas del libro dan para bastante más de lo que se
podría adivinar detrás de esa cifra.
Octavio Hernández repasa en los primeros cuatro capítulos las novedades aportadas por el lenguaje a partir de la versión 2.0 (especialmente los tipos genéricos),
para pasar, a continuación, a abordar los fundamentos de LINQ y su reflejo en el lenguaje C# 3.0 y su librería básica de apoyo (LINQ to Objects). La última parte del
libro describe las posibilidades que ofrecen los principales proveedores de LINQ
contenidos en .NET 3.5, junto a abundantes ejemplos, probados hasta la última coma
(perdón, punto y coma).
Introducing Microsoft Expression Design
Greg Holden. Editorial: Course Technology PTR. Páginas: 600. Disponible: enero de 2008.
ISBN: 978-1598631562. Idioma: inglés.
Microsoft Expression Blend Unleashed
Brennon Williams. Editorial: SAMS. Páginas: 500. Disponible: junio de 2008. ISBN: 9780672329319. Idioma: inglés.
TEXTO: MARINO POSADAS
desván
Marino Posadas
<<dotNetManía
El ADN como lenguaje de programación
58
Se había intentado antes, pero el proyecto de investigación dirigido por Erik
Winfree, profesor de ciencias de la
computación en el Instituto de Tecnología de California, puede considerarse el primer intento serio de reunir bioquímica e informática. “Podemos
diseñar una serie de estructuras capaces
de crear patrones complejos, circuitos,
y motores”, afirmó respecto a las pruebas obtenidas creando patrones y estructuras de ADN en tubos de ensayo, Winfree, quien además se define como un ferviente creyente de
que la anunciada (pero todavía no producida) comunión entre
las dos disciplinas científicas está a punto de producirse, añadía:
“No se trata de quedarnos en el mero ensamblado de formas
geométricas utilizando ADN. Si entendemos el lenguaje,
podríamos diseñar respuestas biológicas a través de la re-programación, para terminar con virus reales”.
De cualquier forma, Winfree no es el único que investiga seriamente con esta posibilidad. Hace ya algún tiempo, la doctora Lila
Kari de la University of Western Ontario (Canada), especializada
en lenguajes formales, ganó el premio Florence Bucke por sus trabajos de recombinación genética del ADN, en los que demostraba que, teóricamente, se podría utilizar este tipo de combinación
para simular cualquier operación de las realizadas habitualmente
por un ordenador. La forma de plantear los problemas sería lo más
complejo y duradero, mientras que el tiempo de cálculo se reduciría de forma tan drástica, que proposiciones que ahora escapan
al cálculo de la mayoría de los ordenadores (o sea, que tardarían
años en realizarse) podrían resolverse en cuestión de horas.
Y es que las conexiones entre
bioquímica e informática son cada
vez más numerosas. Lo último en
conexiones directas lo presentaba
hace poco un grupo de científicos
de la Universidad de Arizona, dirigidos por Charles M. Higgins,
quienes han construido un robot
cuyo movimiento está vinculado al
cerebro de una polilla (como lo
oyen). El dispositivo (ver foto adjunta) conecta el cerebro de la polilla
(inmovilizada en un tubo de ensayo
especial, y rodeada de dibujos que –al moverse– le sugieren movimiento) con el robot, y cuando el escenario de control genera la
sensación de movimiento el robot responde de varias formas. Higgins afirma haber construido el dispositivo como medio de estudio neuronal, pero otros colegas afirman que podría utilizarse en
sentido inverso; esto es, sugiriendo reacciones en el cerebro
mediante movimientos robotizados. Para más información sobre
este último experimento, ver el artículo de Physics.org:
http://www.physorg.com/news114715561.html.
noticias.noticias.noticias
documentos en la red
¿Utiliza Captchas como
Webmaster? Si cree que son
seguros, no se pierda este artículo sobre las vulnerabilidades
de estos gráficos que supuestamente permiten diferenciar la
percepción humana de las acciones de los bots en la red. En el
artículo Has CAPTCHA Been "Broken"? (http://www.codinghorror.com/blog/archives/001001.html), Jeff Atwood (Coding
Horror) analiza las vulnerabilidades de estos mecanismos e
incluso indica la página Web de un hacker chino que consigue
romper la mayoría de ellos.
¡SQL Server 2008 podrá ser administrado mediante
PowerShell! Jeffrey Snover (Microsoft) anunciaba recientemente en el blog del equipo de desarrollo de Windows
PowerShell esta noticia que –sin duda– merece la pena leer
tanto si se está en el mundo de IT, como en el de desarrollo o se es un DBA. Para más datos, visitar:
http://blogs.msdn.com/powershell/archive/2007/11/13/
sql-server-support-for-powershell.aspx.
sitios del mes
La propia MSDN recoge la
actividad de los bloggers más
destacados (no conocemos el
criterio que siguen), y los agrupa en páginas para los interesados en un lenguaje o tecnología determinados. Este es el
caso de Visual Basic Blogs (http://msdn2.microsoft.com/
en-us/vbasic/ms789067.aspx#mvp) donde aparecen algunos de
los autores habituales de esta revista.
utilidades del mes
Recover Keys. Una más que útil herramienta ahora que
todos los programas tienen claves, y no siempre hemos
prestado atención a dónde las guardábamos. Es capaz de
recuperar claves de más de 140 productos. Una tranquilidad y solo un 1 Mb de descarga (el programa costará
20$ en el futuro, pero es gratuito en la actualidad por
tiempo limitado, otra razón para descargarlo pronto…)
El sitio: http://www.giveawayoftheday.com/recover-keys.
bCheck: un sitio de utilidades. Se trata de pequeñas utilidades –algunas no ocupan más de 12K–, pero son gratuitas
y algunas pueden resultar extremadamente útiles. Como
HoeKey, que permite configurar el teclado como se quiera (cualquier combinación, cualquier programa), o Capster, que ejecuta cualquier programa al inicio de Windows
solo si la tecla de control está pulsada, o Reso, que lanza
una aplicación en la resolución favorita del usuario devolviendo el sistema al estado en que se encontraba al salir
de ésta. Por cierto, si alguna vez podemos decir de un sitio
que es minimalista al máximo, es éste: http://www.bcheck.net.

Documentos relacionados