Efecto Aero mediante WPF

Con la llegada de Windows Vista apareció el efecto Aero, pero como realizar este efecto en las aplicaciones de WPF que desarrollamos con Visual Studio 2008 y además que este efecto se aplique a toda la ventana de la aplicación??

Bien pues aquí te muestro una solución que te llevará por una serie de pasos para lograr el efecto deseado.

Una vez creado un nuevo proyecto de WPF y añadirle los distintos controles vamos a meternos en faena. Empezaremos añadiendo la referencia PresentationFramework.Aero para que nuestra aplicación utilice las correspondientes librerías a la hora de realizar el efecto.

Crearemos una nueva clase que deberá contener las directivas:

  • using System.Runtime.InteropServices;
  • using System.Collections.Generic;

Dentro de la clase introduciremos el siguiente código:

namespace AeroGlassExample

{

public class GlassHelper

{

struct MARGINS

{

public MARGINS(Thickness t)

{

Left = (int)t.Left;

Right = (int)t.Right;

Top = (int)t.Top;

Bottom = (int)t.Bottom;

}

public int Left;

public int Right;

public int Top;

public int Bottom;

}

 

[DllImport("dwmapi.dll", PreserveSig = false)]

static extern void DwmExtendFrameIntoClientArea(IntPtr hwnd, ref MARGINS margins);

 

[DllImport("dwmapi.dll", PreserveSig = false)]

static extern bool DwmIsCompositionEnabled();

//utilización de las diferentes apis para realizar el efecto

 

public static bool ExtendGlassFrame(Window window, Thickness margin)

{

if (!DwmIsCompositionEnabled())

return false;

 

IntPtr hwnd = new WindowInteropHelper(window).Handle;

if (hwnd == IntPtr.Zero)

throw new InvalidOperationException("The Window must be shown before extending glass.");

 

// Estableces transparencia tanto para WPF como para Win32

SolidColorBrush background = new SolidColorBrush(Colors.Red);

background.Opacity = 0.5;

window.Background = Brushes.Transparent;

HwndSource.FromHwnd(hwnd).CompositionTarget.BackgroundColor = Colors.Transparent;

 

MARGINS margins = new MARGINS(margin);

DwmExtendFrameIntoClientArea(hwnd, ref margins);

return true;

}

}

}

Esta clase será las que marque el marco de aplicación del efecto Aero y será utilizada en el código Behind de nuestra aplicación.

Ahora nos situaremos en el código Behind, por defecto (Window1.xaml.cs) e incluiremos las siguientes lineas de código:

public partial class Window1 : Window

{

private int _top = 10, _left = 10, _right = 200, _bottom = 200;

private bool neverRendered = true;

public Window1()

{

InitializeComponent();

this.SourceInitialized += new EventHandler(Window1_SourceInitialized);

}

private void OnMove(object s, DragDeltaEventArgs e)

{

_left += (int)e.HorizontalChange;

_top += (int)e.VerticalChange;

this.Left = _left;

this.Top = _top;

 

}

void Window1_SourceInitialized(object sender, EventArgs e)

{

GlassHelper.ExtendGlassFrame(this, new Thickness(-1));

}

protected override void OnContentRendered(EventArgs e)

{

if (this.neverRendered)

{

//La ventana toma el tamaño del contenido

//porque SizeToContent establece el tamaño a través de Width And Height.

//A continuación, permite establecer al usuario el tamaño de la ventana

//con su correspondiente efecto Aero

this.SizeToContent = SizeToContent.Manual;

 

FrameworkElement root = this.Content as FrameworkElement;

if (root != null)

{

root.Width = double.NaN;

root.Height = double.NaN;

}

 

this.neverRendered = false;

}

 

base.OnContentRendered(e);

}

}

De este modo conseguiremos crear el efecto Aero en toda la ventana, consiguiendo que las aplicaciones se integren en el entorno de Windows Vista de una forma sutil y sencilla.

EfectoAerom1

Efecto reflexión

Trasteando con Microsoft Expression Blend2 he conseguido crear un efecto llamativo y que le da un toque sutil a nuestra aplicación.

El punto de partida es la inserción de un Media Element (un video en mi caso), seguidamente crearemos el efecto de reflexión de dicho elemento.

Lo primero que debemos hacer es introducir un video a nuestro proyecto. Para ello debemos situarnos en el explorador de archivos de Expression Blend, haremos click con el botón derecho sobre nuestro proyecto y le indicamos agregar elemento existente, en nuestro caso un video.

Efectorefle1

El siguiente paso es arrastrar el video que está situado en el explorador de soluciones a la pantalla principal de nuestra aplicación, después seleccionaremos Herramientas->Crear Recurso de Pincel->Crear Recurso Visual Brush. Le otorgaremos un nombre a nuestro pincel”reflejo” y el área de definición será toda la ventana.

Efectorefle2

De este modo se ha creado un pincel de nuestro video que vamos a utilizar para realizar el efecto de reflexión

Ahora seleccionamos de la barra de herramientas el objeto rectángulo, y le damos el mismo tamaño que el video pero situando en la parte inferior de nuestro entorno de trabajo.

Teniendo seleccionado el objeto rectángulo, nos situaremos en la pestaña propiedades, en el apartado Pinceles, seleccionamos la propiedad Fill. Seleccionamos Recursos de Pincel Efectorefle3 , aparecerá nuestro pincel “reflejo”, lo seleccionamos y tenemos un reflejo de el video. Pero te preguntarás pero el reflejo no tiene que ser invertido, si ciertamente. Para lógralo nos situamos en la sección Transformación y seleccionamos en una primera instancia Voltear  Efectorefle4 y seguidamente Voltear eje Y Efectorefle5 .

Para que nuestra reflexión sea más sofisticada lo que haremos es quitarle algo de opacidad. Con el objeto rectángulo seleccionado, en la sección Pinceles, seleccionamos la propiedad OpacityMask, luego el pincel de degradado  Efectorefle6 y accedemos al apartado Apariencia, donde pondremos el valor de la propiedad Opacity al 50%.

Por último ejecutaremos la aplicación F5 y de este modo hemos creado el llamativo efecto de reflexión.

Efectorefle7

Control del foco en un formulario

En esta nueva entrada del blog deseo mostrar un caso sencillo a la vez que útil. Me voy a poner en situación, tenemos un formulario típico, con una serie de datos que rellenar que serán utilizados de el modo que se crea conveniente. Que pasa cada vez que introducimos un dato en cada campo de un formulario y deseamos pasar al siguiente, pues que perdemos tiempo en utilizar el ratón para cambiar al siguiente dato, creando la incomodidad correspondiente al usuario final. Como la finalidad de WPF es crear una experiencia de usuario satisfactoria, vamos a pasar al siguiente campo con la tecla Enter, así evitaremos la citada incomodidad.

Creo el formulario con sus correspondientes elementos:

<Window x:Class="WpfApplication2.Window1"

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

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

Title="Window1" Height="300" Width="300">

<Window.Resources>

<!–creación de estilos para los–>

<!–diferentes controles del formulario–>

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

<Setter Property="Width" Value="60"/>

<Setter Property="Margin" Value="4"/>

<Setter Property="Background" Value="Azure"/>

 

</Style>

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

<Setter Property="Width" Value="160"/>

<Setter Property="Margin" Value="4"/>

</Style>

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

<Setter Property="Width" Value="160"/>

<Setter Property="Margin" Value="4"/>

</Style>

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

<Setter Property="Margin" Value="4"/>

</Style>

</Window.Resources>

<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Name="documentRoot">

<Grid.RowDefinitions>

<RowDefinition/>

<RowDefinition/>

<RowDefinition/>

<RowDefinition/>

<RowDefinition/>

</Grid.RowDefinitions>

<Label Target="{Binding ElementName=DNI}" Content="_DNI:" Grid.Column="0" Grid.Row="0"/>

<TextBox Name="DNI" Grid.Column="1" Grid.Row="0"/>

<Label Target="{Binding ElementName=NomUs}" Content="_Usuario:" Grid.Column="0" Grid.Row="1"/>

<TextBox Name="NomUs" Grid.Column="1" Grid.Row="1"/>

<Label Target="{Binding ElementName=Password}" Content="_Password:" Grid.Column="0" Grid.Row="2"/>

<PasswordBox Name="Password" Grid.Column="1" Grid.Row="2"/>

<StackPanel Grid.Row="3" Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Center">

<Button Content="_Login" Name="logarse" IsDefault="True"/>

<Button Content="_Cancelar" Name="cancelar" IsCancel="True"/>

</StackPanel>

</Grid>

</Window>

Ahora me situaré en Window1.xaml.cs del proyecto que estoy elaborando, dicho código que la parte lógica de nuestra aplicación. Seguidamente introduciré el código que hace posible el cambio de foco en los distintos elementos mediante la tecla Enter:

public partial class Window1 : Window

{

public Window1()

{

InitializeComponent();

this.documentRoot.AddHandler(TextBox.KeyDownEvent, new KeyEventHandler(documentRoot_KeyDown));

//controlamos el evento de la tecla Enter en los textbox

this.logarse.Click += new RoutedEventHandler(loginButton_Click);

this.cancelar.Click += new RoutedEventHandler(cancelButton_Click);

 

}

private void cancelButton_Click(Object sender, RoutedEventArgs e)

{

MessageBox.Show("formulario cancelado");

}

 

private void loginButton_Click(Object sender, RoutedEventArgs e)

{

MessageBox.Show("envio de datos");

}

 

private void documentRoot_KeyDown(Object sender, KeyEventArgs e)

{

if (e.Key == Key.Return)

//compara que la tecla obtenida sea distinta de Enter

{

UIElement focusedElement = Keyboard.FocusedElement as UIElement;

if (focusedElement != null)

{

focusedElement.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));

//al presionar Enter pasaria al siguiente textbox,para ser rellenado por el usuario

}

e.Handled = true;

}

}

 

}

De este modo hemos conseguido mejorar la eficiencia del usuario final, en cuyo caso si es un grabador de datos lo agradecerá enormemente.

Gráficas en WPF

El gran volumen de datos que manejan las empresas en la actualidad, hace que la presentación de estos sea clara y concisa. Una de las herramientas para poder presentar los datos en Windows Presentation Foundation es la utilización de la librería que nos ofrece de forma gratuita el equipo de desarrollo de amCharts.

Una vez descargada dicha librería, esta nos permitirá la utilización de las distintas formas de presentación de los datos (barras,sectores,líneas,etc.) en Visual Studio 2008.

objetos_2_22090C8A

Para poder utilizar estas herramientas, creamos un nuevo proyecto WPF desde Visual Studio. Seguidamente nos situamos en la barra de herramientas de Visual Studio 2008, haremos clic con el botón derecho sobre ella y presionamos sobre la opción elegir elementos. En la ventana emergente, escogeremos la pestaña Componentes WPF,presionando el botón examinar tendremos la opción de seleccionar la ubicación de nuestra librería y así su posterior uso.

Ahora que tenemos los iconos correspondientes en la barra de herramientas, seleccionamos para empezar Pie Chart. Establecemos el área donde se va a realizar la presentación de nuestros datos. Al introducir dicha herramienta en el área de trabajo, en al área dedicada al código XAML, se introducirá el siguiente código:

<am:PieChart Height=”171″ Margin=”81,39,129,0″ Name=”pieChart1″ VerticalAlignment=”Top” />

El siguiente paso es añadir los diferentes sectores a nuestro control. Cada sector debe representarse mediante el siguiente código:

<am:Slice Title=”Mantenimiento” Value=”78″ />

Las propiedades que podemos usar en cada sector son el titulo y el porcentaje que va a ocupar dicho sector.Cada vez que añadamos un sector nuevo este será presentado

con un color diferente de forma automática, además aparecerá en la parte inferior del control la leyenda del mismo.

image_2_22090C8A

El siguiente control que podemos insertar es la representación de línea de datos.Esta se compondrá de una serie de valores unidos a través de una línea, el usuario podrá representar diversas líneas en función de las necesidades del mismo.

La representación como en el anterior caso se realizará o bien introduciendo el control desde la barra de herramientas o a través del editor Xaml del siguiente modo:

<am:LineChart Name=”lineChart1″>
            <!–Control lineal–>
            <am:LineChart.Graphs>
                <!–contenedor de las diferentes líneas de datos–>
                <am:LineChartGraph Title=”Chart #1″>
                    <!–Línea de Datos–>
                   <am:LineChartGraph.DataItems>
                        <!–cada uno de los valores que–>
                        <!–se representarán en la gráfica–>
                        <am:LineDataPoint SeriesID=”1″ Value=”1″ />
                        <am:LineDataPoint SeriesID=”2″ Value=”4″ />
                        <am:LineDataPoint SeriesID=”3″ Value=”6″ />
                        <am:LineDataPoint SeriesID=”4Value=”5″ />
                        <am:LineDataPoint SeriesID=”5″ Value=”2″ />
                        <am:LineDataPoint SeriesID=”6″ Value=”4″ />
                        <am:LineDataPoint SeriesID=”7″ Value=”5″ />
                    </am:LineChartGraph.DataItems>
               </am:LineChartGraph>
            </am:LineChart.Graphs>
        </am:LineChart>

image_4_4FF65F42

La última representación de datos seria a través de columnas. Añadiremos nuevamente el control a través de la barra de herramientas o a través del editor de código Xaml introduciendo el siguiente código:

<am:ColumnChart Name=”ColumnChart1″>
            <!—Control de columnas–>
            <am:ColumnChart.Graphs>
                <!–contenedor de las diferentes columnas de datos–>
                <am:ColumnChartGraph=”Gastos2009″>
                    <!–columna de Datos–>
                   <am:ColumnChartGraph.DataItems>
                        <!–cada uno de los valores que–>
                        <!–se representarán en la gráfica–>
                        <am:ColumnDataPoint SeriesID=”1″ Value=”1″ />
                        <am:ColumnDataPoint SeriesID=”2″ Value=”4″ />
                        <am:ColumnDataPoint SeriesID=”3″ Value=”6″ />
                        <am:ColumnDataPoint SeriesID=”4Value=”5″ />
                        <am:ColumnDataPoint SeriesID=”5″ Value=”2″ />
                        <am:ColumnDataPoint SeriesID=”6″ Value=”4″ />
                        <am:ColumnDataPoint SeriesID=”7″ Value=”5″ />
                    </am:ColumnChartGraph.DataItems>
               </am:ColumnChartGraph>
            </am:ColumnChart.Graphs>
        </am:ColumnChart>

 

 

image_6_4FF65F42

Como podemos ver, los diferentes controles de la herramienta utilizada , dan un toque diferenciado a la hora de la representación de los datos. Ahora solo queda jugar con esta herramienta a nuestro antojo.