Tendencias de trabajo de Flex, Silverlight, GWT y JavaFX

Ya se que estas tendencias que voy a poner ahora son de EEUU pero esperemos que en Europa sea igual con los meses de retraso de siempre. En el blog de

Mike Slinn ha puesto un post (http://www.insideria.com/2009/07/flex-silverlight-job-trends.html) en el cual se reflejan las tendencias de trabajo de

indeed.com, este grafico es el siguiente

jobgraph.png

 

De SimplyHired.com se muestra un grafico con resultados parecidos

t-line.png

 

Viendo los resultados vemos que hay una tendencia ascendente en SilverLight mayor incluso que Flex, pensáis que esto se puede reproducir en Europa?

Que opináis?

Cliente Twitter en SilverLight 3

Ya os comente en el post Un buen ejemplo de WPF una aplicación realizada en WPF que utilizaba yo que era un cliente de Twitter y FaceBook que me gusta mucho como esta hecho. Aprovechando el lanzamiento de SilverLight 3 han sacado la misma aplicación en SilverLight 3.0, que puede ser instalada out of browser también.

Fijándonos en las dos aplicaciones apostaría que el código no ha cambiado mucho por no decir nada y cuando diseñaron la aplicación en WPF ya estaban pensando en utilizarla para SilverLight 3.0, un buen ejemplo para tenerlo en cuenta cuando pensemos nuestras aplicaciones

Sobees Web Alpha Silverlight 3

 

Podéis acceder a probarla desde aquí

Drag And Push del IPhone en SilverLight

Después de haber estado viendo los posts de Custom Layouts en WPF, Animaciones en WPF, Triggers en WPF y Estilos en WPF de la mano de smartyP’s blog podemos ver una aplicación que imita el estilo de arrastrar y soltar del IPhone cuando ordenas los iconos de las aplicaciones, además no los ha dejado con código fuente para que podamos ver su implementación  que podéis descargar desde aquí.

 

image

 

Podéis ejecutar la aplicación y probarla desde aquí

Commands en WPF

Windows Presentation Foundation provee unos  tipos de eventos abstractos y
desacoplados que han sido llamados Comandos. Realmente la gran diferencia
existente  con  respecto  a  eventos  clásicos  como  el  que  se  lanza  cuando  un
usuario selecciona un elemento en una lista desplegable, es que los comandos
no  están  ligados  al  interfaz  de  usuario  que  los  exponen,  es  decir,  solo
representan acciones independientemente del interfaz.
Realmente  los  comandos  no  son  una  invención  de  Windows  Presentation
Foundation,  esta  tecnologia  ya  estaba  presente  en  Microsoft  Foundation
Classes (MFC) con un mecanismo similar.

En este tipo de eventos para describir el modelo existen cuatro piezas clave.

Commands

Representa una  tarea de un  aplicativo  la  cual mantiene  en  todo momento  si
puede o no ser ejecutada.

Command Sources

Son  los  que  lanza  un  comando,  es  decir, un botón  podría  ser  un Command
Source ya que puede lanzar un comando.

Command Bindings

Usando  un mismo  comando  con  diferentes  bindings  podemos  lanzar  dicho
comando en diferentes sitios teniendo un significado diferente en cada  lugar,
es  decir,  cada  command  binding  enganchará  un  comando  con  la  lógica
necesaria.

Command Targets

Para  ver  este  último  elemento  recurramos  al  tipico  ejemplo  del  comando
Pegar, donde el Command Target será el elemento donde el comando actuará.
Es  decir,  en  el  caso  del  comando  Pegar,  el  command  target  será  el TextBox
donde se pegará el texto que hubiera en el portapapeles. 

 

ICommand

Todo  comando  implementa  el  interfaz  ICommand  que  esta  disponible  en
System.Windows.Input. Este interfaz incluye tres miembros: dos métodos y un
evento.

Execute

Contendrá la lógica ha implementar por el comando en la aplicación. 

CanExecute

Sirve  para  devolver  el  estado  del  comando  pudiendo  comunicar  si  este  esta
habilitado o no.

CanExecuteChanged

Siempre que el valor de CanExecute cambie se lanzará un evento informando
de ello.

    public class MyCommand: ICommand 
    { 
        public bool CanExecute(object parameter) 
        { 
            throw new NotImplementedException(); 
        } 
 
        public event EventHandler CanExecuteChanged; 
 
        public void Execute(object parameter) 
        { 
            throw new NotImplementedException(); 
        } 
    } 

 

Comandos por defecto


Por suerte, no hay que  implementar comandos comunes como Cortar, Pegar,

Copiar,  etc  ya  que  WPF  provee  una  serie  de  comandos  preestablecidos  y

expuesto como propiedades estáticas en cinco clases diferentes

ApplicationCommands

Close, Copy, Cut, Delete, Find, Help, New, Open, Paste, Print, PrintPreview,

Properties, Redo, Replace, Save, SaveAs, SelectAll, Stop, Undo, etc.

ComponentCommands

MoveDown,  MoveLeft,  MoveRight,  MoveUp,  ScrollByLine,  ScrollPageDown,

ScrollPageLeft,  ScrollPageRight,  ScrollPageUp,  SelectToEnd,  SelectToHome,

SelectToPageDown, SelectToPageUp, etc.

MediaCommands

ChannelDown,  ChannelUp,  DecreaseVolume,  FastForward,  IncreaseVolume,

MuteVolume, NextTrack, Pause, Play, PreviousTrack, Record, Rewind, Select,

Stop, etc.

NavigationCommands

BrowseBack, BrowseForward, BrowseHome, BrowseStop, Favorites, FirstPage,

GoToPage, LastPage, NextPage, PreviousPage, Refresh, Search, Zoom, etc.

EditingCommands

AlignCenter,  AlignJustify,  AlignLeft,  AlignRight,  CorrectSpellingError,

DecreaseFontSize,  DecreaseIndentation,  EnterLineBreak,

EnterParagraphBreak,  IgnoreSpellingError,  IncreaseFontSize,

IncreaseIndentation,  MoveDownByLine,  MoveDownByPage,

MoveDownByParagraph,  MoveLeftByCharacter,  MoveLeftByWord,

MoveRightByCharacter, MoveRightByWord, etc.

Uso de los Comandos desde XAML


Existen controles que  incluyen   y exponent  la  lógica de comandos por  lo que

no  debemos  de  preocuparnos  de  realizar  ningun  trabajo  sobre  comandos.

Estos  controles  implementan  el  interfaz  ICommandSource  exponiendo  los

siguientes miembros:

Command

Se le asigna el comando a ejecutar.

CommandParameter

Representa un valor definido por el usuario que será pasado como parámetro

al comando.

CommandTarget

Objeto al que afecta la ejecución del comando.

 

En  el  siguiente  típico  ejemplo  donde  veremos  como  usar  los  comandos

preestablecidos de Cortar, Pegar  y Copiar que  afectarán  a una  caja de  texto.

Estos  comandos  serán  lanzados  por  varios  botones  de  la  barra  de

herramientas.

Utilizando DataBinding asignamos como CommandTarget el elemento de tipo

TextBox  y  de  nombre  txtDocument.  En  Command  irá  cada  uno  de  los

comandos a asignar: Cut, Copy o Paste.

 

 

<StackPanel> 
   <ToolBar> 
      <Button Command="Cut" 
              CommandTarget="{Binding  
ElementName=txtDocument}">Cortar</Button> 
      <Button Command="Copy" 
              CommandTarget="{Binding 
ElementName=txtDocument}">Copiar</Button> 
      <Button Command="Paste" 
              CommandTarget="{Binding 
ElementName=txtDocument}">Pegar</Button> 
   </ToolBar> 
   <TextBox Name="txtDocument" Width="300"></TextBox> 
</StackPanel> 

 

image

RoutedEvents en WPF

Windows Presentation Foundation presenta los RoutedEvents como un nuevo
tipo de  eventos que pueden  invocar handlers de  varios  elementos que  esten
escuchando por el en un árbol de elementos.
Como hemos visto hasta ahora, la forma en la que se distribuyen los elementos
en un código XAML es una jerarquía en forma de árbol. Mediante este tipo de
eventos, podemos  lanzar un  evento  en un  elemento  en  el nivel  inferior más
profundo  que  haya  y  “subir”  a modo  de  burbuja  hasta  alcanzar  el  elemento
raiz. Este es el concepto Bubbling muy conocido por los que haya utilizado el
modelo de objetos de DHTML.

Veamos un ejemplo en el siguiente código:

<UserControl x:Class="MyCommands.UserControl1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Height="150"> 
    <StackPanel Background="White"> 
        <Border BorderBrush="Black" BorderThickness="1"></Border> 
        <TextBlock FontWeight="Bold"  
                   FontSize="15">User Control1</TextBlock> 
        <Button Click="ButtonLanzar_Click" Width="250"  
                VerticalAlignment="Bottom">Lanzar Evento</Button> 
    </StackPanel> 
</UserControl> 

Si  lanzamos  un  RoutedEvent  desde  el  botón  del  ejemplo  anterior,  dicho
evento  “subirá”  hasta  alcanzar  al  elemento  raiz,  es  decir,  pasará  por: Button
->StackPanel  ->  UserControl.  En  el  caso  que  alguno  de  estos  elementos
estuviese  escuchando  por  este  evento,  podría  lanzar  cualquier  código  ese
momento.

Estrategia de Enrutado

Cuando es definido un RoutedEvent podemos asignar el comportamiento que
tendrá  el  evento  mientras  viaja  a  través  del  árbol  de  elementos.  Para  ello
disponemos  de  los  valores  de  la  enumeración  RoutingStrategy:  Tunneling,
Bubbling y Direct.

Tunneling

En este caso el evento será lanzado en primer lugar desde el elemento raíz del
árbol de elementos e  irá recorriendo cada uno  inmediatamente  inferior hasta
alcanzar al elemento fuente.

Bubbling

A diferencia del  tipo Tunneling, en este  tipo, el evento es  lanzada en primer
lugar  desde  el  elemento  fuente  y  recorrerá  cada  elemento  del  árbol
inmediatamente superior hasta llegar al elemento raíz.

Direct

Con  el mismo  comportamiento que un  evento normal de  .NET. El  evento  es
únicamente lanzado desde el elemento fuente.

 

Si tenemos este código XAML

<Button PreviewMouseDown="PreviewMouseDownButton"
        MouseDown="MouseDownButton">
   <Grid PreviewMouseDown="PreviewMouseDownGrid"
         MouseDown="MouseDownGrid">
      <Grid.ColumnDefinitions>
         <ColumnDefinition />
         <ColumnDefinition />
      </Grid.ColumnDefinitions>
      <Canvas PreviewMouseDown="PreviewMouseDownCanvas"
              MouseDown="MouseDownCanvas"
              Width="20" Height="18" VerticalAlignment="Center">
         <Ellipse PreviewMouseDown="PreviewMouseDownEllipse"
                  MouseDown="MouseDownEllipse"
                  x:Name="myEllipse"
                  Canvas.Left="1" Canvas.Top="1" Width="16" Height="16"
                  Fill="Yellow" Stroke="Black" />
         <Ellipse Canvas.Left="4.5" Canvas.Top="5" Width="2.5" 
                  Height="3" Fill="Black" />
         <Ellipse Canvas.Left="11" Canvas.Top="5" Width="2.5" 
                  Height="3" Fill="Black" />
         <Path Data="M 5,10 A 3,3 0 0 0 13,10" Stroke="Black" />
      </Canvas>
      <TextBlock Grid.Column="1">Click!</TextBlock>
   </Grid>
</Button>

El árbol visual

 

image

Si uno de los elementos Elipse del ejemplo anterior recibe una entrada, el routing de
eventos habilitaría el Button, Grid, Canvas y Ellipse a recibir el evento y dependiendo del tipo

SeetheLight

Ya sabemos que la compañía de Redmond hará oficial  las versión 3.0 de SilverLight en un evento el día 10 de Julio de 2009, que viene cargadasde novedades, esta nueva versión introduce más de 50 nuevas funciones, incluyendo soporte 3D, aceleración gráfica de GPU, soporte a formato de vídeo H.264 y añade la posibilidad de desarrollar aplicaciones externas fuera del navegador.

Tim Heuer del equipo de Microsoft acaba de publicar una nueva web http://www.seethelight.com/ que ahora mismo es un contador de días que quedan para que salga la versión 3.0, pero la pregunta es ¿Tendremos alguna sorpresa? ¿Veremos la luz?.

Esperamos con ansiedad

 

image

Estilos y Templates en WPF

Cuando realizamos una aplicación WPF una gran ventaja que tenemos es la posibilidad de definir estilos para cualquier control. Un estilo es una serie de parejas propiedad/valor, que serán aplicadas a una serie de elementos, es decir podemos definir para cada propiedad de un control un valor que será el que se aplique. La idea es parecida a los CSS del desarrollo web. Esto te da las ventajas de :

  • Reducir redundancia en tu código
  • Cambiar la apariencia de los controles en un solo punto
  • Poder cambiar el estilo de tus controles en tiempo de ejecución

Imaginemos que en nuestra aplicación queremos que todos los botones sean de fondo naranja, con letra italica , un margen determinado, bueno un estilo para un botón. La definición del estilo sería:

 

 <Style x:Key="miBoton" TargetType="Button">
            <Setter Property="Background" Value="Orange" />
            <Setter Property="FontStyle" Value="Italic" />
            <Setter Property="Padding" Value="8,4" />
            <Setter Property="Margin" Value="4" />
  </Style>

Los estilos se definen como recursos así que o van en la propia ventana en la sección Windows.Resources o en un diccionario de recursos que suele ser lo habitual y lo aconsejable.

Cuando queremos que botón aplique este estilo se lo debemos decir en la propiedad Style

<Button Style="{StaticResource myStyle}">Estilo Aplicado</Button> 
image 

Una caracteristica interesante de los estilos es que tienen herencia gracias a la propiedad del estilo BasedOn, si quiero otro estilo con la letra en negrita seria tan sencillo como

<Style x:Key="boldStyle" BasedOn="{StaticResource miBoton}"  TargetType="Button">
           <Setter Property="FontWeight" Value="Bold" />
        </Style>

 

image

 

Además de customizar un control a través de sus propiedades, podemos reemplazarlo por algo completamente diferente, a través de un Control Template.

Cada control tiene un template por defecto , que le da la apariencia básica, el template esta definido en cada control en la Dependency Property  Template . Con un Control Template podemos reemplazar totalmente el árbol visual de un control. Por ejemplo un Botón su árbol visual es el siguiente

 

Muchas veces podemos cambiar el Template a partir de un Stylo, modificando la propiedad Template, lo mejor con un ejemplo

 

<Style x:Key="CircularStyle" BasedOn="{StaticResource miBoton}" TargetType="Button">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Grid>
                            <Ellipse Fill="{TemplateBinding Background}"
                             Stroke="{TemplateBinding BorderBrush}"/>
                            <ContentPresenter HorizontalAlignment="Center"
                                          VerticalAlignment="Center"/>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

 

 

Si aplicamos el estilo

 

image

Como podéis observar ahora el botón, es circular

 

Para que veais un ejmplo mas completo os dejo el código de la aplicación de arriba y he añadido un Diccionario de Recursos que hace un checkbox como el de un IPhone

OffStateOnState

 

Pequeño Laboratorio de Animaciones y Triggers en WPF

Por petición de Julio Trujillo Leon, este post son los pasos de la realización de un pequeño ejemplo para realizar un proyecto con una pequeña animación disparada con un Trigger y asi ver como se comporta la teoría vista en los post:Animaciones en WPF y Triggers en WPF.

 

 

1.  Crear un nuevo proyecto WPF 

a.  Utilizando Microsoft Expression Blend crear un proyecto WPF Application

(.exe) de nombre AnimacionSimple

Utilizar como lenguaje C# y como Target .Net Framework 3.5

b.  En el fichero Windows1.xaml modificar para que la ventana aparezca en

tamaño de 640 por 480 y el fonde totalmente negro.

Podrá modificar las propiedades en la ventana propiedades 

c.  Modificar el fondo para que sea totalmente negro. 

2.  Añadir un circulo y animarlo  

a.  Crear un circulo centrado en la pantalla de 140 por 120.

b.  Cambiar el fondo del circulo para usar un Gradient Brush donde crear

un degradado de blanco a rojo.

c.  En la ventana de Objects and Timeline crear un StoryBoard y un Timeline

d.  Una vez creado tanto el StoryBoard o el Timeline, se inicia la grabación. La

línea amarilla marcará el inicio de cada movimiento (en nuestro caso).

clip_image002

e.   Modificar la posición del circulo mediante las propiedades X e Y de

RenderTransform.

clip_image004

f.  Moviendo la línea amarilla y modificando la X e Y del circulo crear la

animación.

g.  Una vez creada la animación podremos ver el resultado previo de la

animación pulsando el botón play.

image

3.   Lanzar la animación del circulo en un evento

a.  En la ventana de Triggers seleccionar el evento que ya esta creado y

eliminarlo.

clip_image008

b.  En esta misma ventana, añadir un nuevo evento

Window.MouseDoubleClick que lanzará nuestra animación creada.

c.  Ejecutar el proyecto con el botón F5 para ver el resultado. 

 

Triggers en WPF

Los Triggers en Windows Presentation Foundation surgen como necesidad de
disponer  de  mecanimos  con  los  que  pudiesemos  responder  mediante  un
eventos o asignacion de valor o cualquier acción a un evento en específico.
Por esto se dispone de distintos tipos de triggers donde podemos destacar los
siguientes tres: Property triggers, Data triggers y Event triggers.
Estos tres tipos de triggers no están disponibles en todas las clases a traves de
la  propiedad  que  exponen  de  nombre  Triggers,  a  saber,  la  clase
FrameworkElement  solo  soporta  Event  Triggers  sin  embargo;  Style,
DataTemplate y ControlTemplate acepta los tres tipos de triggers.

 

Property triggers

Es  invocado  cuando  el  valor  de  una  dependency  property  cambia.  Es  decir,
cuando una dependency property tenga un valor determinado, se ejecutará.
En  el  siguiente  ejemplo  podemos  ver  como  un  Property  Trigger  cambia  el
fondo de un botón a verde cuando el ratón pasa por encima, es decir, cuando
la dependency property IsMouseOver cambia de valor a True.

<Style TargetType="{x:Type Button}"> 
  ... 
  <Style.Triggers> 
    <Trigger Property="IsMouseOver" Value="True" > 
       <Setter Property="Background" Value="Green" /> 
    </Trigger> 
  </Style.Triggers> 
</Style> 
Data triggers


Al  igual  que  el  tipo  Property  Triggers,  los  Data  Triggers  son  lanzados  en

función del valor de una propiedad, con  la  salvedad que esta propiedad aquí

puede ser cualquier tipo de .NET.

Mientras  que  los  Property  Triggers  suelen  ser  usados  para  comprobar

propiedades  que  afectan  al  aspecto  visual,  los  Data  Triggers  se  usan

especialmente  para  comprobar  propiedades  que  afectan  más  al  terreno  no

visual, es decir, al contenido.

En el  siguiente ejemplo podemos ver como un Data Trigger cambia el  fondo

de un Textbox en función del valor que tiene la propiedad Text.

 

<Style TargetType="{x:Type TextBox}"> 
   ... 
   <Style.Triggers> 
      <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Text}"  
                   Value="Rojo"> 
         <Setter Property="Foreground" Value="Red" /> 
      </DataTrigger> 
      <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Text}"  
                   Value="Verde"> 
         <Setter Property="Foreground" Value="Green" /> 
      </DataTrigger> 
   </Style.Triggers> 
</Style> 

En este tipo de Triggers disponemos de los MultiTriggers y MutiDataTriggers

que nos aportan la posibilidad de añadir más de una condición al Trigger por

defecto consiguiendo expresar un AND lógico. Para ello estas clases disponen

de  la  propiedad  Conditions  donde  añadiremos  tantas  condiciones  como

desemos. 
En  el  siguiente  ejemplo  veremos  como  el  trigger  se  lanzará  cuando  las

propiedaes HasItems y Width tengan unos determinados valores:

<Style.Triggers> 
   <MultiTrigger> 
      <MultiTrigger.Conditions> 
         <Condition Property="HasItems" Value="false" /> 
         <Condition Property="Width" Value="Auto" /> 
      </MultiTrigger.Conditions> 
      <Setter Property="MinWidth" Value="120"/> 
   </MultiTrigger> 
</Style.Triggers> 
Event triggers


Despues  de  ver  los  dos  tipos  anteriores  de  triggers,  este  Event  Triggers  su

propio  nombre  lo  indica,  no  se  fija  en  propiedades  ya  sea  Dependency

Properties o CLR Properties sino que se fija en eventos.

Cuando  un  Routed  Event  es  lanzado,  un  Event  Trigger  puede  realizar  una

función como consecuencia de ello.

En  el  siguiente  ejemplo  podemos  ver  como  una  animación  es  arrancada

cuando el evento Click es lanzado:

<Style.Triggers> 
   <EventTrigger RoutedEvent="Click"> 
      <EventTrigger.Actions> 
         <BeginAction TargetName="StoryBoard1" /> 
      </EventTrigger.Actions> 
   </EventTrigger> 
</Style.Triggers> 

En el siguiente post veremos un ejemplo de como hacer las animaciones con Trigguers a partir de Blend