En este artículo veremos cómo crear una aplicación Silverlight que se pueda ejecutar tanto en el navegador como fuera de él.
Entre muchas otras cosas, Silverlight ahora permite crear aplicaciones enriquecidas, con la posibilidad de ejecutarse como aplicaciones independientes (que no tienen por qué estar embutidas dentro de un navegador web). Es algo que veremos con todo el detalle en este artículo, que estamos seguros que interesará a los lectores, por tratarse de una utilidad excelente para hacer programas con alto dinamismo y las funcionalidades avanzadas que nos permite esta plataforma de Microsoft.
Empezando
Para comenzar, abriremos Visual Studio 2008 y crearemos un nuevo proyecto de aplicación Silverlight que llamaremos FueraDelNavegador. Visual Studio nos preguntará si queremos alojar (host) la aplicación en un sitio Web; le indicaremos que sí, con lo que en realidad se nos creará una solución con dos proyectos: el primero (FueraDelNavegador) es la aplicación Silverlight propiamente dicha, mientras que el segundo (FueraDelNavegador.Web) es un proyecto ASP.NET de prueba en el que se alojará la aplicación para que podamos probarla.La interfaz de usuario de la aplicación que vamos a desarrollar constará de cuatro elementos TextBlock organizados de dos en dos en diferentes StackPanel. Además, hemos añadido un botón que le dé al usuario la opción de instalar la aplicación localmente. El código XAML relevante de MainPage.xaml se presenta en el listado 1.
Listado 1
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="¿Dónde estoy? " FontSize="24" />
<TextBlock x:Name="ModoEjecucion" FontSize="24" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="¿Tengo red?" FontSize="24" />
<TextBlock x:Name="ModoRed" FontSize="24" />
</StackPanel>
<Button x:Name="IrFueraDelNavegador" FontSize="24" Content="Instalar" Click="IraFueraDelNavegador_Click" />
</Grid>
Utilizaremos los controles de texto para que nos vayan indicando un par de características del entorno en el que se está ejecutando nuestra aplicación: si ésta se está ejecutando en el navegador y si tenemos una conexión de red disponible. Para que estos valores se actualicen nada más ejecutarse nuestra aplicación, nos suscribimos al evento Loaded de la página. En el gestor del evento, comprobamos si estamos dentro del navegador a través de la propiedad Application.Current.IsRunningOutOfBrowser. Para saber si disponemos de conexión de red, debemos utilizar el método estático IsNetworkAvailable de la clase NetworkInterface (ensamblado System.Net, espacio de nombres System. Net.NetworkInformation). En caso de encontrar una conexión de red, mostramos el mensaje en color verde, y si no se encuentra ninguna conexión disponible, en color rojo. Todo ello puede verse en el listado 2.
Listado 2
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
if (Application.Current.IsRunningOutOfBrowser)
{
ModoEjecucion.Text = " Estoy fuera del navegador";
}
else
{
ModoEjecucion.Text = " Estoy dentro del navegador";
}
ComprobarRed();
}
private void ComprobarRed()
{
if (NetworkInterface.GetIsNetworkAvailable())
{
ModoRed.Text = " Tengo conexión ";
ModoRed.Foreground = new SolidColorBrush(Colors.Green);
}
else
{
ModoRed.Text = " No encuentro ninguna red";
ModoRed.Foreground = new SolidColorBrush(Colors.Red);
}
}
Para que el control de texto que muestra el estado de la conexión a red se mantenga actualizado en todo momento, debemos hacer uso del evento NetworkChange.NetworkAddressChanged, al que nos suscribiremos en el constructor de la clase MainPage. En el gestor de este evento llamamos al método refactorizado ComprobarRed (listado 3).
Listado 3
public MainPage()
{
InitializeComponent();
Loaded += new RoutedEventHandler(MainPage_Loaded);
NetworkChange.NetworkAddressChanged += new NetworkAddressChangedEventHandler(NetworkAddressChanged);
}
void NetworkAddressChanged(object sender, EventArgs e)
{
ComprobarRed();
}
Si en este momento ejecutamos la aplicación, veremos el resultado en nuestro navegador Web predeterminado; algo similar será lo que verán nuestros usuarios al ejecutar la aplicación ya desplegada utilizando la URL correspondiente.
Ejecución fuera del navegador
Lo siguiente que vamos a hacer es dotar a la aplicación de la funcionalidad necesaria para que se pueda instalar y ejecutar de manera local, o sea, fuera del navegador (out-of-browser) en un ordenador cliente. Para ello, hemos agregado a la interfaz de usuario un botón que ejecutará esta función cuando el usuario haga clic en él. El código que debemos incluir en el evento Click de dicho botón se muestra en el listado 4, y es trivial: la llamada al método Install pondrá en marcha todo el proceso necesario para instalar la aplicación Silverlight en el sistema cliente.
Listado 4
private void IrFueraDelNavegador_Click(object sender, RoutedEventArgs e)
{
Application.Current.Install();
}
Además, necesitamos configurar nuestro proyecto para que sea capaz de instalarse de manera local. Para ello, debemos ir a las propiedades del proyecto FueraDelNavegador y en la pestaña Silverlight marcar la opción "Enable running application out of the browser". Al seleccionar esta opción, el botón llamado "Out-of-Browser Settings" se habilitará, y podremos indicar algunos valores de configuración para la aplicación, tales como el título de la ventana, ancho y altura de ésta, el nombre del acceso directo, una breve descripción de lo que se va a descargar, e iconos de diferentes tamaños. Además, aquí podemos especificar si queremos que la aplicación utilice la GPU de la máquina cliente, para que sea ella y no el procesador principal quien se encargue de renderizar los gráficos vectoriales, vídeos, efectos sobre píxeles, etc. Esta posibilidad también fue incorporada por primera vez en Silverlight 3.
En este punto ya tenemos una aplicación Silverlight que se puede instalar en una máquina local. Para comprobarlo, no tenemos más que ejecutar la aplicación desde Visual Studio, y pulsar sobre el botón "Instalar". Se abrirá un cuadro de diálogo preguntándonos si queremos añadir accesos directos a la aplicación en el escritorio y en el menú Inicio; después de indicar nuestras preferencias y aceptar, la aplicación se instalará y podremos ejecutarla localmente en lo adelante.
Antes de finalizar esta sección, veamos cómo lograr que cuando la aplicación se ejecute fuera del navegador no se muestre el botón de instalación. Esto lo conseguimos modificando un poco el código del listado 2, tal como se muestra en el listado 5.
Listado 5
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
if (Application.Current.IsRunningOutOfBrowser)
{
ModoEjecucion.Text = " Estoy fuera del navegador";
IrFueraDelNavegador.Visibility = Visibility.Collapsed;
}
else
{
ModoEjecucion.Text = " Estoy dentro del navegador";
IrFueraDelNavegador.Visibility = Visibility.Visible;
}
ComprobarRed();
}
Haciendo la aplicación actualizable
Una vez que podemos instalar la aplicación de manera local, caemos en la cuenta de que nos interesa mucho que esa aplicación pueda actualizarse de forma sencilla. Investigando un poco, vemos que existe una funcionalidad que nos permitirá lograr esto sin apenas esfuerzo. En pocas palabras, el método Application.CheckAndDownloadUpdateAsync comprueba si existen actualizaciones de nuestra aplicación y las descarga asíncronamente en caso de que existan. Al finalizar su trabajo, el método nos avisa disparando el evento CheckAndDownloadUpdateCompleted. A través de la propiedad UpdateAvailable del parámetro EventArgs de este evento podremos conocer si se encontró alguna actualización para la aplicación. El listado 6 muestra cómo hemos aprovechado esta característica en nuestra aplicación de ejemplo.
Listado 6
public partial class App : Application
{
public App()
{
// ...
this.CheckAndDownloadUpdateCompleted +=
new CheckAndDownloadUpdateCompletedEventHandler(CheckUpdates);
}
void CheckUpdates(object sender,CheckAndDownloadUpdateCompletedEventArgs e)
{
if (e.UpdateAvailable)
{
MessageBox.Show(@"Hay actualizaciones disponibles. Por favor, reinicie la aplicación");
}
}
private void Application_Startup(object sender, StartupEventArgs e)
{
this.CheckAndDownloadUpdateAsync();
this.RootVisual = new MainPage();
}
// ...
}
Si ahora compilamos y ejecutamos la aplicación con Visual Studio y arrancamos la versión que teníamos instalada, se nos avisará de que se ha descargado e instalado una actualización y se nos pedirá que la reiniciemos; al hacerlo, ya tendremos disponible las últimas características de nuestra aplicación Silverlight.
Añadiendo efectos visuales
No contentos con lo ya visto, repasaremos ahora de una forma rápida y práctica otras potentes características que también aparecieron por primera vez con Silverlight 3.Añadiremos a la interfaz de usuario un StackPanel más, que contendrá un elemento Image y un Slider (listado 7).
Listado 7
<StackPanel Orientation="Vertical" Margin="24">
<Image Source="trees-web.jpg" Stretch="Fill" Width="500">
<Image.Effect>
<BlurEffect Radius="0" x:Name="MiBlur">
</BlurEffect>
</Image.Effect>
</Image>
<Slider Grid.Row="1" Minimum="0" Maximum="10" Value="{Binding ElementName=MiBlur, Path=Radius, Mode=TwoWay}" MinWidth="192" HorizontalAlignment="Center" Margin="24">
</Slider>
</StackPanel>
El objetivo que queremos conseguir es poder aplicar efectos como DropShadowEffect (que añade sombras a los elementos) y BlurEffect (que los difumina). Añadimos también a la carpeta ClientBin del proyecto FueraDelNavegador. Web un archivo JPG que asociaremos al elemento Image. Además, en este código aprovechamos una forma de enlace a datos (binding) incorporada en Silverlight 3 que hace posible enlazar unos elementos a otros, de modo que los cambios que se produzcan en un elemento tengan efecto sobre otros, de una manera declarativa, sin necesidad de escribir explícitamente código para ello.
En este momento, podemos ejecutar la aplicación y jugar con la barra de desplazamiento, viendo cómo se va transformando la imagen. Observe cómo hemos enlazado la propiedad Value del Slider al efecto de difuminación de la imagen.
También se dará cuenta de que el elemento <Image.Effect> aparece en singular, no en plural, lo que nos da una idea de que solo se puede aplicar un efecto a un elemento de la interfaz de usuario. Pero saltar esta "restricción" y aplicar varios efectos a un mismo elemento de interfaz de usuario es realmente sencillo. Por ejemplo, podemos encapsular el elemento Image dentro de un elemento Border, y asociar a este elemento un efecto DropShadowEffect. Esto es lo que hace el código que se muestra en el listado 8, en el que además hemos añadido otro Slider para asociarlo al efecto de sombra.
Listado 8
<StackPanel Orientation="Vertical" Margin="24">
<Border Margin=" 24">
<Border.Effect>
<DropShadowEffect ShadowDepth="0" x:Name="MiSombra">
</DropShadowEffect>
</Border.Effect>
<Image Source="trees-web.jpg" Stretch="Fill" Width="500">
<Image.Effect>
<BlurEffect Radius="0" x:Name="MiBlur">
</BlurEffect>
</Image.Effect>
</Image>
</Border>
<Slider Grid.Row="1" Minimum="0" Maximum="10" Value="{Binding ElementName=MiBlur,Path=Radius, Mode=TwoWay}" MinWidth="192" HorizontalAlignment="Center" Margin="24">
</Slider>
<Slider Grid.Row="2" Minimum="0" Maximum="10" Value="{Binding ElementName=MiSombra,Path=ShadowDepth, Mode=TwoWay}" MinWidth="192" HorizontalAlignment="Center" Margin="24">
</Slider>
</StackPanel>
Conclusión
En este artículo hemos mostrado cómo aprovechar varias de las características que fueron incorporadas a Silverlight en la versión 3: poder ejecutar aplicaciones fuera del navegador, acceder al modo de conexión de que dispone nuestra máquina y enlazar elementos de la interfaz de usuario con otros. Además, la aplicación resultante es automáticamente actualizable.Como hemos dicho antes, el ciclo de evolución que está teniendo Silverlight es impresionante. Una verdadera vorágine a la que ya nos estamos acostumbrando los desarrolladores. Y un mundo que nos abre más y más puertas por las que pueda pasar nuestra imaginación, permitiéndonos crear aplicaciones cada vez más impresionantes. Desde aquí le recomiendo sinceramente comenzar desde ya a evaluar la versión beta de Silverlight 4.
Puede descargar el código fuente de la aplicación de ejemplo desde el sitio Web de dotNetManía.