> For the complete documentation index, see [llms.txt](https://elguerre.gitbook.io/de0an/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://elguerre.gitbook.io/de0an/capitulo-2-antes-de-comenzar.-el-terreno-de-juego/interfaz-de-usuario.md).

# Interfaz de usuario

Ahora que ya conocemos en términos generales cómo comenzar a desarrollar nuestra aplicación, veremos cuál puede ser el aspecto de la misma, cómo será la navegación entre ventanas o páginas, tamaños de controles UI y fuentes, etc.

Haremos un repaso general por los componentes vitales para poder entenderlos, pero no olvidemos que iremos profundizando en ellos durante el proceso de diseño y desarrollo de nuestra aplicación en capítulos sucesivos.

## Splash screen

Pantalla de bienvenida o pantalla de inicio que permanece visible unos segundos al iniciar la aplicación permitiendo introducir al usuario a la misma.

Consiste en una imagen estática con extensión “.jpeg”, “.jpg” o “.png”, que se identifica con el nombre *SplashScreen,* de entre 1 y 256 caracteres de longitud, que situaremos en la carpeta “Assets” del proyecto. La siguiente tabla muestra los tamaños que ésta puede tomar, así como los diferentes escalados para poder adaptarla adecuadamente a las distintas resoluciones y tamaños de pantalla de las diferentes familias de dispositivos.

**Tabla 07.- Escalados y tamaños de imágenes para el SplashScreen**

| Escala | Tamaño (Pixeles) |
| ------ | ---------------- |
| 100    | 620x300          |
| 125    | 775x375          |
| 150    | 930x450          |
| 200    | 1240x600         |
| 400    | 2480x1200        |

Windows puede escalar automáticamente una imagen. De esta forma evitamos la necesidad de varias imágenes. Si esta es nuestra opción, utilizaremos siempre la de mayor escalado, es decir, la de 400. Sin embargo, se recomienda crear una imagen para cada resolución, así, Windows utilizará automáticamente la más adecuada dependiendo del dispositivo en el que se ejecute.

La siguiente nomenclatura para el nombre de las imágenes crea este automatismo:

* *\<SplashScreen>.scale-100.\<png | jpg | jpeg>*
* *\<SplashScreen>.scale-125.\<png | jpg | jpeg>*
* *\<SplashScreen>.scale-150.\<png | jpg | jpeg>*
* *\<SplashScreen>.scale-200.\<png | jpg | jpeg>*
* *\<SplashScreen>.scale-400.\<png | jpg | jpeg>*

También podemos crear una página “.XAML” dinámica, con información de inicio o de espera para indicar la ocurrencia de algo. ¡Así, el usuario percibirá un inicio pesado o costoso como algo mucho más liviano! En estos casos, estas pantallas no deberán estar incluidas en la pila de retroceso (o *back stack*), por lo que deberán ser omitidas si el usuario pulsa el botón Atrás (*Back*). Denominaremos a esta página *Splash.xaml* o *SplashPage.xaml*.

## Pantalla de bloqueo

La pantalla de bloqueo, o *Lock Screen*, es la pantalla que aparece cuando el dispositivo está bloqueado.

Llamadas perdidas, próximas citas, mensajes nuevos, correos no leídos; son muchas las cosas que podemos comprobar en el dispositivo cuando tenemos un minuto libre. Si bien, algunas veces solo disponemos de unos pocos segundos. Es en estos casos donde la pantalla de bloqueo adquiere mayor importancia. Gracias a ella, con tan solo una mirada podemos estar al tanto de todo lo que ocurre en nuestro día a día.

Existen tres formas de interactuar con la pantalla de bloqueo:

* BadgeLogo (insignia o distintivo). Es el icono de la aplicación junto a un contador de notificaciones. Puede ser simplemente un número o bien, un pictograma para comunicar el estado. Debe contener píxeles blancos y cierto nivel de transparencia. Si se implementa, también se mostrará un contador junto al icono.

**Tabla 08.- Estados del BadgeLogo para el tipo Glyphs (insignia)**

| Estado   | Insignia/distintivo                                                                                                                                                                                  |
| -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Ninguno  | No muestra la insignia (*o badge*)                                                                                                                                                                   |
| Alerta   | ![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-c5f9721c74f4b20c9c7a46bb2c3f47c9dd53f50d%2Fimage7.png?alt=media) |
| Atención | ![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-7caaf0d38082b29a1926498a6afd3dd34a704c0e%2Fimage8.png?alt=media) |

* Notificaciones. Texto enviado por la aplicación para detallar el estado de la aplicación. Se sitúa junto al *BadgeLogo*, pero no sólo.

Si el tipo de notificación es “Badge and Tile Text”, entonces el Tile ancho (Wide) pasará a ser requerido ya que sólo ésta plantilla proporciona la información correcta a mostrar con el texto de la notificación.

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-416b391d026c9ea663e4a27dcf03786b67df4f65%2Fimage9.png?alt=media)

**Figura 07.- Selección del tipo de notificación para la pantalla de bloqueo**

* Imagen de fondo (o *LockScreen Background*). Es una imagen estática que puede cambiar el usuario por configuración.

{% hint style="info" %}
**Nota**: La información de personalización de la pantalla de bloqueo no es más que el *Tile* principal de la aplicación, que siempre existe, aunque no lo hayamos anclado.
{% endhint %}

La siguiente imagen muestra la configuración de la pantalla de bloqueo a modo de ejemplo en un teléfono.

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-1436dc99d089a6cbf914d87cb2a150fe16a68b06%2Fimage10.png?alt=media)

**Figura 08.- Configuración de la pantalla de bloqueo en un teléfono**

## Indicadores visuales

Windows utiliza tres tipos diferentes de indicadores para mostrar el progreso de una tarea, desplazamiento de vistas, intensidad de señal, duración de la batería y otra información adicional.

* **Indicador de progreso (o&#x20;*****Progress Indicator*****):** Muestra la actividad de las aplicaciones relacionada con una actividad en sí o una serie de eventos. Este indicador puede ser *determinista* si tiene un inicio y un fin o, *indeterminista*, si continua hasta que la tarea haya terminado. En Windows Mobile, se trata de un control integrado en la barra de estado.
* **Indicador de desplazamiento (o&#x20;*****Scroll Indicator*****):** Se produce cuando el contenido en la pantalla supera los límites de la página visible. Cuando el usuario se desplaza, los indicadores de desplazamiento aparecen visibles en el lado derecho para el desplazamiento vertical y a lo largo de la parte inferior para desplazarse horizontalmente. Estas barras de desplazamiento indican que el contenido es más largo o más ancho que la página, y representan la posición actual en la página. Tras un segundo los indicadores desaparecen.
* **Visor de desplazamiento (o&#x20;*****Scroll Viewer*****):** Permite al usuario navegar a contenido que no está directamente visible en el marco de la aplicación, tales como una larga sección de texto o una imagen.

## Orientación de la pantalla

Windows 10 es compatible con las siguientes orientaciones de pantalla:

* *Landscape* u, horizontal.
* *Portrait* o, vertical.
* *Landscape flipped* o, horizontal invertido.
* *Portrait flipped* u, vertical invertido.

Por defecto, la orientación puede ser cualquiera de ellas indistintamente, así que, si únicamente se quiere permitir una o varias de ellas, tendremos que indicarlo explícitamente en el manifiesto de la aplicación. Por otro lado, y para que los controles se posicionen correctamente según cada orientación existen diferentes técnicas:

* *Stack Panel*. Organiza sus elementos en una sola línea que puede ser horizontal o vertical.
* *Scrolling*. Utiliza un control *StackPanel* dentro del cual se coloca otro control *ScrollViewer*. *StackPanel* permite ordenar los elementos hijos, uno tras otro, mientras que *ScrollViewer* desplaza a través del *StackPanel* los elementos de interfaz de usuario si no caben en la pantalla cuando se cambia la orientación de vertical a horizontal.
* *Grid layout*. Requiere añadir código al evento *ArrangeOverride* de la página para cambiar la posición de los elementos en el *Grid*.

```
<Grid>
  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="*" />
  </Grid.RowDefinitions>
  <ctrls:PageHeader Content="Settings Page"/>
  <Pivot Grid.Row="1" >
    <PivotItem Header="About">
      <TextBlock Text="TextBlock About" />
    </PivotItem>
    <PivotItem Header="Licenses">
      <TextBlock Text="TextBlock Licenses" />
    </PivotItem>
  </Pivot>
</Grid>
```

Aunque el código XML anterior recolocaría los controles independientemente de su orientación, también podemos hacerlo mediante código. Por ejemplo, para recolocar una barra de comandos (o *CommandBar*) suponiendo que la celda de la cuadrícula (0, 0) permanece fija con un contenido cualquiera, tendríamos el código que ilustra la siguiente figura:

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-4d2047cc30de71669ac26faa9640f8141149929d%2Fimage11.png?alt=media)

**Figura 09.- Ejemplo de posicionamiento mediante programación**

* *Relative panel*. Permite el posicionamiento de los controles hijos manteniendo una relación de unos con otros o bien en relación con el panel/grid padre que lo contiene.

```
<RelativePanel>
  <ctrls:PageHeader x:Name="pageHeader" Content="Settings Page"
    RelativePanel.AlignLeftWithPanel="true"
    RelativePanel.AlignRightWithPanel="True"
    RelativePanel.AlignTopWithPanel="True" />
  <Pivot RelativePanel.Below="pageHeader"
    RelativePanel.AlignLeftWithPanel="true"
    RelativePanel.AlignRightWithPanel="True"
    RelativePanel.AlignBottomWithPanel="True" >
    <PivotItem Header="About">
      <TextBlock Text="TextBlock About" />
    </PivotItem>
    <PivotItem Header="Licenses">
      <TextBlock Text="TextBlock Licenses" />
    </PivotItem>
  </Pivot>
</RelativePanel>
```

Al igual que con el control Grid, también podemos realizar cambios de posicionamiento mediante código. Veremos más adelante una forma mucho más elegante y recomendada mediante el uso del control ***VisualStateManager*** y disparadores adaptativos (o *Adaptive Triggers)*.

## Barra de estado

La barra de estado (o *Application Bar*), es una barra indicadora utilizada en Windows Mobile. Muestra información sobre el estado del sistema de manera sencilla y limpia en una parte reservada del área de trabajo de la aplicación.

En la siguiente figura se observa una representación de la barra de estado con todos sus indicadores o iconos informativos.

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-3b962da586023338acee470844f98fb7c57b886b%2Fimage12.png?alt=media)

**Figura 10.- Barra de estado con todos sus indicadores**

El significado de cada uno de estos iconos se describe a continuación en la siguiente tabla:

**Tabla 09.- Significado de cada uno de los iconos de la barra de estado**

| Icono                                                                                                                                                                                                 | Significado                         |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- |
| ![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-6f373e49ad21989e454375676435e9b2a3b8d718%2Fimage13.png?alt=media) | Intensidad de cobertura             |
| ![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-d1a102562be7e272362d2a13e61e388dd8cbad03%2Fimage14.png?alt=media) | Conexión de datos                   |
| ![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-6f91e4cc3d60dd7af33a8007b82d0549bb2fa8b9%2Fimage15.png?alt=media) | Desvío de llamadas                  |
| ![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-e8706c13994090d2017dd4ac49001ecd624704bc%2Fimage16.png?alt=media) | Roaming                             |
| ![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-7a1de0d88440460b034df1d65f2ab1d2c01a87af%2Fimage17.png?alt=media) | Conexión Wifi                       |
| ![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-b51c8a2c39420f49670ca68d203efcd09cca09b5%2Fimage18.png?alt=media) | Dispositivo Bluetooth               |
| ![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-6a47062564ca59d5e8a3a7cad8e0e5306828731f%2Fimage19.png?alt=media) | Perfil del teléfono. Modo de sonido |
| ![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-844e078f5dc1f5ed605a195ed3d8fad02d419faa%2Fimage20.png?alt=media) | Teclado y ubicación.                |
| ![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-474c6adb80e6e6406bb1ef77b4f3088b6b787597%2Fimage21.png?alt=media) | Nivel de carga de la batería        |
| ![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-eed4300cd20a575e254b01d75a24009a7e6f635d%2Fimage22.png?alt=media) | Reloj del sistema                   |

Esta barra se actualiza automáticamente para proporcionar diferentes notificaciones y mantiene al usuario informado de cualquier situación a nivel de sistema. No puede ser modificada al tratarse de un control reservado del sistema, pero permite cierta interacción con la misma:

* Cambiar la visibilidad.
* Cambiar el color.
* Cambiar la opacidad.
* Utilizarla como indicador de progreso.

El siguiente código C# muestra cómo realizar estas interacciones en Windows Mobile.

```
if (ApiInformation.IsTypePresent("Windows.UI.ViewManagement.StatusBar"))
{
  var statusBar = Windows.UI.ViewManagement.StatusBar.GetForCurrentView();
  // Cambiar el color
  statusBar.BackgroundColor = Colors.Green;
  // Cambiar la opacidad
  statusBar.BackgroundOpacity = 0.5; /* [0-1] */
  // Mostrar la barra de estado
  await statusBar.ShowAsync();
  // Establecer el indicador de progreso junto a un mensaje de texto.
  statusBar.ProgressIndicator.Text="Cargando...";
  // Establecer el indicador de progreso a un valor de progreso
  statusBar.ProgressIndicator.ProgressValue=0.5; /* [0 – 1] */
  //Mostrar el indicador de progreso
  await statusBar.ProgressIndicator.ShowAsync();
}
```

Las siguientes figuras muestran la barra y menú de aplicación como resultado del código anterior:

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-51bf678c1b259ea3701aa9c80f33dce31e9c1786%2Fimage23.png?alt=media)

**Figura 11.- Barra de estado**

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-5a387714e28620743373687d5b0c156066174cd7%2Fimage24.png?alt=media)

**Figura 12.- Barra de estado mostrando indicador de progreso**

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-f5986a20414cf6dd2d53900a0e38072a655f21ed%2Fimage25.png?alt=media)

**Figura 13.- Barra de estado mostrando indicado y mensaje de progreso**

## Barra y menú de aplicación

La barra de aplicación, o barra de comandos (o *CommandBar*), posibilita el acceso rápido a las tareas más comunes dentro de la aplicación. Cada uno de estos accesos viene indicado por un botón, de tipo:

* AppBarButton\*.\* Botón con icono y/o etiqueta.
* AppBarToggleButton. Botón con icono y/o etiqueta, pero con la particularidad de que mantiene el estado del botón de forma similar a un control *Checkbox*.

A su vez, estos botones pueden estar agrupados como primarios, *CommandBar.PrimaryCommands*, o como secundarios, *CommandBar.SecondaryCommands*, o de tipo menú, que, aunque declaren un icono, no lo muestran.

Por ejemplo, a continuación, podemos ver una barra de comandos y, seguidamente el código XAML que la representa:

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-5adc4243925fb0d3a81512b7ae05fc6f0472785c%2Fimage26.png?alt=media)

**Figura 14.- Barra de comandos de ejemplo**

```
<CommandBar>
  <CommandBar.PrimaryCommands>
    <AppBarButton x:Uid="AppBarButtonSave"
                  Label="save"
                  Command="{Binding SaveCommand}"
                  Icon="Save" />
    <AppBarButton x:Uid="AppBarButtonDelete"
                  Label="remove"
                  Command="{Binding DeleteCommand}"
                  IsEnabled="{Binding IsEnabledToDelete, Mode=TwoWay}"
                  Icon="Delete" />
    <AppBarButton x:Uid="AppBarButtonBrowseImage"
                  Label="image"
                  Command="{Binding AddImageCommand}"
                  Icon="BrowsePhotos" />
  </CommandBar.PrimaryCommands>
  <CommandBar.SecondaryCommands>
    <AppBarButton x:Uid="AppBarButtonRemoveImage"
                  Label="remove image"
                  Command="{ Binding RemoveImageCommand }" />
  </CommandBar.SecondaryCommands>
</CommandBar>
```

Otro ejemplo de una barra y menú de aplicación podemos verlo al crear una cita en el calendario de Windows Mobile, donde se incluyen ciertas acciones o comandos que facilitan al usuario la interacción con dicha cita.

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-e2e706aebc35836a0d5b7777fb1bec5240e02baa%2Fimage27.png?alt=media)

**Figura 15.- Barra de comandos al crear una cita**

La barra de comandos presenta una propiedad *IsOpen* con el fin de mostrarla u ocultarla y, la propiedad *ClosedDisplayMode* que puede tomar los valores siguientes:

* Mínimo. Muestra el área “Más” mediante el símbolo \[…] indicando así al usuario la existencia de un menú desplegable de comandos que se mostrarán una vez que el usuario pulse sobre el mismo.
* Compacto. Además de mostrar el área “Más”, mantiene visibles los comandos más importantes y sus iconos. El resto de comando permanecen ocultos hasta que el usuario pulse sobre re el símbolo “\[…]”.
* Oculto. Oculta completamente la barra de menú.

{% hint style="info" %}
**Nota**: Se recomienda colocar la barra de menú en la parte inferior en dispositivos móviles siempre y cuando se utilice una única barra. En aquellos casos en los que la aplicación muestre pestañas en la parte inferior se evitará sobrecargar demasiado la parte inferior colocando la barra en la parte superior de la pantalla.

En otros dispositivos con pantallas más grandes en las que sólo se utilice una barra de menús, está se colocará en la parte superior.
{% endhint %}

## Controles

Para diseñar la interfaz de usuario en Windows 10 existen una serie de controles que van a permitir ir ubicando y posicionando a su vez otros controles e ir dando la forma y aspecto más conveniente a la aplicación. Muchos de ellos ya son conocidos por su equivalencia en otras tecnologías o plataformas o incluso en versiones anteriores de Windows y Windows Phone. La siguiente figura ilustra la caja de herramientas de Visual Studio donde podemos ver todos ellos.

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-88a6ec278404d85a47366cd2e4cc2ad93d3250f2%2Fimage28.png?alt=media)

**Figura 16.- Controles XAML de Windows**

En los siguientes apartados iremos profundizando en aquellos controles más comunes y significativos. Algunos de ellos como base para otros controles y, a su vez, necesarios para crear la interfaz de usuario y el mapa de navegación de la aplicación.

### Controles de navegación

Las aplicaciones UWP, se basan en un modelo de página en la que los usuarios se desplazan hacia adelante a través de diferentes páginas de contenido. A medida que se navega entre páginas se realiza la carga en el marco de la página principal. Concretamente este modelo se basa en un marco, *Frame*, que contiene controles página, *Page*, que contienen controles de diseño, y estos, a su vez, otros controles adicionales.

En la siguiente imagen se muestra este modelo de página para Windows Mobile:

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-2064b7ef90fa390aff26b68ba61e4529fa8ab076%2Fimage29.png?alt=media)

**Figura 17.- Marco y modelo de página**

### Frame

El control Marco (o *Frame)* contiene cada una de las páginas que componen la aplicación permitiendo la navegación entre ellas manteniendo un histórico de las mismas a través del método *Navigate*. Los métodos *GoBack* y *GoForward*, permiten la navegación hacia atrás o hacia adelante hacia el elemento más reciente en el histórico de navegación.

```csharp
// Navegación entre páginas
this.Frame.Navigate(typeof(DetailPage));
// Navegación a la página anterior
this.Frame.GoBack();
// Navegación hacia la siguiente página
this.Frame.GoForward();
```

### Layout

Un *layout* es un contenedor de otros contenedores. Permiten el tamaño y posicionamiento de objetos u elementos en la pantalla. El posicionamiento podrá ser de distinto tipo:

* Absoluto. Se especifica el posicionamiento exacto de los objetos contenidos. No tiene en cuenta el tamaño de la pantalla. Como alternativa a las diferentes resoluciones podrían utilizarse diferentes páginas o bien escalar.
* Dinámico. Se especifica la organización de los elementos contenidos. Para ello, se utilizan valores especiales a asignar a sus propiedades *Width* y *Height*:
  * *Auto*. Utilizado en los controles *Grid* y *StackPanel* con el fin de ajustar los elementos contenidos al control contenedor.
  * *MinWidth* y *MinHeight*. Propiedades utilizadas para evitar que los controles que contienen texto queden ilegibles durante un escalado por reducción de tamaño. Cuando se usen estas propiedades, se eliminarán estas otras; Height y *Width*.
  * *RowDefinition* y *ColumnDefinition.* Propiedades utilizadas en un control *Grid*. Se utiliza el valor especial “\*” para las propiedades *Height* y *Width* indicando así un valor relativo. Si se quiere especificar que una columna o fila es un número “n” de veces mayor que otras, se ha de indicar con un valor positivo seguido de “\*”.
* Paneles contenedores. Son contenedores de otros elementos que organizan y posicionan a estos dentro del mismo.
  * *Canvas*. Define un área en la que colocar otros elementos mediante coordenadas X e Y relativas al área del mismo. Estas coordenadas vienen indicadas por las propiedades *Canvas.Left* y *Canvas.Top* respectivamente
  * *StackPanel*. Es un panel simple que organiza sus elementos en una única línea orientada horizontal o verticalmente. Este valor, se encuentra indicado por la propiedad *Orientation*. Su valor por defecto es *Vertical*.
  * *Grid*. Organiza sus elementos en una matriz con filas y columnas, representadas por las propiedades *RowDefinitions* y *ColumnDefinitions*. Adicionalmente, las propiedades *RowSpan* y *ColumnSpan*, permite agrupar varias filas o columnas respectivamente. De igual forma que para el posicionamiento dinámico, también cuenta con las propiedades *Width y Height*.
  * *Relative Panel*. Permite el posicionamiento de los controles hijos en relación unos con otros o bien en relación con el panel/grid padre que lo contiene. Dicho posicionamiento se consigue a través de las siguientes propiedades:
    * **Above**. Encima. Tomará como valor el control sobre el que se situará.
    * **Below**. Debajo. Tomará como valor el control bajo el que se situará.
    * **LeftOf**. A la izquierda de. Tomará como valor el control a partir del cual se posicionará a su izquierda.
    * **RightOf**. A la derecha de. Tomará como valor el control a partir del cual se posicionará a su derecha.
    * **Align<\*>With**. Alineado con. Donde <\*> puede tomar indistintamente el valor: *Top, Bottom, Left, Right, HorizontalCenter o VerticalCenter* y, un valor booleano indicando su alineación o posición respecto del control padre.
  * *ViewBox.* Es un contenedor que adapta su contenido al tamaño máximo definido por sus propiedades *MaxWidth* y *MaxHeight*. Aunque no es muy popular, conviene que lo conozcamos para saber cuándo puede sernos de utilidad.

{% hint style="info" %}
**Nota**: Sólo es posible utilizar un control dentro de una página XAML así que, para poder construir aplicaciones con interfaces de usuario ricas, necesitaremos que este control sea uno de los contenedores anteriores.
{% endhint %}

### Control Hub

El control de navegación centralizada (o *hub*), muestra grupos de contenido en una vista de desplazamiento panorámico, es decir, un área horizontal o vertical que se extiende mucho más allá de los límites de pantalla del dispositivo. Es el control por excelencia utilizado como base para muchas aplicaciones y el más significativo puesto que es uno de los controles que hace que la interfaz de usuario (UI) de Windows sea única.

Es utilizado principalmente como punto de entrada a la aplicación. Ofrece una manera atractiva de ver las novedades más interesantes, para luego profundizar en el contenido de la aplicación. La navegación centralizada muestra **distintas categorías de contenido**, cada una de las cuales se asigna a las páginas/secciones de la aplicación. Proporciona una amplia variedad visual, atrae a los usuarios y los dirige a distintas partes de la aplicación.

El control *Hub* se compone de:

* Cabecera (o *Header*). Título del control.
* Imagen del fondo (o *Background*).
* Secciones (o *HubSection*).
  * Cabecera (o *Header*). Título de cada sección
  * Imagen de fondo (o *Background*).

Permite al usuario desplazarse entre cada uno de sus paneles deslizando el dedo de izquierda a derecha o viceversa (***pan***). En la figura siguiente podemos ver un ejemplo:

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-79752f5e327561c0105f623eda87f8e8d964db87%2Fimage30.png?alt=media)

**Figura 18.- Estructura del control Hub: cabecera, secciones y área visible**

Al diseñar un control de ***Hub***, debemos tener en cuenta algunos aspectos importantes:

* Se recomienda **no utilizar más de cinco secciones**. Esto es debido a temas tanto de rendimiento como de usabilidad. Un número elevado de secciones pueden hacer que el usuario se desoriente.
* Evitar el uso de controles que permitan desplazamiento (o *scroll*) que puedan dificultar la propia navegación del control *Hub*. Estos controles podrían complicar los desplazamientos y/o navegación. En caso de ser necesario, crear un enlace o botón para navegar a otra página permitiendo volver hacia atrás a la misma sección del control *Hub*.
* Durante la carga de contenido en el control *Hub*, mostrar una barra de progreso a pantalla completa mientras que éste se carga. La carga inicial se realiza únicamente para las dos secciones indicadas por su propiedad *DefaultSectionIndex* cuyo valor por defecto es -1, es decir, la primera sección definida en el XAML.
* Si la carga de una sección es costosa, mostrar una barra de progreso en la barra de estado, para no bloquear la interacción del usuario.
* Si se utiliza una barra de estado, se recomienda que siempre este minimizada, extendiendo así el espacio a utilizar por el *Hub*.

Otro aspecto a saber, es que ha sido optimizado para que la carga de contenido se realice automáticamente al navegar a cada una de las secciones.

Al igual que cualquier control, el *Hub*, dispone de diferentes eventos que pueden ser capturados para su manipulación y navegación. En este sentido, y en caso de utilizar únicamente dos secciones, muchos de estos eventos no serán lanzados y por tanto no podrán ser capturados. Esto se debe a que siempre permanecen activas como máximo dos secciones.

{% hint style="info" %}
**Nota**: El uso de colores vivos en las imágenes de fondo puede dificultar la lectura del contenido de las secciones. Evitémoslos en la medida de lo posible.
{% endhint %}

### Control Pivot

El control *Pivot*, proporciona una forma rápida de administrar vistas a pantalla completa. Es muy parecido a un control basado en pestañas (o *Tab*s) y se puede utilizar para cambiar de vista o filtrar grandes cantidades de datos (por lo general, de un mismo conjunto de datos). Basta con deslizar el dedo de derecha a izquierda de la pantalla o viceversa, o pulsar sobre el título/cabecera de cada vista.

A cada una de las vistas o páginas, se les denomina *PivotItem*, y se compone de las siguientes partes:

* Titulo. Identifica a la aplicación.
* Cabeceras. Identificativo de cada una de las secciones que componen el control *Pivot*.
* Página o vista, *PivotItem*. Controles o elementos que forman el control *Pivot* y sobre los que se asientan otros controles y contenido.

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-cac34b913c8938ef67279b316041a5d12d0d12f6%2Fimage31.png?alt=media)

**Figura 19.- Control Pivot**

Al igual que para el control *Hub*, su diseño, requiere conocer algunas buenas prácticas:

1. No utilizar más de 4 ó 5 *PivoItems*.
2. Usarlo para mostrar objetos o datos de tipo similar.
3. Limitar el tamaño de las cabeceras a un máximo de dos palabras.
4. La actividad del usuario no debe cambiar de manera drástica al navegar entre cada *PivotItem*.
5. No mostrar el contenido de un *PivotItem* vacío, indicar en su caso, un mensaje informativo, como, por ejemplo, “No se han encontrado datos”.
6. Evitar el uso de controles que permitan desplazamiento o scroll que puedan dificultar la propia navegación del control *Pivot*. Estos controles podrían complicar los desplazamientos y/o navegación. En caso de ser necesario, crear un enlace o botón para navegar a otra página permitiendo volver hacia atrás a la misma sección del control *Pivot*.
7. No utilizar nunca un control de entrada de texto, para no dificultar la interacción del usuario, principalmente en los desplazamientos laterales.

Como habremos podido comprobar, tanto el control *Pivot* como el *Hub*, poseen muchas similitudes, sin embargo, la principal diferencia para saber cuándo utilizar uno u otro, radica en el contenido a mostrar en ellos. El *Hub*, tiene como objetivo mostrar información muy variada e incluso de diferentes fuentes de datos, mientras que el *Pivot*, pretende hacerlo a partir de una única fuente y su información está más ceñida a un tema en concreto.

### SplitView

Se trata de un panel extensible y plegable y un área de contenido. El panel se puede expandir y contraer o permanecer en abierto, y puede presentarse al lado izquierdo o derecho de una ventana de la aplicación. El área de contenido está siempre visible y tiene varios modos identificados por la propiedad *DisplayMode*:

**Tabla 10.- Modos del control SplitView**

| Modo                                                                                                                                                                                                                                                                                                                                                                                                                  | Figura representativa                                                                                                                                                                                 |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Superpuesto (u *Overlay*). El panel se oculta hasta su apertura. Cuando está abierto, el panel se superpone sobre el área de contenido. Generalmente el desencadenante para la apertura es un botón “*Hamburger*”.                                                                                                                                                                                                    | ![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-349d006bba7167c90bc4754853f279dc0b0fcf22%2Fimage32.png?alt=media) |
| Compacto (o *Compact*). El panel está siempre visible, con un ancho suficientemente como para mostrar los iconos (por lo general de 48px). El panel y el área de contenido dividen el espacio en pantalla disponible. Aunque el modo compacto estándar no cubre el área de contenido, se puede transformar en un panel más grande para mostrar más contenido e incluso pudiendo llegar a cubrir el área de contenido. | ![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-63d9a589cfa91b3a01eacb58ab742b6c0f2bb53a%2Fimage33.png?alt=media) |
| En línea (o *Inline*). El panel esta siempre visible y no se superpone sobre el área de contenido. El panel y el área de contenido dividen el espacio en pantalla disponible                                                                                                                                                                                                                                          | ![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-b92c6ca2af2e64ff1b1421d18c65f6427b47abaa%2Fimage34.png?alt=media) |

Un control **SplitView** o un control **Pivot** pueden utilizarse para un mismo propósito, si bien, la representación sería distinta. La siguiente figura es una prueba de ello:

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-a8a450dcb5a4d06c846bbc0da6d5ca74f13024c9%2Fimage35.png?alt=media)

**Figura 20.- Representación para los controles SplitView y Pivot**

Este control toma especial relevancia en las nuevas aplicaciones UWP, particularmente en aplicaciones de escritorio.

### Control WebView

El control VistaWeb (o *WebView*), es un control que permite hospedar contenido HTML en una aplicación con el comportamiento de Internet Explorer. A diferencia de cualquier otro control, éste no dispone de una plantilla *Control*. Sin embargo, comparte propiedades y puede comportarse de manera semejante.

* Source. *URI* absoluta o relativa de la fuente donde se encuentra el contenido HTML.
* Navigate. Realiza la navegación a una *URI* absoluta o relativa de la fuente donde se encuentra el contenido HTML.
* NavigateToString. Cadena de texto en formato HTML a mostrar.
* InvokeScript/InvokeScriptAsync. Ejecuta una función de script definida en el documento HTML cargado.
* NavigateWithHttpRequestMessage. Navega a una URI con una petición POST y encabezados HTTP.
* NavigateToLocalStreamUri. Carga contenido local a través de una resolución personalizada. Esto habilita escenarios avanzados como la descarga y almacenamiento en caché de contenido basado en web para su uso sin conexión.
* Eventos para responder a los estados de navegación y de carga de contenido: *NavigationStarting*, *ContentLoading*, *DOMContentLoaded*, *NavigationCompleted*, *FrameNavigationStarting*, *FrameContentLoading*, *FrameDOMContentLoaded* y *FrameNavigationCompleted*.
* Eventos para responder a posibles situaciones problemáticas: *LongRunningScriptDetected*, *UnviewableContentIdentified*, *UnsupportedUriSchemeIdentified* y *UnsafeContentWarningDisplayingevent*.
* Método *CapturePreviewToStreamAsync* para obtener una imagen de vista previa de contenido hospedado.
* Métodos asincrónicos para invocar el script y recopilar el contenido seleccionado como paquete de datos para el uso compartido: *InvokeScriptAsync* y *CaptureSelectedContentToDataPackageAsync*.
* Propiedades para obtener el título del documento y establecer el color de fondo predeterminado: *DocumentTitle* y *DefaultBackgroundColor*.
* Compatibilidad con el esquema *ms-appdata* y los almacenes de datos *LocalFolder* y *TemporaryFolder*. Esto habilita la navegación a URIs tales como *ms-appdata:///local/folder/file.html* y *ms-appdata:///temp/folder/file.html*. La compatibilidad de *WebView* con este esquema requiere colocar el contenido en una subcarpeta bajo la carpeta local o temporal. Cada una de estas subcarpetas de primer nivel está aislada del contenido de las demás subcarpetas de primer nivel. Por ejemplo, podemos navegar a *ms-appdata:///temp/folder1/file.html* pero no tener un vínculo *para navegar a ms-appdata:///temp/folder2/file.html*.
* NewWindowRequested. Evento originado cuando el usuario lanza una acción que implica que el contenido sea abierto en una nueva ventana.
* PermissionRequested. Evento que ocurre cuando una acción requiere permisos.
* ScriptNotify. Evento causado cuando el control *WebView*, pasa una cadena a la aplicación a través de JavaScript.
* CaptureSelectedContentToDataPackageAsync. Habilita el uso compartido de contenido con otras aplicaciones.

Visitar la página siguiente para más detalle sobre las características de este control: <https://msdn.microsoft.com/es-es/windows/uwp/controls-and-patterns/web-view>

{% hint style="info" %}
**Nota**: Para que una página web externa genere el evento *ScriptNotify* al llamar a *window\.external.notify*, es imprescindible incluir la URI de la página en la sección “ApplicationContentUriRules” del manifiesto de la aplicación (pestaña “Content URIs\_”\_ del diseñador del manifiesto de la aplicación). Esto no se aplica al contenido que procede del paquete de la aplicación. Para ello será necesario utilizar una URI del tipo *ms-local-stream://* o realizar la carga del contenido mediante *NavigateToString*.
{% endhint %}

La siguiente figura muestra el aspecto de este control en ejecución:

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-d37edf7612a4abe4d89a3728be541d6d4e1d562f%2Fimage36.png?alt=media)

**Figura 21.- Control Web View**

### SemanticZoom

El control de Zoom Semántico (o *Semantic Zoom*), permite que al usuario hacer zoom entre dos vistas semánticas distintas del mismo conjunto de datos. Una de las cuales contiene una lista de elementos agrupados por clave y la otra, una lista de claves de grupo. Al pulsar una clave de grupo, se muestran los elementos de ese grupo.

El poder alejar y ver todas las claves de grupo en una sola página resulta de gran ayuda al usuario, ya que puede acceder rápidamente a un elemento distante sin necesidad de desplazarse demasiado.

Un ejemplo claro es el *hub* de fotos de Windows 10, donde las fotos son agrupadas por fecha en la vista de cerca (o *zoom in*) y en la vista de lejos (o *zoom out*) se muestra un listado con todas las fechas para las que hay fotos. El cambio entre una vista y otra se realiza al pulsar el encabezado de claves de grupo. Para el siguiente ejemplo, al pulsar sobre la fecha “abril de 2016” en la vista de cerca. De igual forma, la aplicación de contactos, o incluso el propio menú de Windows incluye zoom semántico, pero en este último caso, en su vista alfanumérica.

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-0781452646be48e83eb3478c04b1ba5c9b196a65%2Fimage37.png?alt=media) ![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-cb36de1796778b81a0d5da21dfb7052de19e537d%2Fimage38.png?alt=media)

**Figura 22.- Zoom semántico. Vistas reducidas y ampliadas. Aplicación de fotos y menú de Windows**

Cuando se habla de zoom semántico, se habla implícitamente de los controles GridView y ListView. Los veremos a continuación.

### GridView

Una vista de cuadrícula (o *GridView*), es una colección de contenido que proporciona una determinada agrupación tal y como indica su nombre.

Un control Grid, ha de definir las filas y columnas de las que se compone a través de las propiedades *RowDefinition* y *ColumnDefinition.* El siguiente ejemplo define un Grid con dos filas y dos columnas:

```
<Grid.RowDefinitions>
  <RowDefinition Height="Auto"/>
  <RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
  <ColumnDefinition Width="*" />
  <ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
```

Donde:

* La primera de fila toma un valor *Auto* (automático) para el tamaño del alto. Su tamaño real dependerá de los controles que ésta contenga en su interior.
* La segunda fila toma un valor “\*”, lo que indica que su tamaño coincidirá con el tamaño restante no usado por la primera fila.
* La primera columna tiene un ancho fijo equivalente a la mitad de la segunda, o lo que es lo mismo, la segunda columna tiene el doble que la primera.

El posicionamiento de cada control de Windows, dentro del Grid, se indica mediante sus propiedades *Grid.Row* y *Grid.Colum*. El siguiente ejemplo muestra cómo situar dos textos y dos controles; fecha (*DatePicker*) y hora (*TimePicker*) en el grid definido anteriormente:

```
<TextBlock Grid.Column="0" Text="Fechas" Style="{ThemeResource HeaderTextBlockStyle}" />
<TextBlock Grid.Column="1" Text="Horas" Style="{ThemeResource HeaderTextBlockStyle}" />
<DatePicker Grid.Row="1" Grid.Column="0" />
<TimePicker Grid.Row="1" Grid.Column="1" />
```

La siguiente figura ilustra el resultado.

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-7a799f3f45a8999003c7d0d2e6d9034173b2fbcb%2Fimage39.png?alt=media)

**Figura 23.- Definición y posicionamiento en un GridView**

{% hint style="info" %}
**Nota**: En un control *Grid*, se utiliza el valor especial “*” para las propiedades Height y Width indicando así un valor relativo. Para especificar que una columna o fila es un número “n” de veces mayor que otra, se indicará con un valor positivo seguido de “*”.
{% endhint %}

### ListView

Una vista de lista (o *ListView*), es una colección que proporciona una agrupación de contenido. Aunque puede incluir columnas, la diferencia con el *GridView*, es que éste, muestra su contenido verticalmente.

### CalendarDatePicker, DatePicker y TimePicker

Los controles *DatePicker* y *TimePicker*, son controles, que permiten la selección de una fecha y una hora de una forma muy sencilla e intuitiva. Se basan en la configuración del usuario para mostrar esta selección.

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-9645a9e5c2d7e917635909d901eb7b2779a6aa72%2Fimage40.png?alt=media) ![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-b1da5e7068175b9a85b5b50863435bf5632bae48%2Fimage41.png?alt=media)

**Figura 24.- Aspectos de los controles CalendarDatePicker y DatePicker**

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-1aebe02acc0409a333ead541fe9972ef45eab1b8%2Fimage42.png?alt=media) ![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-5a4ba9ff542a4092f8aa00a4ff85e90000ad2198%2Fimage43.png?alt=media)

**Figura 25.- Aspecto del control DateTimePicker en formato 12h y 24h**

{% hint style="info" %}
**Nota**: La propiedad *Date* del control *DatePicker* requiere un tipo *DateTimeOffset* y, la propiedad *Time* del control *TimePicker*, una de tipo *TimeSpan*. Es por tanto necesario, implementar una clase ***IValueConverter*** para su conversión si trabajamos con datos *DateTime*.
{% endhint %}

### DatePickerFlyout y TimePickerFlyout

El control *DatePickerFlyout* permite crear un desplegable para mostrar y seleccionar la fecha al igual que un control *DatePicker*. La diferencia es que el primero aporta una personalización mayor.

El siguiente código *XAML*, ejemplifica su uso:

```
<TextBox x:Name="txt" IsReadOnly="True" />
<Button x:Name="dp" Content="&#xe163;" FontFamily="Segoe MDL2 Assets">
  <Button.Flyout>
    <DatePickerFlyout DatePicked="PastDatePicker_DatePicked"/>
  </Button.Flyout>
</Button>
```

Donde el código C# asociado al control XAML del ejemplo anterior (comúnmente conocido como *code behind*), para el evento *DatePicker* se corresponde con el siguiente código:

```
private void PastDatePicker_DatePicked(DatePickerFlyout sender, DatePickedEventArgs args)
{
  var formatter = new DateTimeFormatter("day dayofweek month year");
  txt.Text = formatter.Format(sender.Date);
}
```

Al igual que para este ejemplo hemos empleado un control *Button*, podríamos haber utilizado en su lugar, cualquier otro control de tipo *FrameworkElement*.

Los controles *TimePickerFlyout y DatePickerFlyout* son equivalentes a los dos anteriores, con la salvedad de que estos últimos aplican a horas y no a fechas.

### Flyout

Un control *Flyout* muestra un mensaje flotante que requiere la interacción del usuario sin ser una ventana de diálogo, es decir, sin bloquear cualquier otra interacción del usuario. Permite la creación de desplegables con contenido totalmente personalizable: Cajas de texto, botones, etc. El posicionamiento del contenido depende de su propiedad *Placement* y para cerrarlo basta con hacer *click* fuera de su contenido, pulsar la tecla “Esc”, o bien, la tecla “Back” en el caso de dispositivos móviles. El siguiente ejemplo recoge el uso de este control para presentar un mensaje de texto al usuario.

```
<Button Grid.Row="3" Content="Click Me!">
  <Button.Flyout>
    <Flyout Placement="Top">
      <TextBlock Text="Ejemplo de texto en un Flyout ..."/>
    </Flyout>
  </Button.Flyout>
</Button>
```

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-3deb21573881ecb8333f14027f4a0844bfe4eb8b%2Fimage44.png?alt=media)

**Figura 26.- Mensaje básico usando el control Flyout**

De igual forma podemos utilizarlo como si de cuadro de diálogo se tratara. Por ejemplo, el siguiente código XAML implementa esta casuística utilizando un control *Button*.

```
<Button Content="Click Me !">
  <Button.Flyout>
    <Flyout x:Name="dialog" Placement="Full">
      <Grid MaxWidth="400">
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto"/>
          <RowDefinition Height="*"/>
          <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <TextBlock Text="Some title"
                   Style="{StaticResource HeaderTextBlockStyle}" />
        <TextBlock Grid.Row="1"
                   Style="{StaticResource MessageDialogContentStyle}"
                   Text="Lorem ipsum …"/>
        <Button Grid.Row="2"
                Content="OK" HorizontalAlignment="Right"
                Click="btnHideClick"/>
      </Grid>
    </Flyout>
  </Button.Flyout>
</Button>
```

La figura 27, representa el resultado tras la ejecución del código anterior.

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-1739bc657b042ec41295dff48937c7e50ae1ae1a%2Fimage45.png?alt=media)

**Figura 27.- Cuadro de dialogo mostrado usando el control Flyout**

### MenuFlyout

Se trata de un desplegable en forma de menú contextual que se comporta de forma análoga al control *Flyout,* con la diferencia de que está orientado al uso con menús. Puede contener los elementos siguientes:

* MenuFlyoutItem. Elemento de menú.
* MenuFlyoutseperator. Separador.
* ToggleMenuFlyout. Elemento de menú con marca de selección (o “Check”).

  MenuFlyoutSubItem. Elemento secundario de menú

También está indicado para la representación de acciones contextuales ligadas a un elemento en particular, tales como: *Copy, Cut y Paste*, en la selección de textos.

Los siguientes códigos muestran dos ejemplos para la representación de un mismo menú. Podemos ver ambos representados en la figura 28.

```
<Button Content="Show menu !">
  <Button.Flyout>
    <MenuFlyout>
      <MenuFlyoutItem Text="Date" IsEnabled="False" />
      <MenuFlyoutItem Text="Today" />
      <MenuFlyoutItem Text="Tomorrow" />
      <MenuFlyoutSeparator />
      <MenuFlyoutItem Text="Priority" IsEnabled="False" />
      <MenuFlyoutItem Text="High" />
      <MenuFlyoutItem Text="Low" />
    </MenuFlyout>
  </Button.Flyout>
</Button>
```

```
<Button Content="Show menu subitems">
  <Button.Flyout>
    <MenuFlyout>
      <MenuFlyoutSubItem Text="Date">
        <MenuFlyoutItem Text="Today" />
        <MenuFlyoutItem Text="Tomorrow" />
      </MenuFlyoutSubItem>
      <MenuFlyoutSubItem Text="Priority">
        <MenuFlyoutItem Text="High" />
        <MenuFlyoutItem Text="Low" />
      </MenuFlyoutSubItem>
    </MenuFlyout>
  </Button.Flyout>
</Button>
```

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-b0d831905d483ec18e19ddf893d36bad7b29f905%2Fimage46.png?alt=media)

**Figura 28.- Representaciones distintas de un menú usando MenuFlyout**

{% hint style="info" %}
**Nota**: Se recomienda utilizar en un menú contextual el menor número posible de comandos y emplear textos cortos para cada elemento. La primera letra de cada elemento deberá ser mayúscula.
{% endhint %}

### Popup

Muestra un mensaje flotante (o emergente) de forma similar al control *Flyout*. Se suele utilizar para mostrar temporalmente contenido al finalizar la ejecución de una tarea particular. A diferencia de otros controles, no tiene una plantilla visual por defecto, por lo que, en su lugar, debe definirse el contenido del mismo. Se recomienda utilizar un control de usuario (*UserControl*) y fijarlo como su contenido.

### ComboBox

Control desplegable que muestra un listado con un conjunto de elementos indicados por la propiedad *ItemsSource*. Se trata realmente de un control y no de un *Flyout*. Para Windows Mobile, muestra los elementos a pantalla completa cuando su número es mayor de 5.

### AutoSuggestBox

Se trata de un control similar a un *TextBox*, pero con la diferencia de que éste incluye un listado de sugerencias que son mostradas al usuario a medida que va escribiendo. Un ejemplo podría ser el siguiente, donde se supone una fuente de datos para las sugerencias:

Código XAML:

```
<AutoSuggestBox ItemsSource="{Binding Sugerencias}"
        SuggestionChosen="AutoSuggestBox_SuggestionChosen"
        TextChanged="AutoSuggestBox_TextChanged" >
  <AutoSuggestBox.ItemTemplate>
    <DataTemplate>
      <TextBlock Text="{Binding}"/>
    </DataTemplate>
  </AutoSuggestBox.ItemTemplate>
</AutoSuggestBox>
```

Código C#:

```
private ObservableCollection<string> sugerencias;
public ObservableCollection<string> Sugerencias
{
  get
  {
    if (null == sugerencias)
      sugerencias = new ObservableCollection<string>();
    return sugerencias;
  }
}

private void AutoSuggestBox_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
{
  if (args.Reason == AutoSuggestionBoxTextChangeReason.UserInput)
  {
    // Obtener las sugerencias a partir de la fuente de datos y
    // según vaya escribiendo el usuario.
    // Las siguientes líneas simulan su uso.
    Sugerencias.Clear();
    Sugerencias.Add(sender.Text + "1");
    Sugerencias.Add(sender.Text + "2");
  }
}

private void AutoSuggestBox_SuggestionChosen(AutoSuggestBox sender, AutoSuggestBoxSuggestionChosenEventArgs args)
{
  // Incluir código según la sugerencia seleccionada
}
```

### FlipView

El control vista de vuelta/giro (o *FlipView*) es un control que permite recorrer una colección de elementos de forma secuencial, uno a uno permite mostrar una galería de imágenes. Hereda de la clase *ItemsControl*, al igual que los controles *ListView* y *GridView*, por lo que comparte muchas de sus características.

Seguidamente, se muestra un ejemplo de uso utilizando varias imágenes con desplazamiento horizontal.

Código XAML:

```
<FlipView Grid.Row="4" Grid.ColumnSpan="2" ItemsSource="{Binding Imagenes}">
  <FlipView.ItemsPanel>
    <ItemsPanelTemplate>
      <VirtualizingStackPanel Orientation="Horizontal"/>
    </ItemsPanelTemplate>
  </FlipView.ItemsPanel>
  <FlipView.ItemTemplate>
    <DataTemplate>
      <Grid>
        <Image Source="{Binding Image}" Stretch="UniformToFill"/>
        <Border Background="#A5000000" Height="40" VerticalAlignment="Bottom">
          <TextBlock Text="{Binding Text}" Foreground="#CCFFFFFF" TextWrapping="Wrap" />
        </Border>
      </Grid>
    </DataTemplate>
  </FlipView.ItemTemplate>
</FlipView>
```

En el ejemplo, las imágenes se muestran horizontalmente al deslizar el dedo de derecha a izquierda y viceversa.

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-879fe8dd1df687363c7b155fd671ddc26390e6f9%2Fimage47.png?alt=media)

**Figura 29.- Ejemplo de FlipView durante un desplazamiento horizontal**

Cambiando el valor del atributo *Orientation* de la propiedad *VirtualizingStackPanel*, la transición se produciría verticalmente.

### ProgressBar

Una barra de progreso (o, ***ProgressBar***) indica visualmente el progreso de una operación con dos estilos posibles en base a su propiedad booleana *IsIndeterminate*:

* *True*. Muestra un patrón de repetición.
* *False*. La barra se va completando en base a un valor de progreso (*Value*). En este caso, hay que especificar un intervalo mediante las propiedades *Minimum* y *Maximum*. Por defecto, 0 y 100 respectivamente.

### ProgressRing

Un anillo de progreso (o *ProgressRing*) tiene el mismo propósito que la barra de progreso, pero a diferencia de ésta, se trata de un anillo formado a su vez por una serie de puntos que giran formando un círculo. No posee la propiedad *IsIndeterminate* y por tanto, se trata de un progreso que se repite continuamente siempre que su propiedad *IsActive* tiene el valor *true*.

### ­Mensajes de usuario

Existen multitud de alternativas para mostrar información al usuario, algunas de ellas ya las hemos visto anteriormente como indicadores visuales. Sin embargo, también es necesario mostrar mensajes de ayuda, alertas o errores con una cierta información. Windows proporciona algunos controles para ello:

* MessageDialog. Muestra un mensaje en un cuadro de diálogo simple. El cuadro de diálogo es modal, permite especificar un título y hasta un máximo de tres botones que pueden utilizarse para determinar la respuesta del usuario.
* ContentDialog. Se trata de una ventana de diálogo que requiere de la interacción del usuario. Es personalizable y puede ser mostrada total o parcialmente. Al tratarse de una ventana de dialogo, impide cualquier acción fuera de la misma hasta que ésta se cierra. Para crearla, basta con añadir al proyecto un nuevo ítem de tipo *ContentDialog* y diseñarlo acorde a nuestras necesidades como cualquier otra página o control XAML. La siguiente imagen muestra su creación desde Visual Studio:

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-367aba0e1456f4a4971262fe4582f0a3542f4a26%2Fimage48.png?alt=media)

**Figura 30.- Ejemplo de creación de un control ContentDialog**

Para mostrarlo, será suficiente con las siguientes dos líneas de código:

```
ContentDialog1 dialog = new ContentDialog1();
ContentDialogResult result = await dialog.ShowAsync();
```

En dispositivos móviles, donde no se muestra a pantalla completa, este control bloquea el resto de acciones sobre la aplicación hasta que se cierra explícitamente la misma. Generalmente a través de un botón o bien al pulsar la tecla “Esc”.

Además de los controles anteriores, para presentar mensajes al usuario, podemos utilizar los controles ***Flyout*** o ***Popup***, o incluso otros, tales como un *Panel* o *Border*, mostrando u ocultando su contenido. Por ejemplo, es bastante común utilizar un *Border* con un *TextBlock* que se muestre temporalmente y que no se necesite la interacción del usuario, haciéndolo visible únicamente durante un periodo de tiempo, como si se tratara de una notificación.

### Control Presenter

Permite personalizar fácilmente contenido de un control, presentando el mismo con un aspecto diferente al establecido por defecto. Puede representar controles no disponibles, e incluso actuar como una clase base para controles especiales: *ContentPresenter*, *ScrollContentPresenter*, *FlyoutPresenter, DatePickerFlyoutPresenter*, etc. Suele usarse como plantilla ***ControlTemplate*** dentro un *ContentControl*. A continuación, podemos ver un ejemplo donde un *chekbox* presenta su texto debajo de la caja de marcado (o *check*).

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-7b42780ca756f53fed2dd38a6fbc82af601d3455%2Fimage49.PNG?alt=media)

**Figura 31.- Control CheckBox utilizando un ContentPresenter**

Código XAML:

```
<CheckBox Content="Check Test" >
  <CheckBox.ContentTemplate>
    <DataTemplate>
      <ContentPresenter
        Content="{Binding}"
        Margin="-65,25,0,0"
        HorizontalAlignment="Center">
      </ContentPresenter>
    </DataTemplate>
  </CheckBox.ContentTemplate>
</CheckBox>
```

### VisualStateManager

El control VisualStateManager, permite especificar estados y apariencias a otros controles y administra dichos estados y la lógica correspondiente para la transición entre ellos.

El aspecto de un control cuando se encuentra en un estado determinado se representa con el objeto ***VisualState,*** que está formado por una colección de objetos *Storyboard* que especifican cómo cambia la apariencia del control en un estado determinado.

Los estados visuales son añadidos estableciendo la propiedad *VisualStateManager.VisualStateGroups*. Cada ***VisualStateGroup*** contiene una colección de objetos *VisualState* donde el control siempre se encuentra en un estado diferente para cada VisualStateGroup.

El siguiente ejemplo de código muestra cómo cambiar la apariencia y comportamiento de un botón.

```
<ControlTemplate TargetType="Button">
  <Grid>
    <VisualStateManager.VisualStateGroups>
      <VisualStateGroup x:Name="CommonStates">
        <VisualStateGroup.Transitions>
          <VisualTransition To="PointerOver" GeneratedDuration="0:0:0.5" />
        </VisualStateGroup.Transitions>
        <VisualState x:Name="Normal"/>
        <VisualState x:Name="PointerOver">
          <Storyboard>
            <ColorAnimation Duration="0" Storyboard.TargetName="borderColor" Storyboard.TargetProperty="Color" To="Cyan"/>
          </Storyboard>
        </VisualState>
        <VisualState x:Name="Pressed">
          <Storyboard>
            <ColorAnimation Duration="0" Storyboard.TargetName="borderColor" Storyboard.TargetProperty="Color" To="Red"/>
          </Storyboard>
        </VisualState>
      </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
    <Ellipse>
      <Ellipse.Fill>
        <SolidColorBrush x:Name="borderColor" Color="Black"/>
      </Ellipse.Fill>
    </Ellipse>
    <Ellipse x:Name="ButtonShape" Margin="5" Fill="{TemplateBinding Background}"/>
    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
  </Grid>
</ControlTemplate>
```

Como resultado, el botón pasa a tener la apariencia de una elipse con un borde rojo o cian, dependiendo de si se pulsa el botón o se mantiene pulsado.

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-f8cb185bd794a6f7c1793f0d8f97b13207e395a5%2Fimage50.png?alt=media)

**Figura 32.- Modificando la apariencia y comportamiento de un botón con VisualStateManager**

Al igual que hemos hecho para el botón, gracias al control *VisualStateManager* vamos a poder realizar este tipo de cambios para cualquier otro control.

Si queremos otorgar a nuestros controles comportamientos y apariencias mucho más ricas visitar la página <https://msdn.microsoft.com/es-es/windows/uwp/graphics/index>, donde podemos profundizar en la creación de elementos gráficos y animaciones.

El control *ContentPresenter*, puede ser usado en conjunto con VisualStateManager aportando ambos, un mayor control de comportamiento y apariencia en todos nuestros controles.

### Control Map

Al hablar del control Mapa (o *MapControl*), nos referimos implícitamente a mapas y localizaciones. Hablamos por tanto de: coordenadas de GPS, Geovalla (o *Geofence*), vistas en 2D y 3D, puntos de interés, etc.

Este control nos va a permitir representar gráficamente todas estas funcionalidades sin necesidad de preocuparnos de ello. Sin embargo, a diferencia de otros controles, para poder trabajar con él, tenemos que seguir algunos pasos previos:

1. Acceder y completar el registro en el portal de desarrollo de Bing Maps (*Bing Maps Dev Center*): <https://www.bingmapsportal.com>
2. Crear de una **clave básica** de autenticación tal y como muestra la siguiente figura.

   ![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-5e0bd0a27da753c7d0d38411044f583884c18141%2Fimage51.png?alt=media)

**Figura 33.- Creando una clave básica para el control Map**

3. Asignar la clave obtenida a la propiedad *MapServiceToken* del control Map en el código XAML.

```
<maps:MapControl x:Name="addressMap"
  Grid.Row="2"
  HorizontalAlignment="Stretch"
  VerticalAlignment="Stretch"
  MapServiceToken="JLlajFod . . . GA9xx6yGM"
  ZoomLevel="14"
  Heading="0"
  DesiredPitch="50" />
```

Esta **clave básica**, nos ofrece la posibilidad de usar los servicios de Bing en aplicaciones orientadas al consumidor, educación y sin fines de lucro, así como para aplicaciones comerciales internas de Windows que se califiquen para uso gratuito. Existe a su vez, otra clave *Enterprise*, sin éstas restricciones y con menos limitaciones. Las diferencias entre ambas pueden consultarse en la página: <https://www.microsoft.com/maps/create-a-bing-maps-key.aspx>. Y, para más detalle sobre localizaciones y mapas, visitar la página: <https://msdn.microsoft.com/es-es/windows/uwp/maps-and-location/index>

{% hint style="info" %}
**Nota**: Como hemos comentado al comienzo de esta sección, podríamos seguir nombrado y describiendo todos los controles de la plataforma, no obstante, hemos considerado nombrar sólo aquellos más comunes o que merecen especial atención. Para más detalle sobre cualquiera de ellos, visitar la página: <https://msdn.microsoft.com/es-es/library/windows/apps/mt185406.aspx>. De la misma manera, para profundizar los homólogos de HTML, visitar: <http://msdn.microsoft.com/es-es/library/windows/apps/hh465453.aspx>.
{% endhint %}

## Automation UI

Microsoft Automation UI (o *UIAutomation*), es un *framework* de accesibilidad que permite a las aplicaciones proporcionar y consumir información sobre interfaces de usuario. Proporciona acceso mediante programación a la mayoría de los elementos de la interfaz de usuario. Permite a productos de tecnología de asistencia, como lectores de pantalla, proporcionar información sobre la interfaz para usuarios finales y para manipularla por medios distintos a los de entrada estándar. También permite a los scripts de pruebas automatizadas (o ***Coded UI Tests***) interactuar con la interfaz de usuario.

Las propiedades ***AutomationProperties***, disponibles en todos los controles de interfaz de usuario van a permitirnos indicar a nuestra aplicación toda la información necesaria para cumplir con el objetivo de la automatización. El siguiente ejemplo de código XAML muestra las propiedades principales para la automatización de pruebas, concretamente, *AutomationId* y *Name*:

```
<ListView
  ItemsSource="{ Binding Projects }"
  AutomationProperties.AutomationId="Projects"
  AutomationProperties.Name="Projects"
  …
/>
```

Mientras que el identificador (*AutomationId*) denota unívocamente a cada control, el nombre (*Name*), es utilizado exclusivamente para propósitos de depuración y/o diagnóstico.

Para más detalle sobre *Automatización de IU*, visitar la página: <https://msdn.microsoft.com/en-us/windows/uwp/accessibility/accessibility>.

## Web Authentication Broker

El agente/bróker de autenticación web (o *Web Authentication Broker*) consiste en un conjunto de APIs que permiten realizar inicio de sesión único, *Single Sign-On (SSO),* para autenticarse en un solo servicio a través de múltiples aplicaciones. Es compatible con los protocolos de autenticación ***OAuth*** y ***OpenID***. Así que es posible integrar aplicaciones con un servicio web que proporcione autenticación de usuario. Lo que permite utilizar la identidad del mismo en aplicaciones como Facebook, Twitter y Google.

Cuando una aplicación llama al *Broker*, el usuario recibe un cuadro de diálogo en el que las páginas web se vuelven necesarias para iniciar sesión. El *Broker* permite que el usuario consienta la autenticación y debe informarse de cómo se está utilizando su identidad. Por lo general, proporcionando un enlace a una declaración de privacidad de la página de inicio de sesión. Después de que el usuario complete estos pasos, el cuadro de diálogo desaparece y el usuario queda autenticado y continúa con la aplicación. La siguiente imagen muestra un ejemplo en el que el *Broker* presenta el cuadro de diálogo de Facebook para realizar la autenticación en Windows y Windows Mobile.

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-a603c071614bdb2976591c8f0dc69ade656f4510%2Fimage52.png?alt=media) ![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-a41ddbcab2a8ecddfcdc25e54b8e28f02e9b21c4%2Fimage53.png?alt=media)

**Figura 34.- Ejemplo de control “Web AuthenticationBroker” utilizando Facebook**

El bróker de autenticación se caracteriza principalmente por:

* Facilitar el desarrollo para la autenticación.
* Integrar de las páginas web de proveedores con la interfaz de usuario.
* Aislar las credenciales de usuario de la aplicación.
* Proporciona soporte nativo para el inicio de sesión único con proveedores online.

Para más detalle, visitar la página: <https://msdn.microsoft.com/es-es/windows/uwp/security/web-authentication-broker>.

## Temas

Un tema (o *theme*), es un conjunto de recursos que utilizaremos para personalizar elementos visuales en una aplicación. Es una combinación de un color de fondo y un color de énfasis, más comúnmente conocido como color de acento (*accent color*).

* El color de fondo. Como su propio nombre indica, es el color que se aplica al fondo. Existen dos colores: Oscuro y claro (*Dark* y *Light,* respectivamente).
* El color de acento o *accent color*, es el color que se aplica a controles y otros elementos visuales. En la siguiente figura se muestran estos con sus correspondientes valores hexadecimales.

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-443ee01b1aab6650030aee3fb12d82ec51c80440%2Fimage54.png?alt=media)

**Figura 35.- Colores de acento con sus valores hexadecimales**

Cabe la posibilidad de que exista un color de acento adicional, siendo el fabricante de hardware el operador móvil, quien decida si agregarlo o no al terminal.

Los temas aseguran que los controles y elementos de interfaz son consistentes en todos los dispositivos y, permiten crear aplicaciones que preserven la apariencia de interfaz desde un punto de vista estético.

Cada tema dispone de una serie de propiedades que pueden ser aplicadas en tiempo de diseño a través de código *XAML* y son:

* Recursos de pincel o brocha.
* Recursos de color.
* Nombre de fuentes.
* Espesor/grosor.
* Tamaño de fuentes
* Estilos de texto
* Temas de Visibilidad y opacidad.

Podremos definirlos según nuestras necesidades, no obstante, disfrutaremos de una serie temas ya predefinidos para los colores de fondo Claro y Oscuro (*Light y Dark*):

**Tabla 11.- Temas de colores Claro y Oscuro predefinidos**

| Clave (o *Key*)                 | Light     | Dark      |
| ------------------------------- | --------- | --------- |
| SystemAltHighColor              | #FFFFFFFF | #FF000000 |
| SystemAltLowColor               | #33FFFFFF | #33000000 |
| SystemAltMediumColor            | #99FFFFFF | #99000000 |
| SystemAltMediumHighColor        | #CCFFFFFF | #CC000000 |
| SystemAltMediumLowColor         | #66FFFFFF | #66000000 |
| SystemBaseHighColor             | #FF000000 | #FFFFFFFF |
| SystemBaseLowColor              | #33000000 | #33FFFFFF |
| SystemBaseMediumColor           | #99000000 | #99FFFFFF |
| SystemBaseMediumHighColor       | #CC000000 | #CCFFFFFF |
| SystemBaseMediumLowColor        | #66000000 | #66FFFFFF |
| SystemChromeAltLowColor         | #FF171717 | #FFF2F2F2 |
| SystemChromeBlackHighColor      | #FF000000 | #FF000000 |
| SystemChromeBlackLowColor       | #33000000 | #33000000 |
| SystemChromeBlackMediumLowColor | #66000000 | #66000000 |
| SystemChromeBlackMediumColor    | #CC000000 | #CC000000 |
| SystemChromeDisabledHighColor   | #FFCCCCCC | #FF333333 |
| SystemChromeDisabledLowColor    | #FF7A7A7A | #FF858585 |
| SystemChromeHighColor           | #FFCCCCCC | #FF767676 |
| SystemChromeLowColor            | #FFF2F2F2 | #FF171717 |
| SystemChromeMediumColor         | #FFE6E6E6 | #FF1F1F1F |
| SystemChromeMediumLowColor      | #FFF2F2F2 | #FF2B2B2B |
| SystemChromeWhiteColor          | #FFFFFFFF | #FFFFFFFF |
| SystemListLowColor              | #19000000 | #19FFFFFF |
| SystemListMediumColor           | #33000000 | #33FFFFFF |

También contamos con otro tema de colores para Alto Contraste y, con un conjunto de estilos y plantillas ya predefinidas para todos los controles que hemos visto a lo largo esta sección. Podemos encontrarlas en la página: <https://msdn.microsoft.com/es-es/library/windows/apps/mt299122.aspx>.

Si queremos profundizar más aún sobre los Temas, podemos visitar la página: <https://msdn.microsoft.com/es-es/windows/uwp/controls-and-patterns/xaml-theme-resources>.

{% hint style="info" %}
**Nota**: ¿Quieres ver todos estos controles en acción, cambiar sus propiedades y comportamientos en vivo y en directo? Si es así, descarga de la Tienda la aplicación “**XAML UI Controls**”, no necesitarás programar para navegar y bucear entre todo ellos de una manera muy visual y práctica. Si, aun así, quieres ir más allá, entonces te recomendamos que accedas al repositorio de **Github** de Microsoft: <https://github.com/Microsoft/Windows-universal-samples.git>, donde encontrarás números ejemplos sobre cada uno de ellos.
{% endhint %}
