DevWorx Learning Center

by Misael Monterroca 12. February 2008 13:42

Como bien ya lo mencionó Rocky estamos estrenando nuestro DevWorx Learning Center en el cual estaremos generando contenido gratuito sobre la plataforma Microsoft.

 

Estamos comenzando a generar contenido para:

Los cursos se dividirán en varias secciones (el esqueleto ya está generado en cada uno de los sitios) pronto habilitaremos una sección de notificación de contenido vía RSS o e-mail para que puedan estar enterados cada vez que haya nuevo material. Esperamos que esta iniciativa sea de mucha utilidad para ustedes.

 

Si quieren que abordemos un tema en particular no duden en mandarnos un correo.

 

Saludos!

Tags: , , ,

Comunidades | .Net | DevWorx Learning Center | Learning

ScreenCast : WCF Exponiendo un servicio

by Misael Monterroca 6. February 2008 08:12

Este screencast es la continuación de WCF Introducción

 

En este screencast veremos como exponer un WCF Service Library, los temas que son tratados son:

  • EndPoint
  • Bindings
  • Host
  • Medatada

Url WMV para descarga (mejor definición)
Url Flash para ver Online

Tags: , , ,

Comunidades | .Net | ScreenCast | WCF

Conceptos básicos de programación 3d en WPF

by Misael Monterroca 29. January 2008 12:42

 

En este articulo conoceremos los conceptos básico de programación en tercera dimensión para Windows Presentation Foundation

 

Durante muchos años el escribir programas que generasen modelos en 3D estaba limitado a aquellas personas que supieran tecnologías como OpenGL o DirectX y lenguajes no siempre muy sencillos de usar como C++. En WPF se inicia un nuevo panorama en la programación de modelos tridimensionales de que con relativa facilidad es posible crear modelos en 3D utilizando clases predefinidas que trae el .NET Framework desde luego pudiendo ser uso de los lenguajes de programación como C# y VB o o bien utilizando el XAML.

El sistema de gráficos de tercera dimensión de Windows Presentation Foundation se encuentra completamente integrado al sistema de graficos 2D y todos los elementos y primitivas visuales que son válidos en el entorno 2D también serán válidos en el trabajo en tercera dimensión, por ejemplo sabemos que para generar un gradiente utilizamos el elemento <LinearGradientBrush> . De la misma manera podemos utilizar la misma técnica para generar una textura que tiene cualquier objeto generado en tercera dimensión con el mismo método sin necesidad de aprender algo nuevo.

Esto representa una gran ventaja para los desarrolladores toda vez que no es necesario aprender un lenguaje diferente u objetos distintos para manejo de gráficos de tercera dimensión si no que es posible reutilizar todo el conocimiento adquirido con el dibujo 2D y simplemente aprender a algunos conceptos nuevos propios del modelo de 3D.

Generando un objeto 3D con WPF

1) El elemento ViewPort3D nos brinda la capacidad de dibujar una escena tridimensional en una superficie de dos dimensiones.

Este elemento expone la colección Children que es una colección de objetos ModelVisual3D dentro de los cuales implementaremos nuestras escenas tridimensionales. El código requerido es el siguiente

XAML:

<Viewport3D ClipToBounds="True" Width="150" Height="150">
 
<Viewport3D.Children>
 
<ModelVisual3D>
 
</ModelVisual3D> 
 
</Viewport3D.Children>
 
</Viewport3D>
 

2) Dentro del elemento ModelVisual3D podemos especificar cualquier dibujo que deseemos. Sin embargo a diferencia de los gráficos en dos dimensiones donde existen primitivas predefinidas para dibujar objetos como elipses o rectángulos, en el mundo de 3D únicamente contamos con una clase denominada MeshGeometry3D en la cual es posible especificar un conjunto de vértices de triángulos mediante la propiedad Positions. Esto se debe a que cualquier dibujo tridimensional es posible describirlo con triángulos. Recordemos lo que sucede en los juegos de video: cuando hacemos un acercamiento fuerte alguna escena tridimensional podemos apreciar que las puntas y contornos de los objetos se tornan triangulares, esto se debe a que muchos objetos de los videojuegos, al igual que en WPF, son conjuntos de triángulos, que mediante su composición dan la sensación de un objeto tridimensional.

Nota: En el caso de WPF en .NET 3.5 se agrega un nuevo elemento llamado Viewport2DVisual3D que permite de una manera más sencilla generar una vista tridimensional a partir de la descripción de un objeto 2D.

Regresando a nuestro ejemplo una vez que hemos definido nuestra superficie de dibujo procederemos a utilizar la propiedad ModelVisual3D.Content para dentro de la misma especificar un MeshGeometry3D, en este caso con las posiciones establecidas estaremos generando un cuadrado

XAML

<ModelVisual3D.Content>
 
<GeometryModel3D>
 
<GeometryModel3D.Geometry>
 
<MeshGeometry3D
 
Positions="-0.5,-0.5,0.5 0.5,-0.5,0.5 0.5,0.5,0.5 0.5,0.5,0.5 -0.5,0.5,0.5 -0.5,-0.5,0.5 " />
 
</GeometryModel3D.Geometry>
 
</GeometryModel3D> 
 
</ModelVisual3D.Content>

3) A diferencia de lo que sucede con los objetos 2D donde el concepto de luz no existe, en 3D es indispensable especificar una fuente de luz debido a que si no existe ésta simplemente nuestro objeto no será visible de la misma manera que sucede en la misma vida real. Esto significa debemos de especificar el lugar que estará irradiando la luz y el tipo de material del cual se compone nuestro objeto es decir si éste es reflejante o no.

WPF especifica tres tipos de materiales el SpecularMaterial que refleja la luz de tal manera que el objeto parece brillar, el EmissiveMaterial que refleja la luz y el DiffuseMaterial que no refleja la luz.

En nuestro ejemplo utilizaremos el material DiffuseMaterial. Para especificar el tipo de material del cual se compone nuestro Mesh hacemos uso del siguiente código dentro de GeometryModel3D:

XAML

<GeometryModel3D.Material>
 
<DiffuseMaterial Brush="Red" ></DiffuseMaterial>
 
</GeometryModel3D.Material>

4) Dentro del mundo de tercera dimensión los objetos cambian de apariencia desde el punto de vista de quien observa al objeto. En WPF especificamos este punto de vista haciendo uso de los objetos que heredan de ProjectionCamera.

Controlamos a nuestras cámaras como si en verdad la cámara estuviera posicionada en el espacio, la propiedad Position es del tipo Point3D y especifica las coordenadas en la cual se encuentra la cámara.

XAML:

<Viewport3D.Camera>
 
<PerspectiveCamera Position="0,0,2"/>
 
</Viewport3D.Camera>

Si nosotros ejecutamos el código que llevamos hasta el momento veremos lo siguiente.

 

Aquí antes que nada podemos ver que se generó un cuadrado derivado de los vértices que se le especificaron al elemento MeshGeometry3D. Como aún no hacemos ninguna transformación de nuestro objeto no podemos ver la profundidad que tiene. Añadiremos una transformación posteriormente. Otro aspecto que podemos resaltar es que a pesar de que el material especificado con DiffuseMaterial fue de color Red estamos viendo que nuestro programa muestra el cuadrado en color negro. Esto se debe a que aún no hemos especificado la manera en la cual llega la luz al objeto, estos pasos los haremos a continuación.

5) Para agregar una fuente de luz a nuestra escena, dentro de ViewPort3D.Children especificaremos el siguiente código

XAML:

<ModelVisual3D>
 
<ModelVisual3D.Content>
 
<DirectionalLight Color="White" Direction="-0.5,-0.1,-0.5" />
 
</ModelVisual3D.Content>
 
</ModelVisual3D> 

6) Al ejecutar el código del listado previo podemos ver que ahora nuestro objeto está reflejando la luz y por lo tanto mostrando el color que se le especificó previamente.

7) Procederemos ahora generar una transformación dentro del elemento GeometryModel3D que nos permitirá ver a nuestro objeto en profundidad y de esta manera percibir el efecto de tercera dimensión. Para realizar este objetivo es necesario hacer uso de la clase RotateTransform3D que funciona de una manera similar a su equivalente bidimensional, pero a diferencia del segundo, en el primero hacemos uso de 3 dimensiones para rotar al elemento deseado. A continuación se muestra el uso de este objeto

XAML:

<GeometryModel3D.Transform>
 
<RotateTransform3D>
 
<RotateTransform3D.Rotation>
 
<AxisAngleRotation3D Axis="0,3,0" Angle="40" />
 
</RotateTransform3D.Rotation>
 
</RotateTransform3D>
 
</GeometryModel3D.Transform> 

8) Para finalizar nuestro ejemplo animaremos la propiedad Angle de la transformación. La sintaxis para hacer animación en elementos 3D es exactamente la misma que para los objetos bidimensionales. (ver capítulo “Animación”). Con esta animación veremos que el objeto está moviéndose de una manera circular.

El código requerido es el siguiente:

XAML

<Viewport3D.Triggers>
 
<EventTrigger RoutedEvent="Viewport3D.Loaded">
 
<BeginStoryboard>
 
<Storyboard>
 
<DoubleAnimation From="1" To="360" Duration="0:0:03" AccelerationRatio="1" RepeatBehavior="Forever" 
 
Storyboard.TargetProperty="(Viewport3D.Children)[1].(ModelVisual3D.Content).(GeometryModel3D.Transform).(RotateTransform3D.Rotation).(AxisAngleRotation3D.Angle)"></DoubleAnimation>
 
</Storyboard>
 
</BeginStoryboard>
 
</EventTrigger>
 
</Viewport3D.Triggers>
 

El código completo de todo el ejemplo es el siguiente:

XAML

<Grid>
 
<Viewport3D ClipToBounds="True" Width="150" Height="150">
 
<Viewport3D.Camera>
 
<PerspectiveCamera Position="0,0,2"/>
 
</Viewport3D.Camera>
 
<Viewport3D.Children>
 
<ModelVisual3D>
 
<ModelVisual3D.Content>
 
<DirectionalLight Color="White" Direction="-0.5,-0.1,-0.5" />
 
</ModelVisual3D.Content>
 
</ModelVisual3D> 
 
<ModelVisual3D>
 
<ModelVisual3D.Content>
 
<GeometryModel3D>
 
<GeometryModel3D.Geometry>
 
<MeshGeometry3D
 
Positions="-0.5,-0.5,0.5 0.5,-0.5,0.5 0.5,0.5,0.5 0.5,0.5,0.5 -0.5,0.5,0.5 -0.5,-0.5,0.5 " />
 
</GeometryModel3D.Geometry>
 
<GeometryModel3D.Material>
 
<DiffuseMaterial Brush="Red" ></DiffuseMaterial>
 
</GeometryModel3D.Material>
 
<GeometryModel3D.Transform>
 
<RotateTransform3D>
 
<RotateTransform3D.Rotation>
 
<AxisAngleRotation3D Axis="0,3,0" Angle="40" />
 
</RotateTransform3D.Rotation>
 
</RotateTransform3D>
 
</GeometryModel3D.Transform> 
 
</GeometryModel3D> 
 
</ModelVisual3D.Content>
 
</ModelVisual3D> 
 
</Viewport3D.Children>
 
<Viewport3D.Triggers>
 
<EventTrigger RoutedEvent="Viewport3D.Loaded">
 
<BeginStoryboard>
 
<Storyboard>
 
<DoubleAnimation From="1" To="360" Duration="0:0:03" AccelerationRatio="1" RepeatBehavior="Forever" 
 
Storyboard.TargetProperty="(Viewport3D.Children)[1].(ModelVisual3D.Content).(GeometryModel3D.Transform).(RotateTransform3D.Rotation).(AxisAngleRotation3D.Angle)"></DoubleAnimation>
 
</Storyboard>
 
</BeginStoryboard>
 
</EventTrigger>
 
</Viewport3D.Triggers> 
 
</Viewport3D>
 
</Grid>
 

 

Articulo Publicado en http://desarrollador.redusers.com/

Tags: , ,

.Net | Articulos | WPF

Distintos tipos de Actividades Predefinidas

by Misael Monterroca 29. January 2008 00:47

Distintos tipos de Actividades Predefinidas

Workflow Foundation incluye una gran variedad de actividades predefinidas que podemos utilizar al crear nuestros propios flujos de trabajo. En este articulo veremos algunas de las actividades más destacables incluidas en esta plataforma.

Code

Clase: System.Workflow.Activities.CodeActivity

La actividad Code es una de las actividades más usadas en Workflow Foundation, ya que nos permite ejecutar cualquier tipo de código escrito dentro de un método. Su propiedad más importante es ExecuteCode la cual establece el nombre del método que queremos que se ejecute. En algunos capítulos hemos visto incluso el uso de esta actividad y su importancia que tiene al desarrollar flujos de trabajo. La siguiente figura muestra el resultado de un flujo de trabajo que utiliza esta actividad la cual ejecutará el método MetodoAEjecutar(), siendo el código de ese método el siguiente:

private void MetodoAEjecutar(object sender, EventArgs e) 
 
{ 
 
Console.WriteLine("Hola Workflow Foundation"); 
 
} 
 

Sequence

Clase: System.Workflow.Activities.SecuenceActivity

La actividad Sequence nos permite ejecutar otras actividades en un orden específico, ya que asimismo esta actividad es un contenedor de otras actividades. Un buen ejemplo de una actividad Sequence son los flujos de trabajo de tipo Sequential Workflow, en donde podemos definir diversas actividades para que se ejecuten de manera ordenada o secuencial.

Los flujos de trabajo de tipo Sequential Workflow son instancias de la clase System.Workflow.Activities.SequentialWorkflowActivity, la cual a su vez hereda de la clase System.Workflow.Activities.SequenceActivity.

La siguiente figura muestra el diseñador de Workflow Foundation con una actividad Sequence con tres actividades de tipo Code. El código de esas actividades es el siguiente:

private void Metodo1(object sender, EventArgs e) 
 
{ 
 
Console.WriteLine("Code 1"); 
 
} 
 
 
 
private void Metodo2(object sender, EventArgs e) 
 
{ 
 
Console.WriteLine("Code 2"); 
 
} 
 
 
 
private void Metodo3(object sender, EventArgs e) 
 
{ 
 
Console.WriteLine("Code 3"); 
 
} 
 

 

Por otro lado, al ejecutar el flujo de trabajo de la figura anterior obtenemos el resultado de la siguiente figura. Nótese como efectivamente el código es ejecutado en el orden establecido.

WWF_Actividades_b

Parallel

Clase: System.Workflow.Activities.ParallelActivity

La actividad Parallel como su nombre lo indica permite a un flujo de trabajo ejecutar paralelamente dos o más actividades. Parallel hace uso de la actividad Sequence para definir la serie de actividades que requieren ejecutarse en cada ramificación que definamos. La siguiente figura muestra un flujo de trabajo que implementa esta actividad con cuatro ramificaciones que incluyen cuatro actividades de tipo Code (codeActivity1, codeActivity2, codeActivity3, codeActivity4). El código de los métodos relacionados con esas actividades es el siguiente:

WWF_Actividades_2

 

 

El resultado de la ejecución de este flujo de trabajo será el siguiente:

WWF_Actividades_3 

Es importante aclarar que si bien la actividad Parallel define actividades que se ejecutarán de manera paralela no significa que se ejecutarán al mismo tiempo. Esto obedece a que Workflow Foundation asigna un solo hilo de ejecución para cada instancia de un flujo de trabajo. Esto es por diseño.

 

Delay

Clase: System.Workflow.Activities.DelayActivity

Esta actividad permite definir un retraso de tiempo. Su propiedad más importante es TimeoutDuration la cual especifica la duración en tiempo de ese retraso. La siguiente figura muestra el resultado de agregar esta actividad a la segunda rama del ejemplo de la actividad Parallel, con un retraso de 10 segundos. Podemos observar como efectivamente el retraso de tiempo provoca que el mensaje de codeActivity2 sea desplegado hasta el último lugar.

WWF_Actividades_4

 

While

Clase: System.Workflow.Activities.WhileActivity

La actividad While nos permite ejecutar una serie de actividades de manera cíclica, usando un método que funcione como expresión condicional. Su propiedad más importante es Condition con la cual precisamente definimos el tipo de condición a utilizar (Code Condition o Declarative Rule Condition). En el caso de seleccionar Code Condition necesitamos definir el nombre del método relacionado que fungirá como condicionante para que la actividad While continúe ejecutando iterativamente. El método relacionado con esta actividad debe tener la siguiente signatura:

void NombreDelMetodo(object, ConditionalEventArgs) 

ConditionalEventArgs tiene la propiedad Result de tipo bool. Esta propiedad le indica al runtime de Workflow Foundation si la condición es verdadera o falsa. En este caso para la actividad While si Result es true significa que debe continuar su ejecución de manera cíclica. Si Result es false el ciclo de While es finalizado y continúa la ejecución de la siguiente actividad definida después de While. Veamos un ejemplo de esta actividad.

La siguiente figura muestra el diseñador de Workflow Foundation con una actividad While, la cual contiene una actividad Code. El código relacionado con la actividad Code es el siguiente:

int contador = 1; 
 
 
 
private void Metodo1(object sender, EventArgs e) 
 
{ 
 
Console.WriteLine(contador); 
 
contador++; 
 
} 
 

WWF_Actividades_5

Es necesario hacer notar que hemos definido una variable a nivel de clase llamada int contador. Esta variable nos servirá para desplegar su valor en la consola por cada ejecución iterativa de la actividad Code dentro de While. Para la actividad While hemos establecido que Condition es de tipo Code Condition, y hemos definido el método ChecaCondicion() el cual se encargará de evaluar si la condición ha sido alcanzada. El código de ChecaCondicion() es el siguiente:

private void ChecaCondicion(object sender, ConditionalEventArgs e) 
 
{ 
 
e.Result = contador<=20?true:false; 
 
} 

Si analizamos el código del método ChecaCondicion() podemos observar que estamos evaluando que la actividad While seguirá iterando siempre y cuando la variable llamada contador sea igual o menor que 20. Ya que la variable contador se inicializa con el valor de 1, tal y como esperamos, la consola desplegará los números del 1 al 20 ya que al llegar al 20 la condición evalúa a falsa y While alcanza su fin. Esto lo podemos corroborar en la siguiente figura:

WWF_Actividades_6

Throw

Clase: System.Workflow.ComponentModel.ThrowActivity

La actividad Throw nos permite lanzar excepciones dentro de un flujo de trabajo en Workflow Foundation. Esta actividad nos será de mucha utilidad cuando detectemos que el comportamiento o valores dentro de nuestro flujo de trabajo han alcanzado un estado inconsistente y por ello necesitemos parar la ejecución del flujo. Su propiedad más importante es FaultType, la cual indica qué tipo de excepción es la que arrojará esa actividad.

Para poder demostrar el uso de la actividad Throw, usaremos el mismo flujo de trabajo usado para la actividad While, sin embargo después (abajo) de la actividad While arrastraremos la actividad Throw de la caja de herramientas y la colocaremos en el diseñador. La siguiente figura muestra la caja de diálogo "Browse and Select a .NET Type", en donde podemos buscar y definir el tipo de excepción que la actividad Throw arrojará. Para este ejemplo usaremos la excepción de tipo System.ApplicationException la cual está implementada en mscorlib.

WWF_Actividades_7

La segunda propiedad importante para esta actividad es Fault, la cual nos permite definir una propiedad o campo para ligar la excepción. La siguiente figura muestra la caja de diálogo "Bind 'Fault' to an activity's property". En esta caja de diálogo podemos seleccionar un miembro existente o crear un nuevo miembro. En nuestro caso en este ejemplo crearemos un nuevo miembro ya que no hemos escrito código hasta el momento. Podemos seleccionar que la excepción se ligue a una variable o a una propiedad, en nuestro caso usaremos un campo llamado workflow_exception.

WWF_Actividades_8

Una vez definida y configurada la actividad Throw, veamos en la siguiente figura cuál es el resultado de la ejecución de este flujo de trabajo.

WWF_Actividades_9

Como podemos observar, después de desplegar los valores del contador la consola nuestra el mensaje de error relacionado con esa excepción. Ahora bien, podemos darnos cuenta que la ejecución del flujo de trabajo es suspendida gracias a que se está arrojando una excepción de tipo ApplicationException. En la siguiente parte veremos la actividad FaultHandler la cual nos permite capturar cualquier tipo de excepción y manejarla apropiadamente.

FaultHandler

Clase: System.Workflow.ComponentModel.FaultHandlerActivity

La actividad FaultHandler nos permite manejar apropiadamente las excepciones que sean arrojadas por las actividades Throw dentro de nuestros flujos de trabajo en Workflow Foundation. Para demostrar su uso continuaremos usando el proyecto de flujo de trabajo usado en la demostración de la actividad Throw. En un flujo de trabajo podemos definir uno o más actividades de tipo FaultHandler para definir las actividades que deben ser ejecutadas al estar capturando la excepción. Para realizar esto necesitamos cambiar la vista de nuestro diseñador para desplegar la lista de FaultHandlers. Esto lo logramos haciendo clic en la lista desplegable que se muestra al acercar el cursor a la fecha verde de inicio de nuestro flujo de trabajo, tal y como lo muestra la siguiente figura:

WWF_Actividades_10

Al cambiarnos de vista podemos observar que el diseñador de Workflow Foundation crea una actividad FaultHandlersActivity (nótese el nombre en plural), la cual es un contenedor de actividades de tipo FaultHandlerActivity. En esta actividad podemos arrastrar y colocar una o más actividades de tipo FaultHandler para así definir en cada una la serie de actividades que deseamos que se ejecuten al estar manejando la excepción. La actividad FaultHandler tiene la propiedad FaultType, la cual nos sirve para definir el tipo de excepción que esta actividad puede capturar. La siguiente figura muestra el diseñador con una actividad de tipo FaultHandler a la que se le ha definido la propiedad FaultType como System.ApplicationException (para efectivamente capturar la excepción que arroja Throw) y dentro de esta actividad se ha colocado una actividad de tipo Code con el siguiente código relacionado:

private void ErrorManejado(object sender, EventArgs e) 
 
{ 
 
Console.WriteLine("Error manejado!"); 
 
} 

WWF_Actividades_11

Como podemos deducir, al ejecutar el flujo de trabajo la actividad FaultHandler captura la excepción arrojada por la actividad Throw y despliega efectivamente el mensaje "Error manejado!" en la consola, en vez de desplegar el mensaje por defecto de la excepción. Vale la pena mencionar que cada actividad FaultHandler podría tener una o más actividades relacionadas. El resultado de la ejecución de este flujo de trabajo es mostrado en la siguiente figura:

WWF_Actividades_12

Articulo Publicado en http://desarrollador.redusers.com/

Tags: , , ,

Comunidades | .Net | Articulos | WWF

VS2008 RTM Disponible

by Misael Monterroca 19. November 2007 10:35

Me acabo de enterar de que VS2008 RTM ya está en el area de descargas de MSDN y parace que es cierto, vean lo que hay en el servidor de descargargas de MSDN

 

Server Too Busy

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Web.HttpException: Server Too Busy

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[HttpException (0x80004005): Server Too Busy]
   System.Web.HttpRuntime.RejectRequestInternal(HttpWorkerRequest wr, Boolean silent) +395

 

Gr, donde quedo la alta disponibilidad?

Tags:

.Net

Users Users Users!

by Misael Monterroca 7. November 2007 19:31

La semana pasada recibimos una invitación por parte del editor de la revista Users para escribir un curso basado en el temario de desarrollador 5 estrellas,  gran parte del contendido ya fue escrito, sin embargo, parte del equipo de DevWorx estaremos escribiendo el contenido restante para Windows Presentation Foundation y Windows WorkFlow Foundation en cuanto este la revista en circulación les avisaremos para que vaya con su voceador más cercano a comprar la revista :D.


Por otra parte, Rodrigo anda en Barcelona atendiendo el evento TechNet de europa, por lo que me comenta se ve súper interesante  además anda escribiendo en su blog las noticias más relevantes, por ejemplo, me entere de una excelente noticia, la liberación para finales de noviembre de Visual Studio 2008 según recuerdo la ultima beta pública fue la Beta 2 aunque obviamente MS genera más build internos que no necesariamente son públicos pero se me hace extraño que “públicamente” se pasen del Beta 2 al RTM ya estaremos evaluando el productoa ver que tal se comporta sobre windows vista, la noticia oficial pueden verla en: http://reddevnews.com/news/article.aspx?editorialsid=9216

Tags:

.Net

MVP