Framework de navegación

Framework de navegación

Para aplicaciones con distintas vistas tenemos diferentes opciones:

  1. Crear varios Estados Visuales por medio de Visual State Manager.
  2. Utilizar distintos controles de tipo UserControl e instanciarlo en un UserControl raíz, cargando de forma dinámica cada uno de ellos.
  3. Utilizar el Framework de Navegación.

La última opción es la más aconsejable ya que se trata de un conjunto de controles que nos permite tener un concepto de diferentes “páginas” dentro de una aplicación Silverlight, y cada una de esas páginas puede tener un Uri que las identifique.

Controles de navegación

  1. Contenedor de páginas
  2. Mecanismo de navegación

El proyecto debe contener el ensamblado (System.Windows.Controls.Navigation.dll) y espacio de nombres correspondiente.

Controles (se utilizan tanto en Windows Phone como en Silverlight):

  1. Frame
  2. Page

Veamos el código XAML de una aplicación con navegación.

 
<UserControl
    x:Class="SL_Navegacion1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation" 
    xmlns:uriMapper="clr-namespace:System.Windows.Navigation;assembly=System.Windows.Controls.Navigation"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">

    <Grid x:Name="LayoutRoot" Style="{StaticResource LayoutRootGridStyle}">

        <Border x:Name="ContentBorder" Style="{StaticResource ContentBorderStyle}">

            <navigation:Frame x:Name="ContentFrame" Style="{StaticResource ContentFrameStyle}" 
                              Source="/Home" Navigated="ContentFrame_Navigated" NavigationFailed="ContentFrame_NavigationFailed">
                <navigation:Frame.UriMapper>
                  <uriMapper:UriMapper>
                    <uriMapper:UriMapping Uri="" MappedUri="/Views/Home.xaml"/>
                    <uriMapper:UriMapping Uri="/{pageName}" MappedUri="/Views/{pageName}.xaml"/>
                  </uriMapper:UriMapper>
                </navigation:Frame.UriMapper>
            </navigation:Frame>
        </Border>

        <Grid x:Name="NavigationGrid" Style="{StaticResource NavigationGridStyle}">

            <Border x:Name="BrandingBorder" Style="{StaticResource BrandingBorderStyle}">
                <StackPanel x:Name="BrandingStackPanel" Style="{StaticResource BrandingStackPanelStyle}">

                    <ContentControl Style="{StaticResource LogoIcon}"/>
                    <TextBlock x:Name="ApplicationNameTextBlock" Style="{StaticResource ApplicationNameStyle}" 
                               Text="Nombre de la aplicación"/>

                </StackPanel>
            </Border>

            <Border x:Name="LinksBorder" Style="{StaticResource LinksBorderStyle}">
                <StackPanel x:Name="LinksStackPanel" Style="{StaticResource LinksStackPanelStyle}">

                    <HyperlinkButton x:Name="Link1" Style="{StaticResource LinkStyle}" 
                                     NavigateUri="/Home" TargetName="ContentFrame" Content="página principal"/>

                    <Rectangle x:Name="Divider1" Style="{StaticResource DividerStyle}"/>

                    <HyperlinkButton x:Name="Link2" Style="{StaticResource LinkStyle}" 
                                     NavigateUri="/About" TargetName="ContentFrame" Content="acerca de"/>

                </StackPanel>
            </Border>
        </Grid>
    </Grid>
</UserControl>

Frame

Es un control de contenido que permitirá la navegación entre las diferentes páginas. Su espacio de nombres es System.Windows.Controls.

Las propiedades y métodos más importantes son:

  • CurrentSource: propiedad que indica el Uri del contenido actual
  • CanGoBack / CanGoForward: propiedad que nos indica si el control Frame puede navegar hacia atrás o hacia delante. Este valor estará en función de si hay un Uri en el histórico de navegación en ambas direcciones.
  • GoBack / GoForward: métodos que nos permite navegar hacia atrás o hacia delante.
  • Navigate: método que nos permite navegar hacia la Uri especificado en el parámetro.
  • UriMapper: propiedad que nos permite conocer o establecer el objeto que nos servirá para mapear Uris dentro de nuestra aplicación.
  • CacheSize: El número de páginas que pueden ser cacheadas.
  • Refresh: método que recarga la página actual.

El control Frame NO tiene contenido, éste debe definirse a través de controles tipo Page.

Page

La clase Page esta disponible también en el espacio de nombres System.Windows.Control. Este componente cuenta con una plantilla que se agrega como “Nuevo elemento” y se añade como “Página Silverlight”.

Creación proyecto Silverlight de Navegación.

Aplicación básica: plantilla de navegación Silverlight

Agregar una nueva página que llamaremos MiNuevaPagina.xaml
<navigation:Page x:Class=”SL_navegacion.MiNuevapagina” …

Además de las propiedades y métodos de la clase base UserControl, la clase Page incluye diversos miembros:

  • NavigationCacheMode: propiedad que indica si la página será guardada en caché.
  • NavigationContext: propiedad que nos devuelve un objeto tipo NavigationContext, el cual nos da información sobre la petición de navegación.
  • NavigationService: propiedad que nos devuelve un objeto tipo NavigationService. Con este objeto podemos obtener la misma funcionalidad de navegación que encontramos en el control Frame, por lo que sería posible realizar navegación desde dentro de una página.
  • Title: propiedad para guardar el título de la página.
  • OnNavigatedTo: método que se invoca cuando la página se está cargando en el Frame. Este método se ejecuta incluso antes que el evento Loaded del UserControl.
  • OnNavigatedFrom: método que se invoca cuando la página ha sido descargada del Frame, Por ejemplo cuando estamos navegando hacia alguna otra página.

Cargando páginas en el Frame

 

Código creación botones de navegación.

        private void BtnMiPagina_Click(object sender, RoutedEventArgs e)
        {
            ContentFrame.Navigate(new Uri("/Views/MiPagina.xaml", UriKind.Relative));
        }

Contexto de navegación

Podemos obtener información acerca de la petición que se ha realizado. Por ejemplo si queremos pasar un parámetro Querystring.

Para esto utilizaremos la propiedad NavigationContext del objeto Page. Esta nos devolverá un objeto NavigationContext el cual contiene la propiedad Querystring (colección de todos los valores enviados).

Ejemplo:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;

namespace SL_navegacion2
{
    public partial class Page1 : Page
    {
        public Page1()
        {
            InitializeComponent();
        }

        // Se ejecuta cuando el usuario navega a esta página.
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            string nombre = string.Empty;
            string apellido = string.Empty;
            if (NavigationContext.QueryString.ContainsKey("nombre"))
            {
                nombre = NavigationContext.QueryString["nombre"];
            }
            if (NavigationContext.QueryString.ContainsKey("apellido"))
            {
                apellido = NavigationContext.QueryString["apellido"];
            }
            TxtBlock1.Text = string.Format("{0} {1}", nombre, apellido);
        }

    }
}

En este caso si llamamos a Pagina1.xaml?nombre=Pepito&apellido=López aparecerá en el TxtBlock1 el nombre y apellido.

Mapeo de Uris

Es posible controlar los Uri dentro del Frame, ya que incluye la propiedad UriMapper.

Esto nos permite mapear una Uri existente a una Uri más amigable. Como esta clase pertenece a otro espacio de nombres lo primero que tenemos que hacer es importar el espacio de nombres:

<UserControl x:Class="SL_navegacion2.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:navegacion="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation" 
    xmlns:mapeo="clr-namespace:System.Windows.Navigation;assembly=System.Windows.Controls.Navigation"
             mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="30" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <StackPanel Orientation="Horizontal">
            <Button Content="Página 1" x:Name="BtnPagina1"></Button>
            <Button Content="Página 2" x:Name="BtnPagina2"></Button>
        </StackPanel>
        <Border Margin="10" BorderBrush="Black" BorderThickness="2" Grid.Row="1">
            <navegacion:Frame x:Name="frame" Margin="30" Background="Aqua" Grid.Row="1">
                <navegacion:Frame.UriMapper>
                    <mapeo:UriMapper>
                        <mapeo:UriMapping Uri="/Discos/{valor}"
                                          MappedUri="/pagina2.xaml?banda={valor}">
                        </mapeo:UriMapping>                    
                    </mapeo:UriMapper>
                </navegacion:Frame.UriMapper>
            </navegacion:Frame>
        </Border>    
    </Grid>
</UserControl>

Conceptos avanzados.

Deja un comentario

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

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.