Windows 8:Cómo crear un app lector de blogs (RSS)-Parte 9

Construyendo la UI - Parte 2

En este artículo trabajaremos sobre algunos aspectos de la Interfaz de Usuario (UI) que es conveniente afinar. Será un artículo relativamente corto comparado con los anteriores artículos de la serie. La mayoría del trabajo lo haremos desde Blend aunque vale la pena recordar que de igual forma puedes hacerlo desde código si así lo deseas.

Los puntos a trabajar son:

  • Mejorar la apariencia de ListView
  • Mejorar la apariencia del ProgressRing
  • Mejorar la apariencia del WebView
  • Soporte para Snapped View
  • Imagen de Fondo

Mejorar la apariencia de ListView

Desde Visual Studio en el proyecto damos clic derecho adicionar nuevo Folder y creamos el Folder "Templates".

Seguidamente dando clic derecho a este folder seleccionamos adicionar nuevo ítem y creamos un nuevo archivo de recursos llamado Templates.xaml

Abriendo Appx.xaml en la sección de Merged Dictionaries adicionamos el que acabamos de crear justo debajo de StandardStyles.xaml , compilamos la solución.

Desde Blend abrimos View/RssMainView.xaml, la idea es cambiarle al ListView la forma en que se muestra cuando esta seleccionado,el color violeta que tiene por defecto, y establecerlo en uno más compatible con la UI actual.

Este cambio lo podemos hacer estableciendo desde 0 VisualState para cuando el ítem se encuentra seleccionado, pero requeriría mucho trabajo, mi recomendación es crear una copia del template usado por defecto y modificar solo las cosas necesarias. El template que viene por defecto para el contenedor de Ítems es bastante grande por lo cual conviene dejar estos templates en un archivo aparte, el que acabamos de crear en Visual Studio.

 

Para hacerlo basta con dar clic derecho sobre el ListView y seguir los siguientes pasos:

 

SNAG-0000

 

SNAG-0001

 

Seleccionando en el template cada uno de los ítem siguientes , asignar los valores correspondientes en las propiedades:

SNAG-0002   

Guardas, ejecutas y... tema resuelto.

SNAG-0003   

Mejorar la apariencia del ProgressRing

Modificamos la propiedad Foreground del ProgressRing para dejarla de Color Blanco, desde luego espero que lo hagas modificando el Style correspondiente, de acuerdo a lo enseñado en anteriores artículos.

Mejorar la apariencia del WebView

Todo marcha bien con excepción que el WebView parece sacado de otro planeta, y efectivamente así es, este una especie de wrapper para un componente de IE10 al cual se accede a través de una serie de operaciones COM, esto impactará nuestra solución más adelante en otro artículo, pero por ahora saquémosle provecho,

Dado que técnicamente este control tiene todo el poder de IE10 para parsear HTML5/CSS3/JS entonces podemos valernos de eso para hacerlo lucir mas de acuerdo a lo que es nuestra App, modificando o inyectando CSS , en incluso como veremos, ejecutando algunos scripts.

A inicio de este tutorial, allá en el artículo # 4 en la clase RSSHelper creamos un método llamado CreateContent el cual lucia así

 private static string CreateContent(string content)
{
    string htmlString = string.Empty;
    string preHtml = string.Empty;
    string proHtml = string.Empty;

    if (content != null)
    {
        //Hallar el primer tag html
        var htmlBeginIndex = content.IndexOf('<');
        //Recortar la cadena desde el primer tag html hallado
        if (htmlBeginIndex != -1)
            htmlString = content.Substring(htmlBeginIndex);
    }

    return preHtml + htmlString + proHtml;
}

Como les prometí preHtml y proHtml tendrían un uso futuro, dado que htmlString es el HTML que hemos extraído del feed, podemos adicionarle al inicio de ese HTML algunos estilos CSS (eso es redundante lo se) para modificar el color de fondo de la página mostrada por el WebView, así como el color y tipo de fuente. Para el caso especifico de mi blog adicionaré una referencia a un CSS y a un script para el formateo de código.

 string htmlString = string.Empty;
string preHtml = @"<!DOCTYPE html>
    <html>
    <head>
        <style>
            html, body {
                color:white;
                background-color:#1D1D1D;
                font-family:'Segoe UI';
            }
            mark{
                background-color:white; 
            }
        </style>
        <link href='https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/55/68/prism/7345.prism.css' original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-55-68-prism/7345.prism.css" rel='stylesheet' />
        <script src='https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-55-68-prism/7183.prism.js'></script>
    </head>
    <body>";

string proHtml = @"</body></html>";

Simplemente he adicionado al Html extraído del CSS el cuerpo completo de un archivo Html, solo y con el único fin de poder adicionar hojas de estilo y scripts.

Este es el resultado, cool no? Un cambio impresionante tan solo usando un poco de ingenio.

Sin embargo antes de que cargue el primer articulo el WebView se sigue viendo de color Blanco, desde el RssMainViewModel.cs añadiremos lógica para que el WebView solo sea visible cuando se haya realizado la primera navegación, para ello en el WebView ya no definimos la propiedad Visibility por lo cual la borramos quedando así, tener presente que de todas maneras en el estilo la tenemos definida como Colapsed.

 <WebView x:Name="wvBlogContent"
    Grid.Column="2" Grid.Row="1" 
    vm:RssMainViewModel.HtmlString="{Binding ElementName=lvwBlogPosts, Path=SelectedValue.Content}"
    Style="{StaticResource WebView-Style}"  />

En RssMainViewModel.cs modificamos el método HtmlStringChanged para que al navegar se asegure que el WebView queda visible:

 

 public static void HtmlStringChanged(DependencyObject sender, DependencyPropertyChangedEventArgs arg)
{
    var wb = sender as WebView;
    if (wb != null)
    { 
        wb.NavigateToString((string)arg.NewValue);
        wb.Visibility = Visibility.Visible;
    }
}

 

 

SNAG-0004   

Soporte para Snapped View

Ejecutamos la aplicación, ahora la enviamos a Snapped View agarrándola de la parte superior y enviándola a alguno de los dos extremos de la pantalla (izquierda o derecha).

      SNAG-0005  

Como se puede observar se excede el espacio disponible.

La Snapped View NO SE PUEDE desactivar, es decir nuestra aplicación no puede evitar que un usuario la ponga en esta modalidad, así que hay que soportar la SI o SI.

Para esto se pueden tomar dos alternativas, la rápida es simplemente hacer que en Snapped View se muestre una imagen relacionada con la App, la otra es mostrar contenidos relevantes para el usuario.

Para esta App optaremos por mostrar contenido relevante, este contenido es el mismo ListView que hemos manejado pero con algunas modificaciones para que utilice el espacio adecuadamente.

Desde Visual Studio abrimos View/RssMainView.xaml , al inicio donde agregamos los recursos copiamos el DataTemplate llamado Post-List-ItemTemplate y le ponemos como nombre Post-List-ItemTemplate-snapped .

Eliminamos el segundo TextBlock que contiene y tanto al Image como al TextBlock restante les ponemos el posfijo -snapped en el nombre del estilo quedando así:

 <DataTemplate x:Key="Post-List-ItemTemplate-snapped">
    <StackPanel Orientation="Horizontal">
        <Image ImageOpened="ViewModel.ImageOpenedHandler" 
                Style="{StaticResource Image-Post-List-snapped}"  
                Source="{Binding ImgUri}" />
        <StackPanel>
            <TextBlock TextWrapping="Wrap" 
                    Text="{Binding Title}" 
                    Style="{StaticResource Title-PostList-Style-snapped}"/>
        </StackPanel>
    </StackPanel>
</DataTemplate>

Como vemos estos estilos aún no están creados, así que vamos a App.xaml y creamos una copia de los siguientes estilos

  • Lista-Posts-Style
  • Image-Post-List
  • Title-PostList-Style

A cada uno de ellos les colocamos como posfijo -snapped y los modificamos para que queden de la siguiente manera:

 

 <Style x:Key="Lista-Posts-Style-snapped" TargetType="ListView">
    <Setter Property="Margin" Value="10,0"/>
    <Setter Property="Width" Value="300"/>
    <Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
<Style x:Key="Image-Post-List-snapped" TargetType="Image" >
    <Setter Property="Margin" Value="5"/>
    <Setter Property="Width" Value="60"/>
    <Setter Property="Height" Value="60"/>
</Style>
<Style x:Key="Title-PostList-Style-snapped" TargetType="TextBlock">
    <Setter Property="Width" Value="185"/>
    <Setter Property="Height" Value="Auto"/>
    <Setter Property="Margin" Value="0,5,5,5"/>
    <Setter Property="FontSize" Value="15"/>
    <Setter Property="TextTrimming" Value="WordEllipsis"/>
</Style>

Regresando a View/RssMainView.xaml justo al final antes de la etiqueta de cierre </Grid> adicionamos el siguiente código que nos permitirá reaccionar antes los cambios de estado visual (Visual State) de la aplicación:

 <VisualStateManager.VisualStateGroups>
    <VisualStateGroup x:Name="ApplicationViewStates">
        <VisualState x:Name="FullScreenLandscape"/>
        <VisualState x:Name="Filled"/>
        <VisualState x:Name="FullScreenPortrait"/>
        <VisualState x:Name="Snapped"/>
    </VisualStateGroup>
</VisualStateManager.VisualStateGroups>

Abriendo la etiqueta con  x:Name="Snapped" adicionamos el código necesario para asignar la propiedad Style y la propiedad ItemTemplate del ListView , esto ocasionara que cuando la vista cambie a Snapped estas propiedades cambien el valor por el que hemos indicado. Lo que hacemos es asignar el estilo y template que son los recursos estáticos que hemos definido en los recursos de la página y dentro de App.xaml.

 <VisualState x:Name="Snapped">
    <Storyboard>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Style" Storyboard.TargetName="lvwBlogPosts">
            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource Lista-Posts-Style-snapped}"/>
        </ObjectAnimationUsingKeyFrames>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="ItemTemplate" Storyboard.TargetName="lvwBlogPosts">
            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource Post-List-ItemTemplate-snapped}"/>
        </ObjectAnimationUsingKeyFrames>
    </Storyboard>
</VisualState>

Otra cosa a cambiar es el tamaño y disposición del titulo de la página, en Appx.xaml creamos una estillo llamado Title-Main-Style-snapped para usarlo con el TextBlock, este estilo lo basamos en Title-Main-Style y le agregamos las propiedades que se ven a continuación:

 <Style x:Key="Title-Main-Style-snapped" TargetType="TextBlock" BasedOn="{StaticResource Title-Main-Style}">
    <Setter Property="FontSize" Value="35"/>
    <Setter Property="Width" Value="220"/>
    <Setter Property="Margin" Value="5" />
    <Setter Property="HorizontalAlignment" Value="Left"/>
</Style>

De regreso a View/RssMainView.xaml agregamos esta animación al Visual State del Snapped View

 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Style" Storyboard.TargetName="pageTitle">
    <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource Title-Main-Style-snapped}"/>
</ObjectAnimationUsingKeyFrames>

Y este es el resultado

SNAG-0007   

Imagen de Fondo

Para terminar, este importante detalle. Colocar la imagen es algo sencillo, es tarea de cada uno de ustedes, la parte importante es que en este momento el

ListView no es fácil de leer porque la imagen de fondo, por su colorido, ocasiona ese efecto.

SNAG-0004

 

Simplemente vamos a Appx.xaml y en los estilos

  • Lista-Posts-Style
  • Lista-Posts-Style-snapped

Agregamos el atributo Background asignandole como color #DD1C1C1C con lo cual el resultado final es:

SNAG-0003

 

En el próximo artículo veremos el final de esta serie, adicionando dos temas muy importantes para mejorar la experiencia de usuario.

  • Detección de conexión a internet
  • Adición de la política de privacidad

Índice General

Para cumplir con el alcance establecido he decidido fraccionar el proyecto en las siguientes partes:

 

  1. Windows 8:Cómo crear un app lector de blogs (RSS)-Parte 1
    • Introducción al tutorial  
    • Let's begin
    • Indice General
  2. Windows 8:Cómo crear un app lector de blogs (RSS)-Parte 2
    • Preparando la solución
  3. Windows 8:Cómo crear un app lector de blogs (RSS)-Parte 3
    • Modelo de Datos
  4. Windows 8:Cómo crear un app lector de blogs (RSS)-Parte 4
    • Consumiendo el RSS por medio de SyndicationClient
    • CreateContent
    • CreateSummary
    • Find1stImageFromHtml
  5. Windows 8:Cómo crear un app lector de blogs (RSS)-Parte 5
    • Inicializando la Aplicación e implementado el View-Model
    • Cómo y desde donde llamar a Initialize
    • Asociando el DataContext del View
  6. Windows 8:Cómo crear un app lector de blogs (RSS)-Parte 6
    • Construyendo la UI - Parte 1
    • Esquema principal de la App
    • Creando elementos básicos
    • El titulo
    • Aplicar propiedades utilizando estilos
    • El icono
    • El artículo actual
    • La Lista de Artículos
  7. Windows 8:Cómo crear un app lector de blogs (RSS)-Parte 7
    • Vinculando la View con el ViewModel
    • El artículo actual
  8. Windows 8:Cómo crear un app lector de blogs (RSS)-Parte 8
    • Mejorando la experiencia de usuario - Parte 1
    • Hacer que aparezca un articulo seleccionado por defecto
    • Disminuir el tamaño de los títulos del ListView
    • Disminuir el ancho del ListView
    • Evitar que los resúmenes de los artículos en el ListView crezcan de manera descontrolada
    • Colocar una imagen dummy en el Listview cuando no existan imágenes en el artículo
    • Colocar la imagen adecuada cuando la única imagen del RSS es el aggbug
    • Colocar una imagen dummy en el Listview cuando la imagen hallada en el artículo sea demasiado pequeña
    • Mientras cargan los datos del feed da la impresión de que la App no esta haciendo nada
    • Conclusión
  9. Windows 8:Cómo crear un app lector de blogs (RSS)-Parte 9
    • Mejorar la apariencia de ListView
    • Mejorar la apariencia del ProgressRing
    • Mejorar la apariencia del WebView
    • Soporte para Snapped View
    • Imagen de Fondo
  10. Windows 8:Cómo crear un app lector de blogs (RSS)-Parte 10
    • Mejorando la experiencia de usuario - Parte 2
    • Detección de conexión a internet
    • Adición de la política de privacidad
    • Tareas adicionales
    • FIN DEL TUTORIAL