Recreando GaugeHector.xaml

Hola qué tal, pues en esta ocasión, a petición de nuestro buen amigo Microsoft MVP Gonzalo Pérez, enseñaré como recrear la versión de GaugeHector.xaml en Expression Blend:

image

Bien, lo primero que hice, fue copiar una de las versiones del control, creados por Gonzalo, para empezar a trabajar del mismo, en mi caso, he escogido la versión GaugeV3b.xaml:

image

Primeramente, cambiemos los colores del fondo, esto se hace selccionando el objeto fondo, que es un círculo:

image 

, y le cambiamos a la propiedad fill, los siguientes valores:

Radial Grandient, con cuatro Gradient Stops, con los valores de izquierda a derecha:

1.- #FF7FC1F8

2.- #FF7DD2EA

3.- #FF48BAEA

4.- #FF1368AD

Con una separación mas o menos así:

image

Nos quedará algo mas o menos así:

image

Posteriormente, tenemos que ajustar, con la herramienta de degradado (Gradient Tool), a algo mas o menos así:

image

Listo, pacemos a recrear las dos lineas siguientes:

image

Esta seguramente es la parte mas complicadita del diseño, pero puede ser resuelta a través de las operaciones entre paths que nos permite realizar Expression Blend sin mayor esfuerzo.

En primer lugar, crearemos 2 círculos, uno encima de otro, puedes bajarle el valor alpha al círculo que irá encima, para que puedan quedar bien ajustado, creo que una imagen vale mas que mil palabras:

image

Como ves en la imagen, he creado 2 círculos, el amarillo servirá para “recortar”  el círculo externo. Pero antes, hagamos una copia del círculo amarillo, y lo ocultaremos, ya que nos servirá mas adelante:

image

Ahora, ya podemos hacer el recorte, seleccionamos primero el círculo amarillo que está visible, y posteriormente el círculo rojo, o sea el que está detrás del amarillo:

image

Acto seguido, nos vamos a menú-Object->Combine->Substract:

image

con esto, verás como es recortado el círculo

image

Cambiémosle el color por este: #FF555B6B

También, debemos cambiar al mismo color, todos los objetos dentro del contenedor Marcadores , con lo que obtendremos algo así:

image

El siguiente paso, es recortar el círculo, esto lo haremos de la misma forma, con operaciones entre paths, crearemos dos cuadrados, cada uno  en los límites del círculo con la enumeración del tacómetro, y sustraeremos de nuevo el cuadrado, menos el círculo:

image —-> image

image –>image

lo que resta, es de nuevo, sustraer un cuadrado, a la parte que ha quedado flotando del círculo:

image ->image

Listo, primera línea hecha! 🙂

Ahora, haremos lo mismo para crear una segunda línea, pero cortada en el número 40 y el número 100, para no repetir todo de nuevo, solo pondré algunas imagenes:

image

image

image

image

image

image 

image

image

image

Perfecto, ahora solo basta ponerle un degradado lineal, con 7 Gradient Stops con los valores:

1.-#FFC9D425

2.-#FFF0F6A1

3.-#FFEBF28B

4.-#FFE07D1C

5.-#FFEA8D09

6.-#FFEE4F4F

7.-#FFCD1212

Acomodados de la siguiente forma:

image

Después de hacer un reacomodo a los números, cambiar las propiedades Fill del objeto borde a negro, y de sombra a Nulo, debemos tener algo como esto:

image 

Excelente, pasemos a retocar el rectángulo del centro, el cual es llamado marco

image

Dentro de este, existe un objeto llamado fondo texto, será el primero a retocar, cambiandole los colores del gradiente a estos valores:

Izquierdo: #FF125F7C

Derecho: #FFFFFFFF

image

Modificaremos el fondo con la herramienta de degradado:

image

Ahora, crearemos un círculo dentro de nuestro canvas llamado marco, con los siguientes valores de relleno:

Stroke: No brush

Fill: Lineal Brush con  dos gradientes, el izquierdo con el valor #00FFFFFF y Alpha del 0%; y el derecho con valor #7FFFFFFF y con Alpha del 50%, y el fondo, modificado con la herramienta de degradado así:

image

Con lo que nuestro tacómetro debe lucir así:

image

Lo que falta ahora, es crear ese efecto de reflejo que va encima del control, lo mostraré con imagenes de nuevo, ya que se hace de nuevo a través de operaciones path:

image

image

Al resultado, le agregaremos un relleno gradiente, con 2 gradientStops, ambos de color blanco, pero con valores Alpha diferentes, el primero con 0% de Alpha, y el segundo con 20% de Alpha, con lo que obtendremos:

image

Ya por último, agregamos un círculo color blanco, con Stroke nulo, y con valor de alpha al 16% para dar una mejor impresión, con lo que el resultado final será:

image

 

Listo :D, ha quedado resuelto, como vemos, las operaciones path nos permiten hacer cosas maravillosas.

AHORA SÍ, NO TIENES PRETEXTOS PARA NO CREAR TU VERSION, HAZ TU PROPIA VERSION DEL CONTROL, Y APOYA ESTE PROYECTO!!!.

Mas información en el blog de Gonzalo:  http://geeks.ms/blogs/gperez/

Salu2

Héctor Uriel Pérez Rojas

AutoComplete TextBox en WPF

Hace algunos días, durante el desarrollo de un proyecto, me di cuenta que este es un control que debería sin duda, estar entre los controles de WPF, sin embargo, otra es la realidad.

Así que, en este post, crearemos un Autocomplete TextBox de una manera muy pero muy sencilla, de hecho, será un ComboBox el que utilizaremos para este fin:

1.- En primer lugar, he creado un ComboBox, al cual le he agregado algunos elementos del tipo TextBlock:

image

Con esto tendremos un ComboBox común y corriente:

image

2.- Lo único que debemos hacer, es cambiar 2 propiedades del ComboBox, a verdaderas, las cuales son “IsEditable” y “StaysOpenOnEdit”

image

image

3.- Ponerle un nombre al ComboBox  (En mi caso le he puesto miComboBox), y posteriormente agregar un evento del tipo GotFocus, con el siguiente código:

   1: private void miComboBox_GotFocus(object sender, System.Windows.RoutedEventArgs e)

   2: {

   3:     miComboBox.IsDropDownOpen = true;

   4: }

Esto nos servirá, para que la lista sea abierta cada vez que entremos en el ComboBox.

4.- Editar la copia del ComboBox

image

y eliminar el elemento ToggleButton:

image

image

5.- Todo listo, a probarlo!!!!

image

Wow, funciona de maravilla 😀

En el siguiente post, mostraré cómo usarlo de una manera más práctica ;), hasta entonces, nos vemos.

Salu2

Héctor Uriel Pérez Rojas

Convirtiendo controles 2-D en 3-D en WPF

Bien, hola qué tal de nuevo? Ok en la sección de Preguntas y Respuestas Tere pregunta cómo poder manipular un TextBox en Expression Blend como si un objeto 3-D se tratara.

Bien pues aquí les explico 3 formas en las que se puede hacer, casi lo mismo(porque no en todos es tan sencillo).

Bueno, primero entender que como su nombre lo dice, la función de «Make Image 3D» funciona solo para convertir imágenes en objetos 3-D, no para otro tipo de controles, por lo tanto:

Forma # 1:

Vamos a crear un nuevo proyecto, insertamos un textbox:

13d

Acto seguido, teniendo el TextBox seleccionado, lo convertimos en un VisualBrush:

23d

Le pones el nombre que desees, y ya lo tendrás disponible para usarlo.

Posteriormente, lo que tienes que hacer es insertar una imagen, y convertirla en 3-D:

33d

Vale, ahora que tienes una imagen 3-D, tienes que agregarle como material el VisualBrush que has creado anteriormente al modelo:

43d

Por si no lo alcanzas a ver, el elemento al que modificamos el material se encuentra en :

ViewPort3D->ModelContainer->Content->Model (Cuadro Rojo)

el cual te mostrará en las propiedades un BackMaterial y un Material(Cuadro amarillo), una vez seleccionado el mismo, te mostrará los Brushes que pudes agregarle, en la seccion de hasta la derecha, se encuentran tus propios Brushes, en el cual estará el que has creado hace un momento, al momento de seleccionarlo automáticamente la imagen obtendrá una «copia» de lo que esté pasando en el TextBox original, con esto podrás mover la imagen como si fuera un objeto tridimensional, pero…. hay un pequeño problema…..

NO PUEDES ESCRIBIR SOBRE ÉL; ¿Porqué? Pues porque es una simple imágen. Esto sirve principalmente para animar labels, texblocks, etc; pero si lo que quisieras es escribir realmente en el textbox, lo puedes hacer con la siguiente forma:

 

Forma # 2:

Para esta forma, requieres bajar las 3D Tools for the Windows Presentation Foundation, misma que fue creada por el equipo 3D de WPF.

Bien, voy a crear un nuevo proyecto, agrego una referencia a la DLL que se encuentra dentro de la carpeta que acabo de descargar con el nombre de 3DTools.dll

63d

53d

Ahora agregas una referencia al assembly desde el código XAML:

73d

NOTA: Para los que no saben que acabo de hacer, estoy creando una referencia a la DLL que agregué, paso a paso quiero decir:

xmlns = xml namespace; o sease que estoy creando una referencia a un espacio de nombres.

xmlns:local = Estoy nombrando de alguna forma mi acceso al assembly, en este caso local, aunque pudo haber sido cualquier otro.

«clr-namespace:_3dTools; = clr-namespace es la sintaxis para ubicar un espacio de nombres

assembly=3DTools»  = Es el ensamblado o la librería que acabamos de agregar, y donde se encuentra _3dTools.

Bien, ahora, procedemos a escribir el código que empezará a crear en sí los objetos 3D:

83d

<Window.Resources> 
    <MeshGeometry3D x:Key=»3dMesh»
        Positions=»-1,1,0 -1,-1,0 1,-1,0 1,1,0″
        TextureCoordinates=»0,0 0,1 1,1 1,0″
        TriangleIndices=»0 1 2 0 2 3″/> 
    <RotateTransform3D x:Key=»3dTransform»>
      <RotateTransform3D.Rotation>
        <AxisAngleRotation3D Angle=»45″ Axis=»0 1 1″ />
      </RotateTransform3D.Rotation>
    </RotateTransform3D> 
    <Grid Background=»White» x:Key=»3dMaterial»>
      <Grid.RowDefinitions>
        <RowDefinition Height=»*»/>
        <RowDefinition Height=»*»/>
        <RowDefinition Height=»*»/>
      </Grid.RowDefinitions> 
      <TextBox Grid.Row=»0″>Demo con WPF 3D Tools</TextBox>
      <Slider Grid.Row=»1″ />
      <Button Grid.Row=»2″ Width=»60″ Height=»25″>Aceptar</Button> 
    </Grid> 
  </Window.Resources>

jeje, parece un poco complicado, pero trataré de explicar un poco:

Empiezo definiendo dentro de los Recursos de la aplicación (Window.Resources), en primer lugar, un mashGeometry3D(Geometría de malla), el cual será el encargado de darle forma a mi objeto 3D, esto lo hago con positions(Posiciones Vertex de mi malla), TextureCoordinates(Sirve para definir las coordenadas de mi textura) y TriangleIndices(Indices Triangulares); estos son los recursos base  para definir la textura de mi objeto 3D. Posteriormente Hago un RotateTransform3D para voltear un poco mi objeto 3D, y agrego una serie de elementos(Grilla, dentro de la misma un textbox, un slider y un botón). Como puedes darte cuenta, a cada uno de los elementos que ligaremos les hemos puesto un x:Key, que servirá para referenciarlos (3dMes, 3dTransform y 3dMaterial)

Ahora, el código en sí de la aplicación:

93d

<Grid> 
    <local:TrackballDecorator>
    <local:Interactive3DDecorator> 
      <Viewport3D Width=»450″ Height=»225″> 
        <Viewport3D.Camera>
          <PerspectiveCamera Position=»0, 0, 4″  FieldOfView=»75″ />
        </Viewport3D.Camera> 
        <ModelVisual3D>
          <ModelVisual3D.Content>
            <DirectionalLight Color=»White» Direction=»0,0,-1″ />
          </ModelVisual3D.Content>
        </ModelVisual3D> 
        <local:InteractiveVisual3D
            Transform=»{StaticResource 3dTransform}»
            Geometry=»{StaticResource 3dMesh}»
            Visual=»{StaticResource 3dMaterial}» />
      </Viewport3D> 
    </local:Interactive3DDecorator>
    </local:TrackballDecorator> 
  </Grid>

Aquí, lo que estamos haciendo es, en primer lugar:

<local:TrackballDecorator> = Ingresamos a los métodos de nuestra clase Tools3D, este principalmente nos sirve para hacer un zoom in y zoom out, además de hacer rotación a voluntad del objeto.

<local:Interactive3DDecorator> = Sirve para interactuar con los elementos de nuestro modelo 3D

<Viewport3D… =  Definimos un Viewport3D, así como el que se crea cuando convertimos una imagen en 3D

<Viewport3D.Camera> = Agregamos una cámara

<PerspectiveCamera = Posicionamos la camara

<ModelVisual3D Creamos nuestro modelo 3D

<ModelVisual3D.Content = En nuestro caso, lo estamos usando para agregar una luz

<local:InteractiveVisual3D
            Transform=»{StaticResource 3dTransform}»
            Geometry=»{StaticResource 3dMesh}»
            Visual=»{StaticResource 3dMaterial}» />

Hacemos un binding de cada una de las propiedades de nuestro objeto interactivo 3D, uno al Transform, otro a la malla que definimos, y el último al material 3D(este último contendrá nuestros controles).

Y bien, luego luego aparece en el diseñador el aspecto que nuestra aplicación tiene, y al cual al correrlo, se observa así:

103d

He seleccionado el texto para que veas que efectivamente funciona, ahora puedes de igual manera acercar o alejar el objeto, y rotarlo a tu gusto:

113d

Si no quieres que aparezca cortado el control, lo único que tienes que hacer es poner en falsa la propiedad «CliptoBounds»:

123d

Forma # 3:

Bien, hemos usado una DLL en la forma anterior, sin embargo, con el Framework 3.5 se incluye un control para colocar objetos 2D dentro de objetos 3D,  su nombre es Viewport2DVisual3D; para lo que tendremos que agregar otro espacio de nombres:

xmlns:d=»http://schemas.microsoft.com/expression/blend/2008″

Seguiremos con el proyecto anterior para que te des una idea mas clara de como funciona esto. Primero borra todas las referencias de código que empiecen con <local: …/>, menos la de <local:InteractiveVisual3D.

Lo que vas a hacer ahora, es cambiar esa referencia <local:InteractiveVisual3D , por un elemento Viewport2DVisual3D

        <Viewport2DVisual3D
            Transform=»{StaticResource 3dTransform}»
            Geometry=»{StaticResource 3dMesh}»
            Visual=»{StaticResource 3dMaterial}»>
        </Viewport2DVisual3D>
      </Viewport3D>

Ahora, lo único que falta es agregar el material en sí del objeto Viewport2DVisual3D:

<Viewport2DVisual3D.Material>
    <DiffuseMaterial Viewport2DVisual3D.IsVisualHostMaterial=»true»/>
</Viewport2DVisual3D.Material>

Al final quedaría así:

<Viewport2DVisual3D
            Transform=»{StaticResource 3dTransform}»
            Geometry=»{StaticResource 3dMesh}»
            Visual=»{StaticResource 3dMaterial}»>
          <Viewport2DVisual3D.Material>
            <DiffuseMaterial Viewport2DVisual3D.IsVisualHostMaterial=»true»/>
          </Viewport2DVisual3D.Material>
        </Viewport2DVisual3D>

Con esto obtienes un resultado muy parecido al anterior,

143d

con la pequeña gran diferencia de que no pudes hacer zoom in, zoom out, ni rotar a voluntad en tiempo de ejecución, para lo cual, si gustas puedes agregarle funcionalidad nuevamente poniendo tu ViewPort3D dentro del elemento:

<local:TrackballDecorator> , con su etiqueta de cierre respectivamente.

Bueno, eso es todo, aquí les dejo los proyectos creados con cada una de las formas antes descritas:

Forma 1: 3D_Forma_1.rar-download

Forma 2: 3D_Forma_2.rar-download

Forma 3: 3D_Forma_3.rar-download

Bien, espero que hayáis entendido los conceptos básicos, una vez hecha cualquiera de las formas anteriores, es posible mover nuestros controles a entera libertad en Blend, que es lo que me habían pedido, si queréis aprender al 100 les recomiendo que lean un libro relacionado al mismo, uno que les puedo recomendar es:

3D Programming for Windows

http://www.charlespetzold.com/3D/index.html

Salu2, y por favor Tere o los demás, si pueden hacerme un feedback lo agradecería mucho, Salu2 y éxito!

Héctor Pérez

Introducción a WPF, y creación de una aplicación WPF 3-D, parte 2 de N.

 

Vale, qué tal a todos, en el post anterior empezamos a ver las maravillas de WPF, al crear un proyecto WPF nuevo, y al empezar a explicar el código en él contenido. Esta vez, veremos primeramente qué es XAML.

Creando una interfaz con XAML

XAML es la manera recomendada para crear interfaces de usuario en el modelo de programación de Windows Presentation Foundation, porque nos proporciona un método para separar la definición del diseño de la IU y la lógica. También permite integrar código usando archivos code-behind.

Con XAML también es posible crear una IU entera sin utilizar código. Esto lo demostramos a continuación. Recordáis el código de la vez anterior, pues aquí he agregado algún código mas:

<Window x:Class=»Window2″
    xmlns=»http://schemas.microsoft.com/winfx/2006/xaml/presentation»
    xmlns:x=»http://schemas.microsoft.com/winfx/2006/xaml»
    Title=»Window1″ Height=»300″ Width=»300″>
    <Grid>
        <Button Height=»100″ Width=»200″>
            Hola, soy un botón
        </Button>

    </Grid>
</Window>

 

Vale, pues el texto seleccionado es el que hemos insertado a nuestro código. Como véis, es un elemento del tipo botón, ahora bien, cabe resaltar que WPF tiene controles predefinidos, los cuales iremos usando a través de la creación de nuestra aplicación.

Entonces, el elemento Button, es el encargado de crear un nuevo botón dentro de nuestra grilla, como véis, las etiquetas de Button están dentro de las etiquetas Grid. Esto quiere decir que tenemos una estructura jerárquica, donde algunos elementos (casi siempre contenedores) son los que tienen como «hijos» a los demás elementos.

En este caso, de igual forma a Button se le ha definido un Height de 100 y un width de 200, que son los atributos propiamente del botón. Ahora bien, dentro del butón, tenemos el texto «Hola, soy un botón, lo cual quiere decir  que es el contenido del botón, pero no solamente puede ser texto, hubieramos podido insertar cualquier otra cosa, pero de eso hablaremos mas adelante. Por lo pronto, el resultado es el siguiente:

btn1

Vale, ahora procedamos a hacer algo un poco mas complejo, recordáis que les he dicho que una grilla es un contenedor? vale, pues también hemos mencionado que el botón soporta 1 solo elemento contenido(si, el que aparece entre <button>CONTENIDO</button>, asi que en teoría, podemos insertar una grilla como contenido del control, para después, insertar mucho mas contenido dentro del mismísmo botón!! Insertemos una grilla con el siguiente código:

<Window x:Class=»Window2″
    xmlns=»http://schemas.microsoft.com/winfx/2006/xaml/presentation»
    xmlns:x=»http://schemas.microsoft.com/winfx/2006/xaml»
    Title=»Window1″ Height=»300″ Width=»300″>
    <Grid>
        <Button>
            <Grid>             
            </Grid>
        </Button>
    </Grid>
</Window>

Como véis, hemos en primer lugar, quitado los ATRIBUTOS del botón, asi lograremos que el botón se ajuste a las dimensiones del elemento padre, es decir, de la grilla que lo está conteniendo, que a su vez, se está ajustando a las dimensiones de la ventana(window), y en segundo lugar, hemos reemplazado el contenido de CONTENT que era «Hola soy un botón» por una grilla, a la cual le modificaremos algunos atributos, como véis en el siguiente código:

<Window x:Class=»Window2″
    xmlns=»http://schemas.microsoft.com/winfx/2006/xaml/presentation»
    xmlns:x=»http://schemas.microsoft.com/winfx/2006/xaml»
    Title=»Window1″ Height=»300″ Width=»300″>
    <Grid>
        <Button>
           <Grid Height=»250″ Width=»250″ HorizontalAlignment=»Center»>             
            </Grid>
        </Button>
    </Grid>
</Window>

A este código solo le hemos cambiado el height y el width, aparte de un nuevo atributo: HorizontalAlignment, el cual nos dice hacia donde queremos ubicar el control en cuestión de su padre, en este caso en el centro.

El resultado es el siguiente:

grilla1

Vale, en la imagen se nota un cuadrado dentro del botón gris, esta es la grilla, pero pasemos a hacer algo mas interesante, insertaremos un video, una imágen y un textblock dentro del mismismo botón, para eso, expliquemos que son las rowsdefinitions y las columndefinitions:

RowDefinition: Dentro de la grilla, marca definiciones de una fila.

ColumnDefinition:Dentro de la grilla, marca definiciones de una columna.

Es decir, cuando aplicamos estas row y column definitions, lo que hacemos es crear como líneas a través de la grilla, con el propósito de guiarnos y de tener una mejor distribucion de los elementos dentro de una grilla. Esto lo ves en el siguiente código:

<Window x:Class=»Window2″
    xmlns=»http://schemas.microsoft.com/winfx/2006/xaml/presentation»
    xmlns:x=»http://schemas.microsoft.com/winfx/2006/xaml»
    Title=»Window1″ Height=»300″ Width=»300″>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width=»142*» />
            <ColumnDefinition Width=»136*» />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height=»131*» />
            <RowDefinition Height=»131*» />
        </Grid.RowDefinitions>
        <Button Grid.RowSpan=»2″ Grid.ColumnSpan=»2″>
            <Grid Height=»250″ Width=»250″ HorizontalAlignment=»Center»>             
            </Grid>
        </Button>
    </Grid>
</Window>

como ves, las column y row definitions se definen dentro del elemento <Grid></Grid>. Esto es porque pasa a ser un subelemento de Grid, aquí hemos definido 2 column y 2 row definitions. Meramente, las dimensiones mostradas son las de los espacios que hay ocupan cada uno de las definiciones de columna o de filas. El resultado es el siguiente:

grilla2

Como véis, el mismo visual studio nos muestra las respectivas dimensiones de los espacios, de las columnas 142, y 136, y de las filas 131 para cada una.

Ahora bien, para poder insertar apropiadamente el video primeramente, debemos añadirlo dando click derecho a nuestro poyecto, luego Add, y finalmente Existing Item:

exitem

Vale, ahora seleccionamos cualquier video que tengamos, preferentemente uno corto, como lo son los de prueba de Windows, en mi caso insertare el clásico de bear.wmv

sexplorer

Bien, ahora pasemos a agregar un control <MediaElement>

<Window x:Class=»Window2″
    xmlns=»http://schemas.microsoft.com/winfx/2006/xaml/presentation»
    xmlns:x=»http://schemas.microsoft.com/winfx/2006/xaml»
    Title=»Window1″ Height=»300″ Width=»300″>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width=»142*» />
            <ColumnDefinition Width=»136*» />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height=»131*» />
            <RowDefinition Height=»131*» />
        </Grid.RowDefinitions>
        <Button Grid.RowSpan=»2″ Grid.ColumnSpan=»2″>
            <Grid Height=»250″ Width=»250″ HorizontalAlignment=»Center»>
                <MediaElement Source=»Bear.wmv» Grid.Column=»0″ HorizontalAlignment=»Center» VerticalAlignment=»Top»/>
            </Grid>
        </Button>
    </Grid>
</Window>

Mas que nada, Media Element nos sirve para alojar contenido sobre todo de videos y de música. En este caso, hemos ajustado el alineamiento horizontal lal centro y el alineamiento vertial en «Top», es decir que se ajuste a la parte superior de quien lo contiene.

Bien, si vemos gráficamente esto, el resultado es:

media1

Ahora, si procedemos a ejeuctar esto, ocurre lo siguiente: No se reproduce ningún video. ¿Porqué ocurre esto? Pues porque no tenemos definida ninguna línea de tiempo que reproduzca este video. Sobre esto hablaremos después, por lo pronto, debemos insertar el siguiente código para que el video se reproduzca correctamente:

<Window x:Class=»Window2″
    xmlns=»http://schemas.microsoft.com/winfx/2006/xaml/presentation»
    xmlns:x=»http://schemas.microsoft.com/winfx/2006/xaml»
    Title=»Window1″ Height=»300″ Width=»300″ xmlns:d=»http://schemas.microsoft.com/expression/blend/2008″ xmlns:mc=»http://schemas.openxmlformats.org/markup-compatibility/2006″ mc:Ignorable=»d»>
   <Window.Resources>
        <Storyboard x:Key=»Bear_wmv»>
            <MediaTimeline BeginTime=»00:00:00″ Storyboard.TargetName=»Bear_wmv» Source=»Bear.wmv»/>
        </Storyboard>
    </Window.Resources>
    <Window.Triggers>
        <EventTrigger RoutedEvent=»FrameworkElement.Loaded»>
            <BeginStoryboard Storyboard=»{StaticResource Bear_wmv}»/>
        </EventTrigger>
    </Window.Triggers>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width=»142*» />
            <ColumnDefinition Width=»136*» />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height=»131*» />
            <RowDefinition Height=»131*» />
        </Grid.RowDefinitions>
        <Button Grid.RowSpan=»2″ Grid.ColumnSpan=»2″>
            <Grid Height=»250″ Width=»250″ HorizontalAlignment=»Center»>
            <Grid.ColumnDefinitions>
            <ColumnDefinition Width=»142*» />
            <ColumnDefinition Width=»136*» />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height=»131*» />
            <RowDefinition Height=»131*» />
        </Grid.RowDefinitions>
                <MediaElement x:Name=»Bear_wmv» Grid.Row=»0″  Grid.Column=»0″ VerticalAlignment=»Top» Height=»123.5″ Grid.ColumnSpan=»2″ Margin=»0,0,8,0″ />
        </Grid>
        </Button>
    </Grid>
</Window>

Vale, lo mas sobresaliente de este código, es que hemos creado una línea del tiempo (<Storyboard>), la cual dice:

<Storyboard x:Key=»Bear_wmv»> = Etiqueta de tipo linea del tiempo, con un nombre (o llave de key) que se llamará Bear_wmv

<MediaTimeline BeginTime=»00:00:00″ Storyboard.TargetName=»Bear_wmv» Source=»Bear.wmv»/> = Línea del tiempo del tipo media, con el tiempo de inicio 00:00:00 ( o sea que empiece a reproducir a partir de ese tiempo en el video), un objetivo que va a ser Bear_wmv, que es como hemos definido el MediaElement dentro de nuestra grilla, y con la fuente u orígen que será Bear.wmv propiamente.

Si os dáis cuenta, hemos quitado el Source del mediaelement dentro de la grilla dentro del botón, esto es debido a que será la la MediaTimeline quien apunte directamente al Mediaelement de nuestro botón.

Luego vienen los cierres de etiquetas.

Notad que esto se encuentra definido dentro de <Windows.Resources>, lo cual nos dice que se crearán recursos que estarán disponibles para usarlos cuando queramos y donde queramos en el programa.

Luego, se especifica lo siguente:

<Window.Triggers> = Son lanzadores del programa, o sea que se ejcutarán cuando cierta reacción se realicen en el programa .
        <EventTrigger RoutedEvent=»FrameworkElement.Loaded»> = en este caso, cuando nuestro programa sea cargado.
            <BeginStoryboard Storyboard=»{StaticResource Bear_wmv}»/> = Iniciará el storyboard llamado Bear_wmv, que es recurso estático
        </EventTrigger> = cierre de etiquetas
    </Window.Triggers> = cierre de etiquetas
El resultado es el siguiente:

boton2

Como veis, un vídeo reproduciéndose dentro de un botón!!

Ahora, lo que tenemos que hacer es agregar una imagen a nuestro proyecto, con click derecho sobre nuestro proyecto, agregar elemento existene. Agrega cualquier imagen.

Ahora, tenemos que referenciarla por medio de código, esto lo hacemos así:

<Window x:Class=»Window2″
    xmlns=»http://schemas.microsoft.com/winfx/2006/xaml/presentation»
    xmlns:x=»http://schemas.microsoft.com/winfx/2006/xaml»
    Title=»Window1″ Height=»300″ Width=»300″ xmlns:d=»http://schemas.microsoft.com/expression/blend/2008″ xmlns:mc=»http://schemas.openxmlformats.org/markup-compatibility/2006″ mc:Ignorable=»d»>
    <Window.Resources>
        <Storyboard x:Key=»Bear_wmv»>
            <MediaTimeline BeginTime=»00:00:00″ Storyboard.TargetName=»Bear_wmv» Source=»Bear.wmv»/>
        </Storyboard>
    </Window.Resources>
    <Window.Triggers>
        <EventTrigger RoutedEvent=»FrameworkElement.Loaded»>
            <BeginStoryboard Storyboard=»{StaticResource Bear_wmv}»/>
        </EventTrigger>
    </Window.Triggers>
    <Grid>

        <Button Grid.RowSpan=»2″ Grid.ColumnSpan=»2″>
            <Grid Height=»250″ Width=»250″ HorizontalAlignment=»Center»>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width=»142*» />
                    <ColumnDefinition Width=»136*» />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height=»131*» />
                    <RowDefinition Height=»131*» />
                </Grid.RowDefinitions>
                <MediaElement x:Name=»Bear_wmv» Grid.Row=»0″  Grid.Column=»0″ VerticalAlignment=»Top» Height=»123.5″ Grid.ColumnSpan=»2″ Margin=»0,0,8,0″ />
               <Image Source=»bluemonster.jpg» Grid.Column=»0″ Grid.Row=»1″></Image>
            </Grid>
        </Button>
    </Grid>
</Window>

 

De hecho, lo que ha insertado la imagen es el siguiente fragmento:

<Image Source=»bluemonster.jpg» Grid.Column=»0″ Grid.Row=»1″></Image>

El cual nos dice. etiqueta del tipo imagen, fuente=la imágen que hemos insertado, ponla en la definicion de columnas # 0 y filas #1, son como coordenadas. El resultado:

imagen

Finalmente, agregaremos un textbox dentro del botón, esto se hace con el código:

<Window x:Class=»Window2″
    xmlns=»http://schemas.microsoft.com/winfx/2006/xaml/presentation»
    xmlns:x=»http://schemas.microsoft.com/winfx/2006/xaml»
    Title=»Window1″ Height=»300″ Width=»300″ xmlns:d=»http://schemas.microsoft.com/expression/blend/2008″ xmlns:mc=»http://schemas.openxmlformats.org/markup-compatibility/2006″ mc:Ignorable=»d»>
    <Window.Resources>
        <Storyboard x:Key=»Bear_wmv»>
            <MediaTimeline BeginTime=»00:00:00″ Storyboard.TargetName=»Bear_wmv» Source=»Bear.wmv»/>
        </Storyboard>
    </Window.Resources>
    <Window.Triggers>
        <EventTrigger RoutedEvent=»FrameworkElement.Loaded»>
            <BeginStoryboard Storyboard=»{StaticResource Bear_wmv}»/>
        </EventTrigger>
    </Window.Triggers>
    <Grid>

        <Button Grid.RowSpan=»2″ Grid.ColumnSpan=»2″>
            <Grid Height=»250″ Width=»250″ HorizontalAlignment=»Center»>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width=»142*» />
                    <ColumnDefinition Width=»136*» />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height=»131*» />
                    <RowDefinition Height=»131*» />
                </Grid.RowDefinitions>
                <MediaElement x:Name=»Bear_wmv» Grid.Row=»0″  Grid.Column=»0″ VerticalAlignment=»Top» Height=»123.5″ Grid.ColumnSpan=»2″ Margin=»0,0,8,0″ />
                <Image Source=»bluemonster.jpg» Grid.Column=»0″ Grid.Row=»1″></Image>
                <TextBox Text=»Hello world» Grid.Column=»1″ Grid.Row=»1″ TextAlignment=»Center»></TextBox>
            </Grid>
        </Button>
    </Grid>
</Window>

 

La línea que nos crea el textbox es:

<TextBox Text=»Hello world» Grid.Column=»1″ Grid.Row=»1″ TextAlignment=»Center»></TextBox>

Que es prácticamente lo mismo que el de la imágen, con la diferencia de que estamos creando un Textbox, no una Image.

textbox

Pero para hacerlo un poco mas interesante, vamos a agregarle un color de fondo a nuestro Textbox, pero no será cualquier color, será un degradado, esto es muy fácil con WPF, tan solo con insertar el texto:

               <TextBox.Background> = Definimos que queremos rellenar el Background o fondo
                        <LinearGradientBrush EndPoint=»0.5,1″ StartPoint=»0.5,0″> = Decimos que será un gradiente linear, con un punto inicial en (.5,0) y un punto final en (.5,1) de nuestro textbox.
                            <GradientStop Color=»#FF000000″ Offset=»1″/> = Definimos uno de los colores de nuestro gradiente, en este caso Blanco, y con una «distancia» de 1
                            <GradientStop Color=»#FFFFFFFF» Offset=»0.013″/> = lo mismo que el anterior código, pero con un color negro
                        </LinearGradientBrush> =cierre de etiquetas
                </TextBox.Background> = Cierre de etiquetas

Lo que nos arroja lo siugente:

textbox2

Y listo, tenemos nuestro Textbox rellenado.le he cambiado el color de la letra para que se distinguiera mejor.

Aquí el código completo:

<Window x:Class=»Window2″
    xmlns=»http://schemas.microsoft.com/winfx/2006/xaml/presentation»
    xmlns:x=»http://schemas.microsoft.com/winfx/2006/xaml»
    Title=»Window1″ Height=»300″ Width=»300″ xmlns:d=»http://schemas.microsoft.com/expression/blend/2008″ xmlns:mc=»http://schemas.openxmlformats.org/markup-compatibility/2006″ mc:Ignorable=»d»>
    <Window.Resources>
        <Storyboard x:Key=»Bear_wmv»>
            <MediaTimeline BeginTime=»00:00:00″ Storyboard.TargetName=»Bear_wmv» Source=»Bear.wmv»/>
        </Storyboard>
    </Window.Resources>
    <Window.Triggers>
        <EventTrigger RoutedEvent=»FrameworkElement.Loaded»>
            <BeginStoryboard Storyboard=»{StaticResource Bear_wmv}»/>
        </EventTrigger>
    </Window.Triggers>
    <Grid>

        <Button Grid.RowSpan=»2″ Grid.ColumnSpan=»2″>
            <Grid Height=»250″ Width=»250″ HorizontalAlignment=»Center»>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width=»142*» />
                    <ColumnDefinition Width=»136*» />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height=»131*» />
                    <RowDefinition Height=»131*» />
                </Grid.RowDefinitions>
                <MediaElement x:Name=»Bear_wmv» Grid.Row=»0″  Grid.Column=»0″ VerticalAlignment=»Top» Height=»123.5″ Grid.ColumnSpan=»2″ Margin=»0,0,8,0″ />
                <Image Source=»bluemonster.jpg» Grid.Column=»0″ Grid.Row=»1″></Image>
                <TextBox Text=»Hello world» Grid.Column=»1″ Grid.Row=»1″ TextAlignment=»Center» Foreground=»#FF8617A8″>
                    <TextBox.Background>
                        <LinearGradientBrush EndPoint=»0.5,1″ StartPoint=»0.5,0″>
                            <GradientStop Color=»#FF000000″ Offset=»1″/>
                            <GradientStop Color=»#FFFFFFFF» Offset=»0.013″/>
                        </LinearGradientBrush>
                    </TextBox.Background>
                </TextBox>
            </Grid>
        </Button>
    </Grid>
</Window>

Y viendo la estructura jeráquica que hemos deifnido, quedaría así:

arbol1

Como veis, dentro de nuestra ventana de windows, tenemos nuestra primera grila, luego viene nuestro botón, sobre el cual hay insertada otra grilla, dentro de la misma tenemos un video, una imagen y un Textbox. 🙂

Vale, como véis, es bantante sencillo usar XAML, sin embargo, a veces por cuestión de tiempo, es mejor usar herramientas visuales, tales como la suite expression, de la cual hablaremos en nuestra próxima entrada, Hasta la vista!! y espero no haberlos aburrido

Salu2

Héctor Pérez