Archivos para la Categoría 'Silverlight'

30
Ago
08

API Silverlight Streaming

Haciendo uso de las clases HttpWebRequest y HttpWebResponse que se encuentran en el NameSpace “System.Net”, podremos trabajar con el protocolo HTTP para realizarle pedidos (GET) y/o enviarle algo de informacion con (POST) a un servidor, explicado este punto vamos a ver el codigo.


        //Declaro estas variables cambiale los datos a los de tu cuenta o podrias crearte una ventanita de Login y obtenerlos.

        String accountID= "75844";
        String accountKey = "-------------------------------------";
        String servicesRoot = "https://silverlight.services.live.com/";      

Cada procedimiento tiene un nombre entendible así que no hace falta que lo explique.


private void cargarArchivos()
        {
            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(servicesRoot + accountID + "/?max-items");
            req.Credentials = new NetworkCredential(accountID, accountKey);

            try {

                HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
                Stream strm = resp.GetResponseStream();
                StreamReader reader = new StreamReader(strm);

                XmlTextReader xmlReader = new XmlTextReader(reader);

                listElementos.Items.Clear();

                while(xmlReader.Read()){

                    switch(xmlReader.NodeType){
                        case XmlNodeType.Element:
                            while(xmlReader.MoveToNextAttribute()){  // En mi caso los mostraba el un ListBox
                                if(xmlReader.Name.Equals("name")){ listElementos.Items.Add(xmlReader.Value); }
                            }
                            break;
                    }

                }

            } catch (WebException ex) {
                lblMensaje.Text = ex.Message;
            }

        }

        // Este es para poder el tamaño y los tipos de archivos que se encuentran zipeados 

private void verSubArchivos(String value)
        {
            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(servicesRoot  + accountID + "/" + value);
            req.Credentials = new NetworkCredential(accountID, accountKey);

            try
            {

                HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
                Stream strm = resp.GetResponseStream();
                StreamReader reader = new StreamReader(strm);

                XmlTextReader xmlReader = new XmlTextReader(reader);

                listViewDetalles.Items.Clear();

                while (xmlReader.Read())
                {

                    switch (xmlReader.NodeType)
                    {
                        case XmlNodeType.Element:

                            while (xmlReader.MoveToNextAttribute())
                            {
                                if (xmlReader.Name.Equals("name")) { item = listViewDetalles.Items.Add(xmlReader.Value); }
                                if (xmlReader.Name.Equals("size")) { item.SubItems.Add(xmlReader.Value); }
                                if (xmlReader.Name.Equals("mimeType")) { item.SubItems.Add(xmlReader.Value); }
// No se otra forma de leer los atributos de un XML asi que esta es mi forma si hay una mejor diganmela estamos apra aprender no :)
                            }
                            break;
                    }

                }                

            }
            catch (WebException ex)
            {
                MessageBox.Show(ex.Message);
            }

            this.Cursor = Cursors.Default;

        }

        private void eliminarArchivo(String value)
        {

            if (MessageBox.Show("Esta seguro de querer eliminar ?", "Alerta", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(servicesRoot + accountID + "/" + value);
            req.Credentials = new NetworkCredential(accountID, accountKey);

                req.Credentials = new NetworkCredential(user, pass);

                try
                {
                    req.Method = "DELETE";

                    HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
                    Stream strm = resp.GetResponseStream();
                    StreamReader rdr = new StreamReader(strm);
                    string xmlResponse = rdr.ReadToEnd();

                    if (resp.StatusCode == HttpStatusCode.NoContent)
                    {
                        lblMensaje.Text = "Archivo Eliminado !";
                    }
                    else
                    {
                        lblMensaje.Text = xmlResponse + " - " + returnStatusString(resp) ;
                    }

                }
                catch (WebException ex)
                {
                    MessageBox.Show(ex.Message);
                }

                this.Cursor = Cursors.Default;
            }
        }

 private void subirArchivo(String nombre, String ruta)
        {

            FileInfo info = new FileInfo(ruta);
            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(servicesRoot + accountID + "/" + nombre + "/" + info.Name);
            req.Credentials = new NetworkCredential(accountID, accountKey);

            string strFile = txtUrl.Text;
            req.Method = WebRequestMethods.Http.Put;
            req.ContentType = "application/zip";

            try
            {

                FileInfo fInfo = new FileInfo(strFile);
                long numBytes = fInfo.Length;

                FileStream fileStream = new FileStream(strFile, FileMode.Open, FileAccess.Read);
                BinaryReader br = new BinaryReader(fileStream);

                byte[] data = br.ReadBytes((int)numBytes);
                br.Close();

                req.ContentLength = data.Length;

                lblMensaje.Text = "Subiendo Archivo : " + fInfo.Name;

                using(Stream requestStream = req.GetRequestStream()){
                    requestStream.Write(data, 0, data.Length);
                }

                HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
                MessageBox.Show(resp.StatusCode.ToString());

            }
            catch (WebException ex)
            {
                lblMensaje.Text = ex.Message;
            }

        }

El codigo se puede mejorar y ahorrar lineas como el HttpWebRequest lo estoy usando varias veces claro podriamos crear una funcion que nos lo retorne ya autentificado y con su metodo usando las Enumeraciones . ahora podran administrar su archivos desde su escritorio aqui les dejo la referencia del API.

msdn API Silverlight

Enumeraciones
http://canyouhearthebits.wordpress.com/2008/08/25/enumeraciones-manipulacion-de-bits-flags/

31
Jul
08

Video Tutoriales … Variados

En el Blog de Michael’s encontre algunos video tutoriales variados como Silverlight 1 y AJAX como usar JSON con Silverlight utilizar el Expression Blend y otras cosas interesantes que les sera de ayuda.

Ir al Blog …

22
Jul
08

Tutoriales en PDF de Silverlight

Visitando el blog de Jesse Liberty me tope con este Post que fue posteado el mismo dia del Lanzamiento de esta Nueva Beta en Donde Deja estos Enlaces para descargar unos archivos en PDF acerca de Silverlight .. Estan en Ingles

Espero les sea de Ayuda :D

1 Creating Applications With Controls and Events

2 Binding Data In Silverlight

3 Filling a DataGrid using Sql, Linq and WCF

4 Instant Code Reuse: User Controls in Silverlight

5 Introducing Expression Blend For Silverlight Developers

16
Jul
08

Silverlight Tutoriales. Parte 8: Crear la versión de escritorio con WPF

Este es el último de los ocho tutoriales en el que estamos creando un cliente de Digg con la Beta 1 de Silverlight 2. La idea es que estos tutoriales se lean en orden, con el objetivo de explicar los fundamentos de la programación con Silverlight.

Pueden descargar el código completo del cliente Digg del ejemplo aquí

Crear una aplicación de escritorio con WPF

El objetivo con este último tutorial es un poco diferente del de los otros siete. No vamos a usar Silverlight en este post – sino que usaremos WPF y .NET 3.5. Cojeremos el código de la aplicación que estamos creando con Silverlight y lo reutilizaremos como una aplicación de escritorio.

Silverlight viene con un subconjunto compatible de la API del .NET Framework. Uno de los objetivos de esto es permitir a los desarrolladores aprender un mismo modelo de programación que les permita reusar código y contenido rico, tanto para la web como para aplicaciones escritorio.

Aquí tenéis los pasos que he hecho para convertir la aplicación Silverlight que hemos creado (que se ejecuta en un navegador) en una aplicación de escritorio Windows (que no se ejecuta en el navegador).

Paso 1: Crear una nueva aplicación WPF de escritorio

Empezamos creando una nueva aplicación WPF con VS 2008. La llamaremos “DiggDescktopSample”:

Esto creará un proyecto en VS con dos archivos – un App.xaml y un Window.xaml:

Paso 2: Copiar el código existente en la aplicación WPF

Copiaremos y pegaremos el código que ya tenemos en Silverlight en nuestro nuevo proyecto:

En la Beta1 esta parte de copiar y pegar es un paso manual – estamos viendo la posibilidad de tener una forma más automática de hacer esto.

Paso 3: Corregir un par de cositas

He tenido que hacer dos cambios para que nuestro código compile:

1) El esquema de Silverlight Beta1 xmlns: la url es diferente de la versión de WPF. He tenido que corregir esto en los archivos XAML que hemos copiado en el proyecto para que apunten al esquema de WPF. Esto es algo que estamos mejorando antes de publicarlo.

2) He tenido que cambiar el control <WaterMarkTextbox> a un <TextBox> y cambiar el control <HyperlinkButton> para que sea un <TextBlock>. Estos dos controles son nuevos en la Beta 1 de Silverlight y no están aún en WPF (los añadiremos en futuras versiones). No tengo que cambiar ningún código para que funcione con estos controles, ni siquiera la red, LINQ to XML, ni el código de enlace a la base de datos.

Una vez que hemos hecho estos cambios, el código se compila sin ningún problema.

Paso 4: Hosting de la aplicación en una ventana

Entonces abrí el archivo Windows1.xaml en el proyecto de escritorio (que es la ventana que se carga por defecto cuando arranca la aplicación).

Acutalizé el titulo de la ventana a “Digg Desktop Version” y aumenté el Width y el Height de la ventana.

Luego añadí nuestro user control Page.xaml del proyecto de Silverlight como el control raíz de la ventana. Esto hará que sea visible y que se cargue cuando se cargue la ventana. No tengo que cambiar ningún código de la clase Page ni renombrar nada. Como hereda de la clase UserControl puede hostearse dentro de cualquier ventana o control WPF.

Lo último que he tenido que cambiar una cosilla debido a que el servidor de la api de Digg detecta cuando un cliente no es un navegador y algunas veces le deniega el acceso (probablemente para evitar scripts automáticos accedan a su servicio). Esto lo resolví a través de una url de proxy (sin cambiar código, sólo un cambio de url).

Paso 5: Ejecutar la aplicación

Ya estamos listos para ejecutar la aplicación de Windows. Funciona todo exactamente igual que con la versión de silverlight:

 Y cuando seleccionamos un elemento de la lista, vemos los detalles:

Hay un par de diferencias cosméticas entre la versión del navegador y la de escritorio. Esto es porque WPF hereda todos los estilos por defecto (fuentes, colores, scroll bars, etc) basándose en el tema de escritorio del sistema operativo que está seleccionado, mientras que Silverlight tiene un tema por defecto que usamos en todos los sistemas operativos. Si queremos que las versiones de escritorio y la web sean el mismo podemos conseguirlo siendo explícitos en nuestros estilos y en los templates de los controles – de otra manera la versión de escritorio se adaptará al tema del usuario.

Resumen

Pronto tendremos algunas notas y sugerencias de buenas prácticas a la hora de compartir código entre aplicaciones Silverlight y WPF más adelante. Creo que habran encontrado las características necesarias para crear aplicaciones Silverlight y que es muy sencillo pasarlo a proyectos WPF. También estamos trabajando en que haya una mayor compatibilidad entre este tipo de aplicaciones para que permitir la reutilización de código entre soluciones, controles, contenido y código fácilmente.

Espero que sirva

Scott.

Artículo original.

16
Jul
08

Tutoriales Silverlight. Parte 7: Templates de User Controls para personalizar el Look & Feel

Pueden descargar el código completo del cliente Digg del ejemplo aquí

Cómo personalizar el Look & Feel de Controles

Una de las características más potentes del modelo de programación de WPF y Silverlight es la posibilidad de personalizar el look&feel de los controles que usamos. Esto permite que los desarrolladores y diseñadores se centren en lo que le corresponde a cada uno, permitiendo una flexibilidad increible para crear mejores experiencias de usuario.

En este tutorial veremos varias formas de personalizar los controles, y terminaremos mejorando la interfaz de nuestra aplicación con estas técnicas.

Personalizar el contenido de los controles.

En la primera parte de esta serie de tutoriales añadimos un boton a la página y vimos cómo poner la cadena “Push Me!” dentro. Luego escribimos el método Click que se ejecutaría:

Esto hace que el boton se renderize de la siguiente manera en el navegador:

Una de las cosas que puede sorprenderos es que el contenido del boton no tiene porqué ser sólo un string. Podemos hacer que la propiedad “Content” tenga cualqueir secuencia de controles que queramos.

Por ejemplo, podemos embeber un StackPanel con un <Image> y un <TextBlock>:

Esto hará que la apariencia del botón en ejecución sea la siguiente. Fijense que sigue teniendo el mismo comportamiento:

Podemos usa controles Shape (como una Ellipse) para crear gráficos vectoriales dentro del control:

Fijáos cómo estamos rellenando el control Ellpise con un RadialGraidentBrush para añadir efectos de luz:

Podríamos volvernos locos y añadir controles interactivos como un calendario dentro del botón:

El calendario es totalmente interactivo – los usuarios podrán ir hacia delante y hacia atrás en los meses, seleccionar una fecha, y pulsarlo haciendo que se lance el evento clic:(Nota: no estoy seguro de que esto sea una grata experiencia de usuario – pero nos muestra la flexibilidad que podemos tener).

Esto que hemos visto no sólo funciona para el control Boton, sino que funciona con cualquier control que herede de la clase ContentControl.

Personalizando controles con Templates

El modelo de controles de Silverlight y WPF nos permite ir más allá aparte de personalizar el contenido interno de un control. También nos permite reemplazar el arbol de visualización de cualquiera que queramos – mientras mantengamos el comportamiento.

Por ejemplo, digamos que no queremos que nuestros botones tengan una forma de rectángulo, sino que queremos un boton redondo como el siguiente:

Podemos conseguirlo creando un estilo “Roundbutton” en el archivo App.xaml. En el que sobreescribimos la propiedad “Template” de los botones, dando un ControlTemplate que reemplace el rectángulo con una elpise y un TextBlock:

Ahora podemos hacer que un control <Button> use este template :

  • Añadir contenido a nuestros templates

Como se habran dado cuenta que en el template “RoundButton” el tamaño del boton, y el contenido están en el código (siempre dice “Push Me!”).

Lo bueno es que tanto WPF como Silvelright nos permiten personalizar esto también. Podemos lograr con la extensión {TemplateBinding ControlProperty} . Esto permite que nuestro template se adapte a las propiedades del control:

Fijense que en lugar de añadir un control <TextBlock> para mostrar el contenido, estamos usando el control <ContentPresenter>. Esto nos permitirá que el botón no solo muestre cadenas, sino cualquier contenido que podemos personalizar (como ya hicimos antes).

Podemos usar el estilo anterior en tres botones (cada uno con un contenidos y propiedades diferentes):

Se mostrará de la siguiente forma (y si – el calendario se escala y sigue dando soporte a la paginación y la selección de fechas):

Si queremos ir más allá podemos añadir animaciones al template (para administrar estados del boton como “hover”, “focus” y “pushed”). Esta capacidad nos permite crear interfaces de usuario y unos escenarios increibles que antes no eran posibles con HTML

Los desarrolladores pueden olvidarse de cómo “pintar” los controles en la interfaz de usuario. Pueden programar los eventos de los controles y manipularlos como siempre, y tendrán un diseñador que se encargue de personalizar el look&feel con estilos y templates.

Puliendo nuestra aplicación Digg

Ahora que hemos visto lo básico de cómo se trabaja con los templates, vamos a usarlos en un par de sitios para pulir la interfaz de nuestra aplicación de ejemplo.

Hasta ahora tenemos un lugar obvio en el que nuestra aplicación necesita un poco más de trabajo – El boton “close” del user control:

Es muy sencillo para nosotros (o para un diseñador que trabaje con nosotros) arreglarlo. Podemos añadir un ControlTemlate al estilo del botón en el app.xaml y añadir algunas formas vectoriales para hacerlo más atracivo (nota: un diseñador más competente que yo podría añadir animaciones a las formas vectoriales):

Cuando ejecutemos la aplicación otra vez, el botón se mostrará de la siguiente forma:

El segundo lugar en el que podemos aplicar esto es en el aspecto del ListBox. Si os fijáis bien, podemos ver que el ListBox en la Beta1 tiene un borde por defecto:

Podemos cambiarlo con un border algo más ancho personalizando el template del List Box. Aquí tenéis un estilo que hace esto:

Fijense cómo hemos eliminado todos los controles de borde del ListBox. Estamos usando un control <ScrollViewer> en Silverlight (que nos permite hacer scroll con cualquier contenido) y le estamos embebiendo un <ItemsPresenter> que renderizará los items del ListBox (usará  el <DataTemplate> que creamos en la Parte 4 del tutorial)

Así es como quedaría:

Lo increíble es que no hemos tenido que cambiar ni una sola línea de código de nuestra aplicación, ni modificiar el XAML de nuestros controles para hacer que esto funcione. Esta separación entre codigo/diseño permite a un buen programador y diseñador trabajar juntos en aplicaciones Silverlight y WPF. Expression Blend y toda la suite Expression Studio permiten sacarle el máximo partido a estas características.

Artículo Original.

16
Jul
08

Tutoriales Silverlight. Parte 6: User Controls para implementar escenarios Maestro Detalle

Pueden descargar el código completo del cliente Digg del ejemplo aquí

Comprendiendo los User Controls

Uno de los fines principales en el diseño de Silverlight y WPF es permitir a los desarrolladores encapsular la funcionalidad de la interfaz gráfica en user controls reutilizables. Podemos crear controles personalizados heredando de cualquier clase existente Control (tanto de la clase base Control como de TextBox, Button, etc). Otra forma es crear User Controls – que hacen más sencillo el uso del lenguaje XAML, y son más fáciles de implementar.

Para la aplicación que estamos desarrollando, queremos implementar un escenario Maestro/Detalle en el que la aplicación permita a los usuarios buscar, obtener una lista de historias relacionadas con la búsqueda, y permitirles seleccionar una para ver los detalles. Por ejemlpo, si seleccionamos una historia de la lista:

Veremos algunos detalles:

Vamos a implementar esto creando un user control “StoryDetailsView” que mostrará el contenido cuando se seleccione un elemento de nuestro ListBox.

Creación del user control StoryDetailsView

Empezamos haciendo clic derecho en el proyecto DiggSample y seleccionamos “Add New Item”. Esto nos mostrará una ventana de diálogo. Seleccionamos el template UserControl y le daremos el nombre “StoryDetailsView”

De esta forma hemos añadido un User Control con este nombre al proyecto DiggSample:

Crear un diálogo modal básico con un UserControl

Usaremos este control para mostrar en un diálogo los detalles del elemento seleccionado. Cuando se muestran esos detalles queremos que aparezca encima del contenido de la página, y queremos asegurarnos de que el usuario no puede hacer otras cosas en la página hasta que no cierre esos detalles.

Hay un par de formas de implementar este comportamiento. Para nuestro caso  abrimos el archivo StoryDetailsView.xaml y añadimos el siguiente contenido:

El control <Rectangle> está configurado para que ocupe todo el espacio en la pantalla. El color de fondo es un gris transparente (su opacidad es 7.65 como podéis ver). El control <Border> será pintado encima del control Rectángulo, y ocupará una parte de la pantalla. El color de fondo es azul y contiene un botón de cerrar.

Cuando es visible, el user control StoryDetailsview se mostrará así:

Implementaremos el código del evento “CloseBtn_Click” en el código trasero. Cuando se presione, este evento pondrá la Visibilidad del UserControl a “Collapsed” – lo que lo hará desaparecer de la pantalla y volveremos a ver el contenido de detrás:

Mostrando el control StoryDetailsView

Una forma sencilla de hacer aparecer el control StoryDetailsView sería añadirlo al final del archivo Page.xaml, y poner su visibilidad por defecto en Collapsed (lo que significa que no es visible cuando se carga por primera vez la aplicación):

Y ahora podemos trabajar con el evento “SelectionChanged” el control ListBox en el código trasero:

Cuando un usuario seleccione un elemento de la lista, podemos usar este evento parhacer que el user control ShowDetailsView se muestre:

Esto hará que se muestre el diálogo modal. Cuando se haga clic en el boton “Close” desaparacerá, volviendo a mostrar la lista de historias.

Pasando los datos de la historia al control StoryDetailsView

Por último queremos mostrar en el user control StoryDetailsView los detalles de la información que tiene la historia que hemos seleccionado en el ListBox.

En el evento “SelectionChanged” del list box podemos acceder al objeto DiggStory que hemos seleccionado  a través de la propoiedad “SelectedItem”.

La forma más sencilla para acceder a esos datos sería poner la propiedad “DataContext” del user control al objeto que se ha seleccionado antes de hacer que el control sea visible:

Ahora podemos escribir el el código necesario para mostrar esos datos en el user control. O usar expresiones de databinding.

Por ejemplo, podemos actualizar el xaml de StoryDetailsView para mostrar el título de la historia con la siguiente expresion:

Y ahora cuando se haga clic en una historia:

El evento de selección, pondrá el DataContext del user control al objeto DigStory seleccionado, y luego lomostrará:

Fijense que ahora aparece el título del elemento que hemos seleccionado.

Terminando el aspecto del user control

Ya hemos visto cómo hacer de manera simple un maestro/detalle. Para terminarlo añadiremos más controles al StoryDetailsView y más expresiones de databinding:

Podemos actualizar el user control StoryDetailsView para que sea igual que el anterior actualizando el control <Border> de la siguiente manera:

No hace falta cambiar el código después de esto. Ya que estamos usando las expresiones de databinding para obtener los valores del DataContext.

Artículo Original

16
Jul
08

Tutorial Silverlight. Parte 5: ListBox y DataBinding para listar datos.

Pueden descargar el código fuente completo de la aplicación que estamos haciendo aquí

Mostrar los resultados de Digg con un ListBox y DataBinding

Anteriormente hemos estado usando un control DataGrid para mostrar los resultados. Esto funciona genial cuando queremos mostrar contenido en formato de columna. Para nuestra aplicación Digg, queremos juguetear con la apariencia un poco más y no queremos que se vea como un data grid sino como una lista de resultados. Esto es muy fácil de hacer – además no tendremos que cambiar nada de la lógica de nuestra aplicación.

Empezamos cabiando el control DataGrid con un <ListBox>. Mantendremos el mismo nombre que antes “StoriesList”:

Si ejecutamos la aplicación y hacemos una búsqueda, el listbox se mostrará así:

Se estaran preguntando -¿porque en cada elemento hay un “DiggSample.DiggStory”?. Esto es debido a que estamos enlazando a objetos DiggStory a la lista (cuyo comportamiento por defecto es llamar al método ToString()). Si queremos mostrar la propiedad “Title” del objeto, tenemos que poner la propiedad “DisplayMemberPath” del ListBox así:

Ahora cuando ejectuemos y hagamos una búsqueda tendremos esto:

Si queremos mostrar más de un valor a la vez, tendremos que personalizar un poco más el layout de cada elemento. Podemos sobreescribir el control ItemTemplate del ListBox y poner un DataTemplate. En este DataTemplate personalizaremos cómo se va amostrar cada objeto DiggStory.

Por ejemplo, podemos mostrar los valores “Title” y “NumDiggs” con el siguiente DataTemplate:

Podemos enlazar cualquier propiedad publica de los objetos DiggStory. Fijense que estamos usando la sintaxis {Binding NombrePropiedad}.

De esta manera, el resultado es el siguiente:

Vamos a afinarlo un poco más y pongamos el DataTemplate siguiente. Usamos dos StackPanels – uno para organizar los elementos horizontalmente y otro para poner varios textblocks vertiales:

Y obtenemos el siguiente resultado:

cuando definimos las reglas de estilo en el archivo App.xaml (fijaos que estamos usando un LinearGradientBrush para obtener el gradiente amarillo en el DiggPanel):

Una cosa importante  sobre el ListBox – aunque hayamos personalizado el look & feel de los items, seguimos teniendo el soporte de cuando seleccionamos un elemento. Esto pasa tanto si usamos el ratón o el teclado para seleccionarlo:

El list box también soporta el redimensionado – y nos dará un auto scroll cuando sea necesario (Fijense como aparece la barra de scroll horizontal cuando la ventan se vuelve más pequeña):

Artículo original.

16
Jul
08

Tutorial Silverlight Parte 4: Uso de estilos para encapsular el Look & Feel

Puedes descargar el código fuente completo de la aplicación que estamos haciendo aquí.

Uso de estilos para encapsular el Look & Feel

WPF y Silverlight soportan un mecanismo de estilos que nos permite encapsular las propiedades de los controles como un recurso reutilizable. Podemos guardar las declaraciones de estos estilos en archivos separados de las páginas, y reutilizarlos en varios controles y páginas en la aplicación (así como reusarlos en varias aplicaciones). Conceptualmente es muy parecido a usar CSS con HTML.

Nota: Además de definir información básica (Colores, Fuentes, Tamaños, Márgenes, etc), los estilos en WPF y Silverlight pueden usarse para definir y reutilizar templates de controles – permitiendo así una mayor adaptación de la estructura de los controles (y permitiendo escenarios de personalización que no son posibles con CSS y HTML hoy en día). Veremos esto en la séptima parte de este tutorial.

Para nuestro ejemplo, definiremos nuestro estilo en el archivo App.xaml del proyecto. De esta forma podremos usarlo en toda la aplicación:

Empezaremos encapsulando el estilo para el control <Border> (y para el <TextBlock> que está contenido en el):

Crearemos dos elementos <Style> en el archivo App.xaml para encapsular el estilo del <Border> y del <TextBlock> de la siguiente manera:

Fijense como le estamos dando un identificador único “key” a cada elemento Style. Ahora podemos actualizar los controles <Border> y <TextBlock> para que hagan referencia a estos estilos. Usaremos la característica de XAML llamada “extensiones de marcado” (markup extensions). Son usadas cuando no hay valores literales que queramos poner (otro ejemplo en el que usaremos esto será en las expresiones de databinding):

Cuando actualizemos los otros controles del archivo Page.xaml tendremos un  archivo con el siguiente aspecto:

Encapsulando los estilos de esta menera permite a los desarrolladores centrarse más en el comportamiento de la aplicación y también nos permite reusar estos estilos a lo largo de las páginas y controles que usemos.

Nota: Hay que tener en cuenta que en esta Beta 1 el mensaje de error que sale cuando nos equivocamos al poner el nombre del estilo no es muy claro (lanza una excepción pero no dice qué es lo que está mal). Esto será mejorado en la Beta2. Mientras tanto, si ven un error mientras se carga el estilo asegurence de mirar bien el nombre de los estilos.

Artículo original.

16
Jul
08

Tutorial Silverlight Parte 3: Usar la red para obtener datos y rellenar un DataGrid

Usando Networking para obtener historias de Digg

Silverlight 2 tiene una API de networking integrada para permitir que los clientes Silverlight puedan llamar a servicios remotos con REST, SOAP/WS*, RSS, JSON y servicios web XML. También incluye una API para sockets (System.Net.Sockets) para poder comunicar con otros protocolos que no-HTTP (ideal para escenarios como servidores de chat, etc).

Cross Domain Network Access

Las aplicaciones Silverlight 2 siempre pueden llamar al servidor “origen” cuando hacen llamadas a través de la red (es decir, pueden llamar a urls del mismo dominio del que se descargó la aplicación). También se pueden hacer llamadas a traves de dominos (es decir, puden llamar a urls de distinto dominio del que fué descargada) cuando el servidor web tenga un archivo de políticas XML en donde se indica qué clientes pueden hacer esas llamadas.

Silverlight 2 definie un formato para estos archivos que permite a los administradores de los servidores tener un control total sobre lo que puede acceder un cliente. También es compatible con el formato de estos archivos de Flash – con lo que podemos usar cualquier end-point remoto con REST, SOAP/WS*, RSS, JSON o XML que esté disponible para clientes Flash.

Digg.com tiene un gran conjunto de APIs que publican sobre HTTP. Como tienen archivos de políticas para Flash, podemos usarlo en nuestra aplicación Silverlight (sin tener que hacer ningún tunel con nuestro servidor web para poder usar esas APIs).

Digg.com Topic Feed API

Queremos que nuestros usuarios puedan realizar una búsqueda (por ejemplo: “Programming”) y que Digg.com nos devuelva el resultado de la búsqueda:

Podemos usar la API para feeds de Digg.com para ello. Recive un tema como parámetro en la url (por ejemplo: GET /stories/topic/programming), y devuelve un XML con las historias de digg que coinciden con el tema. Aquí tienen un ejemplo de cómo es el XML que se devuelve.

Llamadas asíncronas a .Digg REST con System.Net.WebClient.

Cuando hacemos clic en el botón de búsqueda, capturaremos el evento “clic”, obtendremos la cadena con el tema a buscar del control WaterMarkTextBox, e iniciaremos una llamada a Digg para obtener el XML del que hablábamos anteriormente.

Silverlight incluye la clase WebClient en el namespace System.NET (también está en la versión completa del Framework). Con esta clase podemos descargar contenido asíncronamente de una URL. La ventaja de descargarnos el XML asíncronamente es que la interfaz de usuario no se bloqueará ni dejará de responder mientras esperamos al servidor remoto (consiguiendo de esta manera una experiencia de usuario fluida).

Todo lo que tenemos que hacer para hacer esto es subscribirnos al evento “DownloadStringCompleted” que se lanzará cuando se termine la descarga, y luego llamar al método WebClient.DownloadStringAsync(url) para comenzar la descarga:

Y con el código anterior ya podemos obtener asíncronamente un string con datos XML que contiene el resultado de la búsqueda.

LINQ to XML para parsear los resultados en clases.

Ahora que podemos obtener un xml con datos, el próximo paso es parsearlo y convertirlo en objetos “DiggStory” para que podamos manipularlos y enlazarlos con los controles.

Esto lo haremos definiendo la clase “DiggStory” con propiedades que se mapean con el contenido de Digg (aprovecharemos las “propiedades automáticas” de C# para conseguir esto):

Ahora podemos usar LINQ(que está incluido en Silverlight 2) y LINQ to XML (una librería extra que podemos añadir a nuestra aplicación) para parsear y filtrar el contenido del documento XML de Digg, y traducirlo en una secuencia de objetos “DiggStory” con el siguiente código:

Fijense que estamos usando un tipo fuertemente tipado con objetos DiggStory a partir del XML.

Mostrar los resultados en un DataGrid

Usaremos el nuevo control DataGrid de Silverlight para mostrar los resultados. Para ello tenemos que referenciar el assembly de controles de Silverlight, y remplazaremos el texto “Todo” de la página con la declaración del control DataGrid:

El DataGrid nos permite configurar las columnas y mostrar los tipos (para un control mayor). Además podemos poner la propiedad “AutoGenerateColumns” a true para que use la reflexión del datasource y cree automáticamente las columnas basándose en el esquema de los objetos.

Actualizamos el Code Behind para enlazar la propiedad ItemSource del datagrid con la secuencia de historias que obtenemos de Digg:

Y ahora cuando ejecutemos la aplicación y hagamos una búsqueda, veremos un listado con los datos que nos devuelve Digg:

El DataGrid de Silverlight soporta todas las características estándar que esperamos que un control de servidor tenga: edicion, selección, scroll, redimensionado, etc. También soporta el auto-flow layout, es decir, se puede expandir y contraer dinámicamente ajustándose al tamaño de su contenedor. También tiene un modelo de templates que nos permiten personalizar el visionado y la edición de datos. Veremos estas características con más detalles en otros post.

Articulo Original

10
Jul
08

Tutorial Silverlight Parte 2: Administración de Layout

Entendiendo la administración de Layout

Silverlight y WPF soportan un sistema de layout que permite a desarrolladores y diseñadores coordinar fácilmente cómo se posicionan los controles en la interfaz de usuario. Este sistema de layout soporta tanto un modelo de posición mixta, en el que los constroles se posicionan en unas coordenadas explícitas, y un modelo dinámico, en el que los controles se redimiensionan automáticamente a medida que lo hace el navegador.

Los desarrolladores que usen Silverlight y WPF usan layout panels para coordinar la posición y el redimensionado de controles que contienen. Los paneles integrados en Silverlight Beta 1 incluyen los tres más comunes de WPF:

  • Canvas
  • StackPanel
  • Grid

Canvas

El panel Canvas es muy básico que soporta la posición de los controles que contiene con coordenadas explicitas.

Los elementos se posicionan en el canvas con una característica de XAML llamada Propiedades Adjuntas(”Attached Properties”) – que nos permiten especificar la posición del control relativa al margen derecho, alto, derecho o bajo del contenedor Canvas. Esta característica es útil ya que permite que un panel padre extienda el conjunto de propiedades de un control que contenga. Canvas, por defecto tiene las propiedades adjuntas Top y Left para definir esto en los controles que contenga, sin tener que añadir ninguna propiedad a estos últimos, o modificar sus clases.

Podríamos añadir dos botones a un Canvas, y posicionarlos a 50 pixels del borde izquierdo, y a 50 y 150 pixels del borde superior (Canvas.Left y Canvas.Top son ejemplos de la sintaxis de las propiedades adjuntas):

Esto se renderiza de la siguiente manera:

El Canvas es muy útil en escenarios en el que los elementos de la interfaz de usuario no se mueven nunca, no tiende a ser muy flexible cuando necesitamos muchos controles que se redmiensionen o muevan. En estos casos terminamos por escribir código que haga que el Canvas se comporte como queremos (es muy duro).  Una mejor solución para estos escenarios dinámicos es usar otro panel pensado para ello – como son StackPanel y Grid.

StackPanel

Este control es un panel simple que soporta el posicionamiento de los controles que contenga en forma de fila o columna. Los StackPanels se usan cuando nos interesa organizar una parte de la interfaz de la página.

Por ejemplo, podemos usar un StackPanel para organizar verticalmente tres botones con XAML:

Y este es el resultado en tiempo de ejecución:

Podríamos haber puesto la propiedad “Orientation” para que el StackPanel sea horizontal y no vertical:

Obteniendo el siguiente aspecto:

Grid Panel

Este control es el panel más flexible, y soporta la agrupación de controles en varias filas y columnas. Conceptualmente es similar al elemento Table en HTML.

Sin embargo, no embebemos controles dentro de las columnas  y filas. Sino que definimos las columnas y filas con <Grid.RowDefinitions> y <Grid.ColumnDefinitions> justo despues del control <Grid>. Podemos usar las propiedades adjuntas en los controles contenidos en el grid, indicando que fila y columna deben rellenar.

Por ejemplo, declaremos un Grid con tres filas y tres columnas, y pongamos 4 botones:

El Grid posicionará los botones de la siguiente manera:

Además de soportar un tamaño absoluto(por ejemplo: Height=”60″) los controles RowDefintion y ColumnDefinition también soportan el modo automático (Height=”Auto”), que ajusta automáticamente el tamaño (también podemos especificar un tamaño máximo y mínimo – puede ser muy útil).

Estas RowDefinition y ColumnDefinitions tienen la propiedad “Porportional Sizing” – que hace que el tamaño de las filas y columnas se redimensionen proporcionalmente en relacion a las otras (por ejemplo: podemos hacer que la segunda fila crezca dos veces más que la primera).

veran que este Grid es muy flexible – y seguramente será el panel más comun que vayamos a usar.

Uso de paneles para agrupar la página de Digg

Recuerden que lo queremos es crear una página de ejemplo de Digg con el siguiente aspecto:

Para crear este aspecto emos añadido un Grid raíz con dos RowDefinitions. La primera será de 40 pixeles de alto y la segunda cojerá el resto del espacion (Height=”*”):

Nota: Fijense que he puesto la propiedad “ShowGridLines” a “true”. Esto nos permite visulaizar más fácilmente las filas y columnas cuando testeamos:

Ahora metemos un segundo Grid como hijo del primero en la primera fila, y lo usamos para agrupar la cabecera. creamos tres columnas en el- una para el tículo, otra para el texto de búsqueda y otro para el botón de búsqueda:

Con esto tenemos el layout básico de nuestra página de búsqueda de Digg:

Nota: Una alternativa a anidar Grids, es usar un Grid con 3 columnas y 2 filas, y usar las propiedades ColSpan/RowSpan del grid para unir varias columnas (igual a como se hace con tablas HTML). He usado dos Grids anidados ya que creo que es más fácil de seguir.

Ahora que tenemos el layout todo lo que necesitamos es añadir los controles que necesitamos.

Para la cabecera usaremos el control <Border> (Con un radio de 10 para que quede bien) y añadiremos texto para crear el título. Usamos el control <WatermarkedTextBox> en la segunda columna para el textbox de búsqueda. Y ponemos un <Button> en la tercera columna. Ponemos un bloque de texto en la segunda fila en la que vamos a mostrar los resultados.

Nota: En la siguiente captura estoy añidendo información de estilo (FontSize, Colores, Margenes, etc) directamente en los controles. En otros post veremos cómo usar Styles para extraer y encapsular estas opcines en un archivo a parte (como CSS) que podremos usar en toda la aplicación.

Ahora ejecutamos la aplicacion:

Redimensionado dinámico de la aplicación

En el XAML anterior es que el control de arriba está configurado para que tenga un ancho y algo fijo:

Cuando lo configuramos de esta manera, la aplicación Silverlight siempre tendrá ese tamaño. Si expandimos el navegador lo vemos:

En algunos escenarios esto puede ser válido, pero en neustro caso queremos que se redimensiones automáticamente con el navegador – como haría una página HTML.

Esto es muy sencillo de conseguir. Eliminamos estos atributos de nuestro control:

Nuestra aplicación Silverlight se expandirá (o encojerá) para llenar el contenedor HTML. Ya que el archivo SilverlightTestPage.html con el que estamos testeando el control Silverlight lo contiene dentro de un <div> con un width y height al 100%, ahora nuestra aplicación sera:

Fijense cómo el contenido de la cabecera se ajusta al ancho del navegador:

Cuando encojemos el navegador, el textbox y el boton de búsqueda tienen el mismo tamaño, ya que las columnas del grid que los contienen tienen un ancho fijo. El control <Border> que contiene el título se redimensiona porque la columna está configurada con Width=”*”.

No tenemos que escribir ninguna línea de código para conseguir este comportamiento – el grid contenedor y el sistema de layout se encargan de redmiensionar todo por nosotros.

Por : Scott Guthrie




Visitas

  • 24,703 hits

Autor

Suscribirse a RSS




Rentabiliza tu sitio!
Con mi Código de afiliado
logras beneficios para ambos! recibirán el 80% de revenue share (en lugar del 60%).

Afiliados

Publicidad

Enlaces Microsoft


BlogESfera Directorio de Blogs Hispanos - Agrega tu Blog