Servicio de traducción Bing integrado en Silverlight 3

La puesta en marcha del nuevo navegador de Microsoft «Bing«, trae consigo un API de la que podemos sacar cierto provecho. En esta entrada vamos a centrarnos en el servicio de traducción que ofrece la mencionada API. Comenzaremos con la obtención de un AppID a través del registro mediante Live ID, de este modo podremos empezar a desarrollar nuestro proyecto.

 0

El acceso a los servicios de Bing lo podemos conseguir de tres formas distintas:

De las tres opciones nos quedamos con SOAP para desarrollar el proyecto que nos ocupa. Abrimos Visual Studio 2008, creamos un nuevo proyecto de Silverlight 3. El siguiente paso que debemos seguir es agregar la referencia del servicio que vamos a utilizar, la url que utilizamos en el servicio de traducción de Bing es la siguiente: http://api.microsofttranslator.com/V1/SOAP.svc.

 

 1

Seguidamente creamos nuestra interfaz para poder realizar la traducción a través de XAML en MainPage.Xaml introduciendo el siguiente texto:

<StackPanel HorizontalAlignment=»Center»>

 

<TextBlock>Idioma Original</TextBlock>

<ComboBox x:Name=»comboOrigen»

Width=»250″></ComboBox>

 

<TextBlock>Texto Original</TextBlock>

<TextBox x:Name=»textoOrigen»

Height=»56″ Width=»250″ FontSize=»34″/>

 

<TextBlock>Idioma de traducción</TextBlock>

<ComboBox x:Name=»comboDestino»

Width=»250″></ComboBox>

 

<TextBlock>Texto traducido</TextBlock>

<TextBox x:Name=»textoDestino»

Height=»56″ Width=»250″ FontSize=»34″/>

 

<Button x:Name=»botonTraducir»

Click=»botonTraducir_Click»

Content=»Traducir» Width=»50″/>

 

</StackPanel>

Como podemos observar la interfaz está compuesta de un ComboBox para elegir el idioma original y el idioma de la traducción y dos bloques de texto para introducir el texto que queremos traducir y el resultado de la traducción. Por último incluimos un botón para lanzar el servicio de traducción.

Nos situamos en MainPage.Xaml.cs e introducimos las librerías que nos van hacer falta para que nuestro proyecto se ejecute de forma correcta.

 

using System.Collections.ObjectModel;

 

 

using traductorBing.traductor;

 

 

Debemos declarar una serie de variables, que serán importantes en los siguientes pasos de nuestro proyecto, cabe destacar la utilización del AppID obtenido con anterioridad, en dicha declaración.

// Referenciar el servicio SOAP de traducción en nuestro proyecto

traductor.LanguageServiceClient lt = new LanguageServiceClient();

// AppId para autentificar los servicios de Bing

string AppId = «XXXXXXXXXXXXXXXXXXXXXXXXXXXXX»;

// Collecion de Idiomas

ObservableCollection<string> langcodes;

Debido a que el servicio utiliza métodos asincronos debemos generar los Handlers que son necesarios, realizamos la acción mencionada en el Load de nuestra aplicación.

private void UserControl_Loaded(object sender, RoutedEventArgs e)

{

// Handlers

lt.TranslateCompleted +=

new EventHandler<TranslateCompletedEventArgs>

(lt_TranslateCompleted);

lt.GetLanguageNamesCompleted +=

new EventHandler<GetLanguageNamesCompletedEventArgs>

(lt_GetLanguageNamesCompleted);

lt.GetLanguagesCompleted +=

new EventHandler<GetLanguagesCompletedEventArgs>

(lt_GetLanguagesCompleted);

}

Sin abandonar el Load de la aplicación, vamos a introducir los diferentes idiomas en los combos.A la vez guardamos las claves de los mismos con el fin de saber que idiomas deseamos pasar al servicio.

// Evento encargado de guardar la lista de idiomas disponibles

// Nos suministra el código del Idioma

lt.GetLanguageNamesAsync(AppId, Language.IetfLanguageTag);

 

// Evento encargado de llenar los combos de Idiomas

// Nos suministra la descripción del Idioma

lt.GetLanguagesAsync(AppId);

El siguiente paso es la creación de los Handlers que se encargarán de suministrarnos los diferentes idiomas.

// Guarda la lista de idiomas disponibles

protected void lt_GetLanguagesCompleted(object sender,

GetLanguagesCompletedEventArgs e)

{

if (e.Error == null)

{

langcodes = e.Result;

}

}

 

// Llena los combos de Idiomas

protected void lt_GetLanguageNamesCompleted(Object sender,

GetLanguageNamesCompletedEventArgs e)

{

if (e.Error == null)

{

comboOrigen.ItemsSource = e.Result;

comboDestino.ItemsSource = e.Result;

 

// El Origen por defecto es Inglés

comboOrigen.SelectedIndex =

langcodes.IndexOf(«en»);

// El Destino por defecto es Español

comboDestino.SelectedIndex =

langcodes.IndexOf(«es»);

}

}

Como guinda del pastel, vamos a realizar la parte que permite realizar la traducción.Al presionar el correspondiente botón, este llamará a un método que realiza la acción mencionada con anterioridad.Como es asincrono, cuando termine se encargará de llamar al Handler que hemos creado en el Load de nuestra aplicación.

private void botonTraducir_Click(object sender,

RoutedEventArgs e)

{

if (comboOrigen.SelectedItem != null &&

comboDestino.SelectedItem != null)

{

lt.TranslateAsync(AppId, textoOrigen.Text,

(langcodes[comboOrigen.SelectedIndex].ToString()),

(langcodes[comboDestino.SelectedIndex].ToString()));

}

}

 

// Recibe el texto traducido del Servicio

protected void ls_TranslateCompleted(Object sender,

TranslateCompletedEventArgs e)

{

if (e.Error == null)

{

textoDestino.Text = e.Result;

}

}

Este es el resultado de la utilización del servicio de traducción que nos ofrece el nuevo buscador de Microsoft.

 

 2

 

Flipbook en Silverlight 3

Voy a crear una aplicación sencilla que puede ser creada mediante WPF, pero en este caso voy a crearla a través de Silverlight, coincidiendo con la puesta en marcha de la versión 3 de dicha plataforma.

La aplicación es un libro virtual, formado por una serie de fotos elegidas previamente. Al presionar sobre la primera foto esta se movería imitando a un libro. Se repetirá dicho efecto cada vez que presionemos sobre las correspondientes fotos.

Lo primero que debemos de incluir es la parte del interface de usuario, lo realizaremos en Xaml introduciendo el siguiente código:

<UserControl x:Class=»libro.MainPage»

xmlns=»http://schemas.microsoft.com/winfx/2006/xaml/presentation»

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

xmlns:d=»http://schemas.microsoft.com/expression/blend/2008″ xmlns:mc=»http://schemas.openxmlformats.org/markup-compatibility/2006″

mc:Ignorable=»d» d:DesignWidth=»640″ d:DesignHeight=»480″>

<UserControl.Resources>

<!–estilo que se va aplicar a cada imagen–>

<Style x:Key=»_imageStyle»

TargetType=»Image»>

<Setter Property=»Margin»

Value=»275,0,0,0″ />

<Setter Property=»Width»

Value=»275″ />

<Setter Property=»Stretch»

Value=»Uniform» />

</Style>

</UserControl.Resources>

<Grid x:Name=»LayoutRoot»>

<Image Style=»{StaticResource _imageStyle}»

Source=»Images/1.jpg»

MouseLeftButtonUp=»FlipImage» />

<!–cada una de las imagenes lanza un evento

al pulsar sobre ellas conel botón

izquierdo del ratón–>

<Image Style=»{StaticResource _imageStyle}»

Source=»Images/2.jpg»

MouseLeftButtonUp=»FlipImage» />

<Image Style=»{StaticResource _imageStyle}»

Source=»Images/3jpg»

MouseLeftButtonUp=»FlipImage» />

<Image Style=»{StaticResource _imageStyle}»

Source=»Images/4.jpg»

MouseLeftButtonUp=»FlipImage» />

<Image Style=»{StaticResource _imageStyle}»

Source=»Images/7.jpg»

MouseLeftButtonUp=»FlipImage» />

<TextBlock Text=»Haz Clic para cambiar de imagen»

VerticalAlignment=»Bottom»

HorizontalAlignment=»Center» />

</Grid>

 

 

</UserControl>

 

Como podemos ver hemos usado un estilo que se definirá en cada una de las imágenes, en WPF este estilo se puede heredar pero en Silverlight aún no tenemos esta particularidad.

El evento que se desencadena lo tenemos que realizar a través del código Behind introduciendo el siguiente código:

public partial class MainPage : UserControl

{

private int _zIndex = 10;

public MainPage()

{

InitializeComponent();

}

private void FlipImage(object sender, MouseButtonEventArgs e)

{

Image image = sender as Image;

 

// Asegura que la imagen estará encima de todas las demás

image.SetValue(Canvas.ZIndexProperty, _zIndex++);

 

// Crea el Storyboard(guión)

Storyboard flip = new Storyboard();

 

// crea una animación de una duración

//de un segundo

DoubleAnimation animation = new DoubleAnimation()

{

Duration = new TimeSpan(0, 0, 1)

};

 

// añade la animación al storyboard.

flip.Children.Add(animation);

 

//crea una proyección de la imagen si no tiene ninguna

if (image.Projection == null)

{

// Establece el centro de rotación en -0.01,

//lo que proporcionará un espacio entre las imagenes

//cuando estas se giren.

image.Projection = new PlaneProjection()

{

CenterOfRotationX = -0.01

};

}

 

PlaneProjection projection = image.Projection as PlaneProjection;

 

// Establece el origen y destino de la imagen basandose

//en la capa de las imagenes

if (projection.RotationY == 0)

{

animation.To = 180;

}

else

{

animation.From = 180;

animation.To = 0;

}

 

//le indica cuando se produce la animación que imagen debe de situarse

//en cada plano

Storyboard.SetTarget(animation, projection);

 

// le indica a la animación la propiedad RotationYproperty

//qeu debe de tomar

Storyboard.SetTargetProperty(animation,

new PropertyPath(PlaneProjection.RotationYProperty));

 

flip.Begin();

}

 

 

}

Lo primero que hago es indicar un índice a través de la variable Z, de este modo se va mover la imagen, asegurando que la imagen que realiza el movimiento será la primera y única foto visible en el margen izquierdo.

Ahora me centraré en el evento FlipImage, lo primero es crear la animación, indicando la duración de la misma, en este caso un segundo. El siguiente paso es añadir la animación al StoryBoard, de modo que se cree una rotación cuyo centro será -0.01, así se creará un pequeño espacio entre la imagen que se está rotando y la imagen estática. La rotación se realiza a través del elemento PlaneProjection aunque podemos utilizar otros objetos más sofisticados a la par de nuestras necesidades.

Como podeis ver una pequeña aplicación le podemos dar un toque de sofisticación, mejorando la experiencia de usuario.

Depurando Data Binding

Uno de los problemas con los que me encuentro a menudo, son las limitaciones que ofrece el lenguaje XAML a la hora de obtener información sobre un error. Voy a centrarme en la depuración de los Data Binding, debido a que son una parte importante de Windows Presentation Foundation y la detección de errores de los mismos se hace casi indispensable.

Tengo dos métodos para depurar los Binding:

  • Output Window de Visual Studio

     

    Tengo una aplicación que carga una serie de imágenes de un archivo XML, pero he utilizado mal el nombre de la propiedad que mostrará las distintas imágenes.

    <Image Source=»{Binding Path=PictureWrong}» Width=»300″ Height=»300″ Grid.Row=»0″/>

    Cada vez que no se vincula de forma correcta una imagen con la propiedad correspondiente se sobreimpresiona un mensaje de error del tipo:

    System.Windows.Data Error: 35 : BindingExpression path error: ‘PictureWrong’ property not found on ‘object’ «Star’ (HashCode=49535530)’. BindingExpression:Path=PictureWrong; DataItem=’Star’ (HashCode=49535530); target element is ‘Image’ (Name=»); target property is ‘Source’ (type ‘ImageSource’)

    De este modo visual Studio, me presenta la información necesaria para reconocer que la propiedad que enlazamos a una fuente de datos «Source», tomando los datos de forma inadecuada.

     

  • Trace Level

     

    Esta opción aparece en el Framework 3.5 y ayuda más aún a obtener al detalle los diferentes errores que se producen en los Data Binding. Por ejemplo tenemos un «TextBox», cuya propiedad «Text» será cambiada por el valor que le otorga la propiedad «Value» del control Slider a través de un Data Binding.

    <TextBox Text=»{Binding ElementName=slider, Path=Value, Mode=OneWay}» Height=»30″ Width=»100″ Margin=»10″ />

<Slider Minimum=»0″ Maximum=»100″ Value=»20″ Margin=»10″ x:Name=»slider» />

Para obtener toda la información y que esta se muestre en la output Window, debo introducir el espacio de nombres «System.Diagnostics» y en el Binding he de añadir «PresentationTraceSources.TraceLevel=High»

 

    <Window x:Class=»WpfApplication1.Window1″

        xmlns=»http://schemas.microsoft.com/winfx/2006/xaml/presentation»

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

        xmlns:trace=»clr-namespace:System.Diagnostics;assembly=WindowsBase»

        Title=»Window1″ Height=»300″ Width=»300″>

        <Grid>

<TextBox Text=»{Binding ElementName=slider, Path=Value, Mode=OneWay,trace:PresentationTraceSources.TraceLevel=High}» Height=»30″ Width=»100″ Margin=»10″/>

    <Slider Minimum=»0″ Maximum=»100″ Value=»20″ Margin=»10″ x:Name=»slider» />

        </Grid>

</Window>

 

La ventana de depuración obtendrá resultados como este:

Created BindingExpression (hash=17654054) for Binding (hash=44624228)
Path: ‘Value’
BindingExpression (hash=17654054): Default update trigger resolved to LostFocus
BindingExpression (hash=17654054): Attach to System.Windows.Controls.TextBox.Text (hash=52727599)
BindingExpression (hash=17654054): Resolving source
BindingExpression (hash=17654054): Found data context element: (OK)
Lookup name slider: queried TextBox (hash=52727599)
BindingExpression (hash=17654054): Resolve source deferred

BindingExpression (hash=17654054): Resolving source
BindingExpression (hash=17654054): Found data context element: (OK)
Lookup name slider: queried TextBox (hash=52727599)
BindingExpression (hash=17654054): Activate with root item Slider (hash=54371668)
BindingExpression (hash=17654054): At level 0 – for Slider.Value found accessor DependencyProperty(Value)
BindingExpression (hash=17654054): Replace item at level 0 with Slider (hash=54371668), using accessor DependencyProperty(Value)
BindingExpression (hash=17654054): GetValue at level 0 from Slider (hash=54371668) using DependencyProperty(Value): ’20’
BindingExpression (hash=17654054): TransferValue – got raw value ’20’
BindingExpression (hash=17654054): TransferValue – implicit converter produced ’20’
BindingExpression (hash=17654054): TransferValue – using final value ’20’

 

 

 

Multiselección en un ListBox de Silverlight 3

Una de las propiedades que se han introducido en la nueva versión de Silverlight 3, es la posibilidad de realizar varias selecciones (Multi-select), de los diferentes Items del control ListBox.

Para comprender dicha novedad voy a crear un pequeño ejemplo, que estará formado por el control citado. Elegiré las opciones que crea convenientes y estas serán presentadas a través de un Texblock, cuando presione en el botón correspondiente.

Lo primero que crearé serán los distintos controles de la interfaz de usuario:

<UserControl x:Class="MultiSelectLB.MainPage"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

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

Width="500" Height="280">

 

<Grid x:Name="LayoutRoot"

Background="wheat"

Margin="10">

<Grid.ColumnDefinitions>

<ColumnDefinition Width="1*" />

<ColumnDefinition Width="1*" />

</Grid.ColumnDefinitions>

<Grid.RowDefinitions>

<RowDefinition Height="1.5*" />

<RowDefinition Height="1*" />

<RowDefinition Height="1*" />

<RowDefinition Height="*" />

</Grid.RowDefinitions>

<TextBlock x:Name="Titulo"

Margin="0"

Text="Multi-selección ListBox"

Foreground="Red"

FontFamily="Georgia"

FontSize="32"

HorizontalAlignment="Center"

VerticalAlignment="Center"

Grid.ColumnSpan="2" />

<ListBox x:Name="Multisel"

Margin="5"

Grid.Row="1"

Grid.Column="0"

SelectionMode="Multiple" />

<Button x:Name="readyButton"

Margin="5"

Grid.Row="1"

Grid.Column="1"

Width="100"

Height="35"

Content="Pulsar para elegir" />

<TextBlock x:Name="Mensaje"

HorizontalAlignment="Left"

Margin="5"

Grid.Row="2"

Grid.Column="0"

Grid.ColumnSpan="2"

Foreground="Blue"

VerticalAlignment="Bottom"

FontFamily="Georgia"

FontSize="18" />

 

</Grid>

 

</UserControl>

 

Como podemos ver en el control ListBox a la hora de indicar el modo de seleccinar los items, podemos elegir entre 3 opciones:

  • Single
    

  • Multiple
    

  • Extended
    

     

    12

El siguiente paso será crear una nueva clase (SelectItem), en la que habrá una lista con los nombres de los distintos Items que puedo elegir. Crearemos un método para comprobar que se ha seleccionado algún item y si es así presentarlo en el control Textblock creado con anterioridad:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Windows.Controls;

 

namespace MultiSelectLB

 

{

 

public partial class MainPage : UserControl

 

{

 

private readonly List<string> Colores =new List<string> { "Rojo", "Amarillo", "Verde", "Azul", "Negro", "Blanco" };

 

public MainPage()

 

{

 

InitializeComponent();

msLB.ItemsSource = Colores;

readyButton.Click += BClick;

 

}

 

private void BClick(object sender, System.Windows.RoutedEventArgs e)

 

{

 

var selectColor = msLB.SelectedItems;

Message.Text = string.Empty;

foreach (string NombreColor in selectColor)

{

 

if (Mensaje.Text.Length > 0)

{

Mensaje.Text += ", ";

}

Mensaje.Text += NombreColor;

 

}

}

 

}

 

}

 

En conclusión, el plus que nos da Silverlight en el ListBox respecto a versiones anteriores, permite realizar la acción de selección de Items en un solo paso. Con lo que se reduce la redundancia de procesos y la consiguiente monotonía para el usuario, creando un aumento de productividad de nuestra aplicación.

 

Acelerar animaciones a través de GPU

Muchas veces en las aplicaciones web notamos como algunas animaciones tardan en ejecutarse o no lo hacen de la forma adecuada. En este articulo os mostraré como una animación puede acelerarse a través de la GPU de nuestro equipo incluso aplicándole efectos que son lentos en su ejecución.

Para realizar la prueba contamos con una animación en la que podemos ver los efectos que se producen al utilizar la aceleración a través de GPU, lo puedes comprobar aquí.

Para mostraros esta aceleración empezaremos permitiendo a todo el Plugin de Silverlight3 que acelere la animación a través de GPU. Para ellos hemos de agregar un parámetro a la etiqueta <object> del archivo HTML que tiene nuestra aplicación Silverlight3.

<object data=«data:application/x-silverlight,» type=«application/x-silverlight-3»

width=«100%» height=«100%»>

<param name=«enableGPUAcceleration» value=«true» />

En Windows la aceleración GPU funciona tanto para pantalla completa como para pantalla reducida. En Mac OSX solo funciona para pantalla completa.Los usuarios de Windows deben de tener una tarjeta gráfica compatible con DirectX 9, además de sus correspondientes controladores.Los usuarios de Mac necesitarán una tarjeta compatible con OpenGl2.

Ahora la acción que nos concierne la aplicaremos sobre un elemento XAML de Silverlight3,en este caso un CANVAS.Este será a su vez contenedor de los diferentes controles que se incluiran más tarde (Imágenes, animaciones,pinceles,etc.), heredando dicha capacidad los controles contenidos dentro del Canvas.

<Canvas CacheMode=»BitmapCache» />

Ahora os preguntareis pero ¿la aceleración no es a través de GPU en vez de Bitmap? Para entender esto como podeis ver no hemos utilizado implicitamente «UseGPU» o «AccelerateThisALotUsingGPU», porque en Silverlight 3 La aceleración de GPU no es ni más ni menos que una aceleración de un Bitmap en la caches de la GPU.

El siguiente paso es otorgar mayor velocidad a la hora de presentar nuestros pixeles, para ello incluiremos el siguiente código en la etiqueta <object> del HTML:

<param name=»enableFramerateCounter» value=»True» />

Cabe destacar que no todas las tarjetas de video tienen la misma cantidad de memoria, con lo que cuando esta se acaba Silverlight3 ejecuta sus acciones a través del Software, ralentizando los procesos de la aplicación.

Para solucionar este problema es aconsejable que actives la visualización de caché. Este añadido permitirá ver qué elementos son acelerados mediante GPU y cuáles no. Solo debemos incluir el siguiente código el HTML de la página que se va alojar o en el código Behing en tiempo de ejecución:

<param name=»enableCacheVisualization» value=»true» />

El camino que hemos de seguir es hacia el escalado de nuestra animación. Para lograr este objetivo debo de añadir la propiedad RenderAtScale del objeto BitmapCache:

var bmc = new BitmapCache();

bmc.RenderAtScale = 4;

lion1.CacheMode = bmc;//siendo lion1 nuestra animación

El último paso es configurar RenderAtScale en el XAML:

<Canvas>

<Canvas.CacheMode>

<BitmapCache RenderAtScale=»4″ />

</Canvas.CacheMode>

</Canvas>

El código anteriormente introducido, nos permite escalar los vectores de Silverlight a 4X, esto conlleva un aumento de la memoria 16 veces más de lo que anteriormente tenía, con lo que la animación se ralentizará si no se dispone de una buena tarjeta de video.

En conclusión la utilización de la aceleración por GPU es una buena ayuda para acelerar nuestras animaciones. Esta acción tienes sus ventajas y desventajas y es bueno saber que se ha de aplicar a animaciones que su contenido cambia rara vez, debido a que el cambio de Bitmap se realiza en la caché de la GPU.

Si desea obtener más información sobre este tema puede consultar el blog de András Velvárt

 

Wikipedia Explorer

Las compañías Dotnet Solutions, Monochrome y Plataform Evangelism de Redmond, se han puesto manos a la obra para dar una vuelta de tuerca al concepto de búsqueda de la conocida "Wikipedia". La Wikipedia Explorer es una aplicación basada en las plataformas de Microsoft Windows Presentation Foundation y Windows Azure. Las principales novedades respecto a la Wikipedia tradicional, es una mayor facilidad de búsqueda, al presentarnos nexos de unión entre los diferentes documentos.

 1

Esta nueva aplicación se ha basado en Windows Azure, ya que tiene la capacidad de prestar el servicio de búsqueda de una manera rápida, al trabajar con varios servidores de gran potencial en el mismo periodo de tiempo. De este modo se reduce el tiempo de búsqueda en la base de datos del dato que deseamos encontrar.

Por último reseñar que Wikipedia Explorer nos ofrece diversas formas de presentación de la información encontrada, o bien mediante texto, mediante los nexos de las diferentes entradas de la información que buscamos o mediante las entradas que contienen un mayor número de información.

2

Personalización JumpList

Desde el punto de vista de los desarrolladores la personalización de la JumpList se basa en la API que pone a nuestra disposición Microsoft, además de la utilización de la librería Vista Bridge Sample Library 1.4 para tal fin.

Lo primero que voy a personalizar son los distintos elementos que aparecen por defecto en las correspondientes categorías. Para ello voy a incluir un fichero "sonnet.txt" en una categoría "Reciente", utilizo el código administrado que ofrece la API:

JumpListManager jlm = …;

<!–Instancia de libreria JumpListManager–>

jlm.AddCustomDestination(new ShellItem { Path=C:CESMIcrosoftW7Win7RCModule01_Taskbarsonnet.txt, Category="Reciente",Title = "Notas de gastos",IconLocation = shell32DllPath});

<!–añado y personalizo el elemento notas.doc dentro de la categoria Reciente–>

El proceso que he seguido es añadir un nuevo elemento a la JumpList a través del comando New ShellItem, dentro de este comando he indicado la ruta del fichero que se va a ejecutar C:CESMIcrosoftW7Win7RCModule01_Taskbarnotas.doc. La categoría en la que va agrupar nuestro elemento es "Reciente" indicandolo del siguiente modo Category="Reciente", además puedo introducir un titulo que mostrará el elemento añadido Title = "Notas de gastos", y además si quiero que mi elemento presente un icono distinto al que por defecto va tomar por el formato del archivo utilizaré IconLocation = shell32DllPath.Como podemos ver este es el aspecto de nuestra JumpList despues de añadir el nuevo elemento:

 

 1

 

La siguiente área que voy a personalizar es la relacionada con las tareas de un usuario. Para ello voy a añadir una nueva tarea "Ejecutar Calculadora" que estará dentro de la categoría Tareas:

JumpListManager jlm = …;

<!–Instancia de libreria JumpListManager–>

jlm.AddTask(new ShellLink { Path=H:CESMIcrosoftW7Win7RCModule01_Taskbarcalc.exe, Title = "Ejecutar calculadora",IconLocation = shell32DllPath });

<!–añado y personalizo la tarea ejecutar calculadora dentro de la categoria Tareas–>

Al añadir una nueva tarea deberemos expecificar que se añade un nuevo elemento new ShellLink. Por otro lado este elemento deberé de expecificar la ruta del archivo ejecutable del mismo Path=H:CESMIcrosoftW7Win7RCModule01_Taskbarcalc.exe. Además si quiero que el elemento se diferencie dentro de las distintas tareas le introduzco un titulo diferenciativo Title = "Ejecutar calculadora" y le asigno un icono distintivo IconLocation = shell32DllPath. De este modo podré ejecutar una acción que realizo de forma frecuente o de forma puntual sin necesidad de bucear entre todas mis carpetas y archivos con la correspondiente pérdida de tiempo.

 2

En conclusión como podemos ver Windows 7 solventa la pequeña carencia de agilidad que sus predecesores tenían a la hora de ejecutar tareas o acceder a archivos, desde el punto de vista del desarrollador nos ofrece un nivel de personalización mucho más avanzada de elementos novedosos como la JumpList.

 

 

Orígenes de los elementos de la JumpList

La puesta en marcha de W7 trae consigo un conjunto de novedades, de todas ellas cabe destacar el elemento JumpList. Dicho elemento aparece en los menús contextuales de las aplicaciones que nosotros tenemos pineados en nuestra barra de tareas. Consiguiendo una mayor agilidad y sencillez a la hora de acceder a nuestras aplicaciones.

 1

El citado elemento está compuesto de dos partes diferenciadas, por un lado los Destinos y por otro lado las Tareas. Los destinos son elementos que usamos con frecuencia, así podemos distinguir dentro de este conjunto elementos anclados, que son los elementos que nosotros hemos decidido pinear a la JumpList. Elementos recientes, siendo estos los que hemos utilizado en la actualidad y por último elementos importantes siendo estos como su nombre indica los elementos que toman una relevancia considerable para nosotros.

Por otro lado tenemos las Tareas que son una serie de comandos que podemos invocar desde la JumpList para poder ejecutar una acción de una manera rápida y sencilla. Dentro de este conjunto tenemos tareas de usuario que son los comandos que el usuario decide ejecutar de forma directa y tareas de el propio programa, que son las tareas inherentes de los accesos directos anclados a la barra de tareas. Ejecutando comandos comunes a todos los accesos directos.

 2

Una vez que tenemos el concepto generalizado de la JumpList, nos adentraremos en la personalización de dicho elemento, empezando por las fuentes de datos. Los orígenes de los datos se pueden obtener de los elementos recientes utilizados por el explorador de Windows. Por otro lado si nuestras aplicaciones utilizan Common File Dialog para abrir ficheros de forma automática, se añaden a la lista del usuario el último fichero abierto. Por último disponemos de una API que nos permitirá personalizar cada uno de los elementos de nuestra JumpList.

En código administrado podemos ver cómo obtener los distintos orígenes de los datos que se van a mostrar como elementos en la JumpList de los accesos directos de la barra de tareas del siguiente modo:

RH.RegisterFileAssociations(…);

<!–elementos recientes del explorador de Windows–>

OpenFileDialog ofd = …; ofd.ShowDialog();

<!–elementos ejecutados a través del Common File Dialog–>

JumpListManager jlm = …;

jlm.AddToRecent("file.ext");

<!–Añadir un elementos a recientes de la JumpList a través de la API de W7–>

Limitar número de palabras a mostrar en un Webpart de texto mediante XSLT

En el proyecto en el que he estado implicado últimamente, una de las especificaciones es limitar el número de palabras tiene que mostrar cada una de las entradas de un Webpart de una lista de anuncios en Windows SharePoint Servicies.

Lo primero que tenemos que realizar es la eliminación de etiquetas HTML(<Div>, <Span>, <Font>, etc.) que generalmente se agregan a la hora de añadir nuevas entradas de la lista deseada. Esta particularidad la realizaremos a través del lenguaje XLST.

Primeramente deberemos definir un método para eliminar las etiquetas HTML lo haremos a través del siguiente código:

<xsl:template name="BorrarEtiquetasHtml">

<xsl:param name="html"/>

<xsl:choose>

<xsl:when test="contains($html, ‘&lt;’)

<xsl:value-of select="substring-before($html, ‘&lt;’)"/>

<xsl:call-template name="BorrarEtiquetasHtml">

<xsl:with-param name="html" select="substring-after($html, ‘&gt;’)"/>

</xsl:call-template>

</xsl:when>

<xsl:otherwise>

<xsl:value-of select="$html"/>

</xsl:otherwise>

</xsl:choose>

</xsl:template>

El siguiente paso es realizar una llamada al método creado con anterioridad pasándole el texto de nuestra entrada. Se realizará del siguiente modo:

<xsl:variable name="pureText">

<xsl:call-template name="BorrarEtiquetasHtml">

<!–llamada al metodo pasandole el cuerpo de nuestra lista –>

<xsl:with-param name="html" select="@Body" />

</xsl:call-template>

</xsl:variable>

 

Una vez enviado el texto, este quedará limpio de las molestas etiquetas que impiden la limitación de caracteres de las entradas de una lista.Para ello utilizaremos la variable que anteriormente ha sido limpiada de etiquetas ( pureText) introduciéndole la siguiente consulta:

<xsl:value-of select="substring($pureText, 0, 600)" />

Siendo Substring el método que devolverá los caracteres comprendidos entre el número inicial que nosotros introduzcamos, en este caso el cero ya que partimos del carácter inicial, seleccionando la cadena hasta el carácter 600 en este caso. Toda esta selección se realizará sobre la variable limpia de etiquetas HTML (pureText).

Como podéis ver es una forma sencilla de mostrar un resumen de las distintas entradas por ejemplo de una lista de anuncios.

 

 

Ojo de pez

En términos fotográficos el ojo de pez es un ángulo de visión extremadamente grande a partir de 180⁰.Voy asemejar este efecto en términos Informáticos. Utilizaré la herramienta de Microsoft con la que en los últimos meses he escrito diversas entradas en este blog, Windows Presentation Foundation, para ello utilizaré una serie de botones que al situarnos sobre ellos realicen el citado efecto.

 1

Una vez abierto Visual Studio 2008 y creado un nuevo proyecto en WPF, dentro de la etiqueta <Grid> que por defecto nos presenta WPF, introduciré la etiqueta <StackPanel> que actuará como contenedor de los botones, recursos, animaciones, etc.

El primer paso es introducir un estilo dentro de los recursos del contenedor citado con anterioridad. El estilo aplicará dos eventos uno cuando nos situemos dentro del control y otro al desplazar el puntero del ratón fuera del control. Los eventos cambiarán la propiedad FontSize de los botones durante un periodo de tiempo, creciendo o decreciendo según me sitúe dentro o fuera del botón con el puntero del ratón como veremos en el siguiente código:

<StackPanel>

<StackPanel.Resources>

<!–recursos que podemos aplicar a Stack Panel–>

<Style TargetType="{x:Type Button}">

<!–estilo que aplicamos a los botones,indicando que el control

al que se va aplicar el estilo es de tipo botón–>

<Setter Property="HorizontalAlignment" Value="Center" />

<Setter Property="FontSize" Value="12" />

<!–valores iniciales que toman los botones–>

<Style.Triggers>

<EventTrigger RoutedEvent="Button.MouseEnter">

<!–se aplica un evento enrutado de entrada del

puntero en el control para cambiarle la

propiedad FontSize–>

<BeginStoryboard>

<Storyboard>

<DoubleAnimation

Storyboard.TargetProperty="FontSize"

To="36" Duration="0:0:1" />

<!–se le aplica el nuevo valor de FontSize durante 1 sg–>

</Storyboard>

</BeginStoryboard>

</EventTrigger>

<EventTrigger RoutedEvent="Button.MouseLeave">

<!–al salir el puntero del boton vuelve al tamaño original–>

<BeginStoryboard>

<Storyboard>

<DoubleAnimation

Storyboard.TargetProperty="FontSize"

To="12" Duration="0:0:0.25" />

<!–el cambio del tamaño del botón se realizará durante 25 sg–>

</Storyboard>

</BeginStoryboard>

</EventTrigger>

</Style.Triggers>

</Style>

</StackPanel.Resources>

 

<Button>Botón No. 1</Button>

<Button>Botón No. 2</Button>

<Button>Botón No. 3</Button>

<Button>Botón No. 4</Button>

<Button>Botón No. 5</Button>

<Button>Botón No. 6</Button>

<Button>Botón No. 7</Button>

<Button>Botón No. 8</Button>

<Button>Botón No. 9</Button>

<!–controles a los que se les aplica el efecto ojo de pez–>

</StackPanel>

De este modo he conseguido un efecto llamativo que puedo aplicar en un listado de artículos, referenciados por su correspondiente imagen, destacando el que vamos a seleccionar con el efecto ojo de pez.