[Windows 8][Presentación] Desarrollando Apps para Windows 8

El año pasado (no hace mucho) tuve la oportunidad de participar en un evento con los MVPs de Colombia, en este evento di una pequeña charla (pequeña por tiempo) mostrando las facilidades que tenemos al desarrollar Apps para esta plataforma, por cosas de la vida 😛 ahora he tenido la posibilidad de dar esta misma charla en más de una conferencia y/o taller presencial de desarrollo de Apps para la tienda de Windows y claro con un poco más de tiempo.

¿Por qué ese título? porque es que es algo por lo que me gusta empezar, por “quitarle” el miedo al desarrollador de incursionar en esta nueva plataforma, en un nuevo modelo de desarrollo que está pegando con mucha fuerza, en un inicio muchas personas se muestran poco interesadas dado el supuesto nivel de complejidad que supone iniciar con una nueva plataforma y mientras vamos avanzando y aclarando términos el desarrollador se muestra más interesado, además de intentar mostrar todos los frentes posibles al público (Back-end devs, front-end devs, testers…) y si hay alguien quien no es desarrollador y quiere el dinero más que nada? También intento mostrar cómo es posible pagar las cervezas y la conexión a internet con este nuevo mercado de Apps.

Por petición del público (es enserio, me lo pidieron: P) he publicado en mi Slidesahre la presentación y en mi SkyDrive
subiré una de las demos que trabajé en esta presentación.

Este proyecto de demo quiero explicarlo un poco mejor en otro post para ser más detallado, pero es simplemente un servicio de Web Api que consumo desde una App haciendo uso de la Grid Template y modificando dos o tres cosas para tener listo un catálogo de “algo” en cuestión de minutos.

Hasta el próximo post.

[Windows 8][Presentación] Desarrollando Apps para Windows 8

[Windows 8][Opinión] Async Await en Convert Value

En el anterior post comentaba la aparente necesidad de tener una firma Task<object> para el método Convert… pero ahora que lo veo bien esta no es una responsabilidad del convertidor, construir una imagen, como lo propongo en ese artículo, implica tener que acceder a las bibliotecas de archivos, comprobaciones y demás, con todo eso sería una responsabilidad muy grande para mi convertidor. Y aún más el hecho de tener que usar la espera bloqueante que supone el Task.Result

return ImageConvert(value as string).Result;

Y se puede hasta pensar en cosas como realizar el llamado asíncrono y pensar luego en una sincronización… pero créeme, ya es demasiado!

                return Task.Factory.StartNew(() =>
                                          {
                                              var task = ImageConvert(value as string);
                                              return task.Result;
                                          });

… pero entonces, ¿dónde lo ubico? ¡Simple! En el ViewModel :D, bastara con agregar una propiedad, en mi caso una del tipo BitmapIamge llamada Image, y “acomodar” tus métodos para poder crear esta imagen. Luego simplemente en el Template preguntamos por esta propiedad y listo!

            <Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}">
                <Image Source="{Binding Image}"
                       Stretch="UniformToFill"
                       AutomationProperties.Name="{Binding Title}"/>
            </Border>

¿Qué ventajas encontré? Pues la que buscaba, poder usar la simplicidad de async/await y claro, corregir ese error de diseño que estaba planteando.

Si tienes alguna opinión no dudes en comentar 🙂

Hasta el próximo post.

[Windows 8][Opinión] Async Await en Convert Value

[Windows 8][How To] Cargar imagen a partir de su path

En la aplicación en la que estoy trabajando he tenido que implementar la carga de unas imágenes a partir de su path, estas imágenes están ubicadas en la biblioteca de imágenes y el path absoluto lo recupero desde la base de datos, el primer approach que realice era similar a este:

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            var bm = new BitmapImage(new Uri(@"D:\Users\nicolocodev\Pictures\csharp.png", UriKind.Absolute));
            image1.Source = bm;
        }

Luego consulté este artículo en la documentación de MSDN y me aclaro un poco más el panorama, el segundo approach quedo así:

	private async void OnLoaded(object sender, RoutedEventArgs e)
        {
            var storageFile = await StorageFile.GetFileFromPathAsync(@"D:\Users\nicolocodev\Pictures\csharp.png");
            IRandomAccessStream stream = await storageFile.OpenAsync(FileAccessMode.Read);
            var bm = new BitmapImage();
            bm.SetSource(stream);
            image1.Source = bm;
        }

Implementar en un GridView

Una vez lo quise implementar en un GridView, tuve que crear un convertidor, para que a partir dado un path obtuviera un BitmapImage, el convertidor quedo de la siguiente forma:

public class UriPhotoConverter : IValueConverter
    {      
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            return ImageConvert(value as string).Result;
        }

        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            throw new NotImplementedException();
        }

        private async Task<BitmapImage> ImageConvert(string urlimage)
        {
            StorageFile file = await StorageFile.GetFileFromPathAsync(urlimage);
            IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read);
            var b = new BitmapImage();
            b.SetSource(stream);
            return b;
        }
    }

Un tema que no me ha gustado, es que no se ofrece la posibilidad de implementar el método Convert() como Task<object> y no puedo usar el sistema de comunicación de async/await 😦 en su lugar debo acudir a la propiedad Result de mi método asíncrono.

Y en el ItemTemplate:

<Image Source="{Binding LocalUrl, Converter={StaticResource PhotoConverter}}" 
                       Stretch="UniformToFill" 
                       AutomationProperties.Name="{Binding Title}"/>

Con esto conseguí que funcionara.

Si conoces una forma más óptima de hacer esto no dudes en dejar tu comentario 🙂

Hasta el próximo post.

 

[Windows 8][How To] Cargar imagen a partir de su path

[Windows 8][HowTo] Agregar propiedades a un StorageFile

En el nuevo desarrollo que estoy haciendo y del que pronto podrás tener noticias en este sitio, me encontré con un escenario en el que debía agregar información completa de unas imágenes. El trabajo con archivos en las Windows Store Apps es bastante sencillo, pues sus APIs están muy bien construidas y con la facilidad de Async-Await, podemos trabajar con todos sus métodos asíncronos sin mayor problema.

Cuando recuperamos un archivo de una ubicación, en mi caso de un KnownFolders, recibiremos un StorageFile que como dice en la documentación Representa un archivo y así es, pero es indistinto el tipo de este y para trabajar con metadata como Title o Subject no expone propiedades para asignar valores.

var file = await KnownFolders.PicturesLibrary.GetFileAsync("DSCN2078.jpg");

Las propiedades a las que me refiero son más precisamente lo que aparece en el tab de Details:

La solución está dada por un método de esta clase, el SavePropertiesAsync()
en su segunda sobrecarga que espera un IEnumerable<KeyValuePar<string,object>>, y fue en este punto donde me perdí y donde está todo el asunto, pues no conocía las claves de aquellas propiedades.

Despues de mucho navegar entre la documentación en MSDN encontré este listado ya luego fue cuestión de revisar cual era el que necesitaba, para mi caso este fue el que soluciono mi problema, y mi código quedo de la forma:

            var file = await KnownFolders.PicturesLibrary.GetFileAsync("DSCN2078.jpg");
            var properties = new List<KeyValuePair<string, object>>();
            properties.Add(new KeyValuePair<string, object>("System.Title", "El titulo"));
            properties.Add(new KeyValuePair<string, object>("System.Comment", "Esta es la descripción de test"));
            file.Properties.SavePropertiesAsync(properties);

Y el resultado:

Bien, hasta aquí este pequeño post.

Espero les sea de utilidad.

Hasta el próximo post.

[Windows 8][HowTo] Agregar propiedades a un StorageFile