[Windows 10] La nueva Title Bar

Introducción

Las aplicaciones Windows 10 corren como cualquier otra aplicación de
escritorio en formato ventana. Esta característica añade un nuevo
componente llamado TitleBar que contiene el título de
la Aplicación a la izquierda con los tres conocidos botones para
minimizar, expandir y cerrar a la derecha.

¿Qué opciones presenta?, ¿hasta dónde podemos personalizarlo?

En este artículo vamos a utilizar y personalizar las opciones disponibles de la TitleBar de diferentes formas.

La nueva Title Bar

Crearemos un nuevo proyecto UAP:

Añadimos las carpetas Views, ViewModels y Services además de las clases base necesarias para implementar el patrón MVVM de la misma forma que vimos en este artículo.

Nuestro objetivo será trabajar y modificar todas las opciones disponibles en la TitleBar. Veremos a continuación que para trabajar con ella accederemos utilizando ApplicationView.GetForCurrentView().TitleBar por lo que primero aprenderemos como trabajar con ella de forma simple desde code behind para posteriormente crearnos un Behavior y poder modificar sus propiedades directamente desde XAML.

Comenzamos creando nuestra interfaz:

<StackPanel
     HorizontalAlignment="Center"
     VerticalAlignment="Center">
     <Button Content="Use Code Behind"
             Click="CodeBehindClick"
             Margin="5"/>
     <Button Content="Use Behavior"
             Command="{Binding NavigateCommand}"
             Margin="5"/>
</StackPanel>

Muy simple. Contamos con dos botones. El primero de ellos modificará la apariencia de la TitleBar desde un evento en el code behind mientras que el segundo navegará a una nueva vista donde se modificará la apariencia de la TitleBar desde XAML utilizando un Behavior.

NOTA: La TitleBar muestra por defecto un color de fondo gris y los elementos con color negro.

El evento del primer botón:

private void CodeBehindClick(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
 
}  

Tendremos en la ViewModel el comando correspondiente al segundo botón:

private ICommand _navigateCommand;
       
public ICommand NavigateCommand
{
     get { return _navigateCommand = _navigateCommand ?? new DelegateCommand(NavigateCommandExecute); }
}
 
private void NavigateCommandExecute()
{
            
}  

Nos centramos en el evento del primer botón. Podemos modificar el texto
que aparece como título en la TitleBar de forma sencilla:

var applicationView = ApplicationView.GetForCurrentView();
 
// Title

applicationView.Title = "Changed basic TitleBar Information"

Utilizando el método GetForCurrentView de la clase ApplicationView obtenemos la instancia de la ventana correspondiente a la App. Esta instancia cuenta con una nueva propiedad llamada TitleBar que nos da acceso a la misma. Tenemos acceso a las siguientes propiedades básicas para modificar el aspecto:

  • BackgroundColor: Propiedad de tipo Color que define el color de fondo de la barra de título sin incluir el fondo de los botones.
  • ForegroundColor: Propiedad de tipo Color utilizada en el color del texto de título.
  • ButtonBackgroundColor: Propiedad de tipo Color para el fondo de la zona de botones en la parte derecha.
  • ButtonForegroundColor: Propiedad de tipo Color que define el color de los botones.
// Basic TitleBar Properties
var titleBar = applicationView.TitleBar;
titleBar.BackgroundColor = (Color)App.Current.Resources["RedColor"];
titleBar.ForegroundColor = (Color)App.Current.Resources["WhiteColor"];
titleBar.ButtonBackgroundColor = (Color)App.Current.Resources["BlueColor"];

titleBar.ButtonForegroundColor = (Color)App.Current.Resources["WhiteColor"];

Más alla de las propiedades de personalización básica que hemos utilizado, podemos modificar muchas otras como:

// Extra
titleBar.ButtonHoverBackgroundColor = Colors.Yellow;
titleBar.ButtonPressedBackgroundColor = Colors.Orange;

Donde:

  • ButtonHoverBackgroundColor: Propiedad de tipo Color que define el color de fondo del botón al pasar el ratón por encima.
  • ButtonPressedBackgroundColor: Propiedad de tipo Color  para el fondo del botón al ser pulsado.

Tenemos gran cantidad de propiedades para definir la apariencia visual en múltiples estados. Si ejecutamos la App:

Al pasar el ratón sobre cualquier botón de la TitleBar:

Pulsando sobre un botón:

Sencillo, ¿cierto?

Mejorando lo presente, utilizando Behavior

Como hemos podido ver hasta ahora:

  • La TitleBar define la cabecera de nuestra App incluyendo título y botones de gestión (minimizar, maximizar y cerrar).
  • Podemos personalizar el contenido del título.
  • Podemos personalizar totalmente la apariencia.

Sin embargo, en lo visto hasta ahora hacemos uso de code behind.

¿Cómo podemos personalizar la TitleBar directamente desde XAML?

Crearemos un Behavior para ello. Añadiremos la referencia a Extensions SDK:

En nuestro proyecto, dentro de la carpeta Behaviors, crearemos una nueva clase que heredará de IBehavior:

public class TitleBarBehavior : DependencyObject, IBehavior
{
     public DependencyObject AssociatedObject { get; private set; }
 
     public void Attach(DependencyObject associatedObject)
     {
         var titleBar = associatedObject as UIElement;
         if (titleBar == null)
             throw new ArgumentException(
                 "TitleBarBehavior can be attached only to UIElement!");
 
         Window.Current.SetTitleBar(titleBar);
 
         AssociatedObject = associatedObject;
     }
 
     public void Detach()
     {
         AssociatedObject = null;
     }
}

Realizamos la implementación de la interfaz IBehavior asociando el Behavior a un elemento UIElement. A continuación, crearemos propiedades de dependencia para modificar el contenido y aspecto de la TitleBar.

public Color BackgroundColor
{
     get { return (Color)GetValue(BackgroundColorProperty); }
     set { SetValue(BackgroundColorProperty, value); }
}
 
public static readonly DependencyProperty BackgroundColorProperty =
            DependencyProperty.Register("BackgroundColor",
            typeof(Color),
            typeof(TitleBarBehavior),
            new PropertyMetadata(false, OnBackgroundColorChanged));
 
private static void OnBackgroundColorChanged(DependencyObject d,
            DependencyPropertyChangedEventArgs e)
{
     var applicationView = ApplicationView.GetForCurrentView();
     applicationView.TitleBar.BackgroundColor = (Color)e.NewValue;
}
 
public string Title
{
     get { return (string)GetValue(TitleProperty); }
     set { SetValue(TitleProperty, value); }
}
 
public static readonly DependencyProperty TitleProperty =
            DependencyProperty.Register("Title",
            typeof(string),
            typeof(TitleBarBehavior),
            new PropertyMetadata(string.Empty, OnTitleChanged));
 
private static void OnTitleChanged(DependencyObject d,
            DependencyPropertyChangedEventArgs e)
{
     var applicationView = ApplicationView.GetForCurrentView();
     applicationView.Title = (string)e.NewValue;
}
 
public Color ForegroundColor
{
     get { return (Color)GetValue(ForegroundColorProperty); }
     set { SetValue(ForegroundColorProperty, value); }
}
 
public static readonly DependencyProperty ForegroundColorProperty =
            DependencyProperty.Register("ForegroundColor",
            typeof(Color),
            typeof(TitleBarBehavior),
            new PropertyMetadata(false, OnForegroundColorChanged));
 
private static void OnForegroundColorChanged(DependencyObject d,
            DependencyPropertyChangedEventArgs e)
{
     var applicationView = ApplicationView.GetForCurrentView();
     applicationView.TitleBar.ForegroundColor = (Color)e.NewValue;
}
 
public Color ButtonForegroundColor
{
     get { return (Color)GetValue(ButtonForegroundColorProperty); }
     set { SetValue(ButtonForegroundColorProperty, value); }
}
 
public static readonly DependencyProperty ButtonForegroundColorProperty =
            DependencyProperty.Register("ButtonForegroundColor",
            typeof(Color),
            typeof(TitleBarBehavior),
            new PropertyMetadata(false, OnButtonForegroundColorChanged));
 
private static void OnButtonForegroundColorChanged(DependencyObject d,
            DependencyPropertyChangedEventArgs e)
{
     var applicationView = ApplicationView.GetForCurrentView();
     applicationView.TitleBar.ButtonForegroundColor = (Color)e.NewValue;
}
 
public Color ButtonBackgroundColor
{
     get { return (Color)GetValue(ButtonBackgroundColorProperty); }
     set { SetValue(ButtonBackgroundColorProperty, value); }
}
 
public static readonly DependencyProperty ButtonBackgroundColorProperty =
            DependencyProperty.Register("ButtonBackgroundColor",
            typeof(Color),
            typeof(TitleBarBehavior),
            new PropertyMetadata(false, OnButtonBackgroundColorChanged));
 
private static void OnButtonBackgroundColorChanged(DependencyObject d,
            DependencyPropertyChangedEventArgs e)
{
     var applicationView = ApplicationView.GetForCurrentView();
     applicationView.TitleBar.ButtonBackgroundColor = (Color)e.NewValue;
}

Hemos definido propiedades para modificar:

  • Título.
  • Color de fondo de la zona del título.
  • Color del título.
  • Color de fondo de la zona de botones.
  • Color de los botones.

Solo nos queda utilizar el Behavior en nuestra interfaz de usuario. Añadimos los namespaces necesarios:

xmlns:i="using:Microsoft.Xaml.Interactivity"
xmlns:behaviors="using:TitleBar.Behaviors"

Utilizamos el Behavior en nuestra Vista bindeando las propiedades para modificar el título y colores de gestión de la TitleBar:

<i:Interaction.Behaviors>
     <behaviors:TitleBarBehavior
          Title="Changed from Behavior!"
          BackgroundColor="{StaticResource RedColor}"
          ForegroundColor="{StaticResource WhiteColor}"
          ButtonBackgroundColor="{StaticResource BlueColor}"
          ButtonForegroundColor="{StaticResource WhiteColor}"/>
</i:Interaction.Behaviors>

Navegando a la segunda vista:

Podéis descargar el ejemplo realizado a continuación:

También podéis acceder al código fuente directamente en GitHub:

Ver GitHub

En futuros artículos veremos otras posibilidades como inyectar contenido XAML o añadir un botón volver directamente en la TitleBar. Recordar que cualquier tipo de duda o sugerencia la podéis dejar en los comentarios de la entrada.

Más información

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *