davidpoll.com
Entradas con la etiqueta vínculos relativos
Los hipervínculos relativos a la navegación Silverlight
Publicado por david.poll en Silverlight el 20 de septiembre 2009
Si usted no ha notado ya, A mí me gusta la función de navegación en Silverlight un poco (me pregunto por qué?
). En mi otros mensajes para la Navegación , he pasado algún tiempo estudiando cómo se puede navegar a las páginas en las asambleas que no sea el ensamblado de la aplicación principal y cómo esas asambleas se puede cargar a la carta (concedida, utiliza algunas soluciones, pero se nos hacia dónde queremos ir!).
Todo esto está muy bien, pero que presenta un molesto problema que afecta a la capacidad de mantenimiento de dicho código. En concreto, se obliga a que cada hipervínculo en cada una de las asambleas externa para saber cómo hacer referencia a su asamblea por su nombre (esto es similar al problema con las direcciones URL absolutas en los hipervínculos en páginas web - las conexiones se hacen bien acoplados a la página para el que fueron creados, y no puede ser copiado en otros proyectos).
Técnicamente, casi todas las URIs que se usan en el marco de navegación de hoy son las URIs relativas (a menos que UriMappings se utilizan para activar los absolutos en los relativos), pero son de aplicación en relación y nunca la página-relativa. Esto significa que si usted tiene una página " / Views/Page1.xaml "y desea establecer un vínculo a otra página en" / Views/Page2.xaml "desde dentro Página1, debe hacer referencia a la ruta completa (" / Views/Page2.xaml ") y no sólo la ruta de acceso relativa a la otra página (por ejemplo, "Page2.xaml" o "./Page2.xaml").
En este post, veremos una manera de permitir la navegación en páginas relativas dentro de sus páginas de Silverlight. La aproximación que vamos a usar se aprovechan de la interfaz INavigate que se ha añadido en Silverlight 3 y el control HyperlinkButton que utiliza esta interfaz para realiza una exploración cuando se hace clic.
La interfaz INavigate tiene este aspecto:
public interface INavigate ( / / Métodos source); bool Navegar (Uri fuente); )
Es una interfaz sencilla con un simple propósito: permitir que un componente para proporcionar una forma de manejar la navegación a un Uri. En este momento, el único componente incorporado en Silverlight que en realidad se aprovecha de ella es el control HyperlinkButton. Usamos este control muy a menudo en Navegación aplicaciones habilitadas, ya que nos permite apuntar un control de marco especial para navegar a una página de Uri. En el proyecto de plantilla de aplicación de Silverlight de navegación, verá XAML como esto:
: Frame x : Name =" ContentFrame " Style ="{ StaticResource ContentFrameStyle }" Source ="/Home" Navigated ="ContentFrame_Navigated" NavigationFailed ="ContentFrame_NavigationFailed"> </ navigation : Frame > <Navegación: Marco x: Nombre = "ContentFrame" Style = "() StaticResource ContentFrameStyle" Source = "/ home" Navigated = "ContentFrame_Navigated" NavigationFailed = "ContentFrame_NavigationFailed"> </ navegación: Marco>
x : Name ="Link2" Style ="{ StaticResource LinkStyle }" NavigateUri ="/About" TargetName ="ContentFrame " Content ="about"/> <HyperlinkButton x: Nombre = "Link2" Style = "() StaticResource LinkStyle" NavigateUri = "/ Acerca de" TargetName = "ContentFrame" content = "sobre" />
Todo esto funciona porque el control Frame implementa INavigate. En otras palabras, no hay magia allí - se puede usar también! Aquí está la forma en que el HyperlinkButton funciona cuando estás intentando apuntar un INavigate (aproximadamente
):
- Para cada uno de los padres FrameworkElement ascensión en el árbol visual de la HyperlinkButton ...
- Compruebe si el FrameworkElement es un INavigate y que su nombre coincide con TargetName (ignorado si TargetName es nulo o vacío)
- Si es así, llame a INavigate.Navigate () en el FrameworkElement
- De lo contrario, la búsqueda de una forma recursiva INavigate que es el nombre correcto en cada uno de los hijos de la FrameworkElement
- Si no hay nombre adecuado INavigate se encontró, seguir subiendo el árbol visual
- Compruebe si el FrameworkElement es un INavigate y que su nombre coincide con TargetName (ignorado si TargetName es nulo o vacío)
En otras palabras, el HyperlinkButton buscará su camino hacia arriba y abajo del árbol visual (técnicamente hacer una búsqueda pre-orden en amplitud de cada padre de la HyperlinkButton, escala posiciones en el árbol visual) de una adecuada INavigate llamar.
Así que, ¿qué significa todo esto INavigate para mí?
Con ese detalle técnico fuera del camino, la pregunta que surge es: ¿cómo podemos utilizar esta página para habilitar la exploración-familiar? Bueno, la navegación debido a un marco de obras dentro de las páginas de hoy se debe a que el control Frame implementa INavigate, y la HyperlinkButton se abre camino en el árbol visual hasta que lo considere.
Para nuestros propósitos, esto es genial, ya que significa que puede interceptar la llamada a INavigate.Navigate () mediante la implementación de la interfaz en algún lugar entre la HyperlinkButton y el marco. Hay un lugar conveniente para ello, ya que las aplicaciones que utilizan la página / Frame y HyperlinkButtons dentro de esas páginas tienen un árbol visual de esta manera:
- Aplicación
- Disposición
- Marco
- Página
- HyperlinkButton
- Otros controles
- Página
- Otros controles
- Marco
- Disposición
Lo que estoy sugiriendo es que la página que vaya a aplicar INavigate y girar a la página de Uri relativa a la aplicación de Uri relativa antes de entregarlos fuera de la NavigationService (o el Marco) para llevar a cabo efectivamente la navegación.
He ido por delante y ampliado mi biblioteca DynamicNavigation hacer DynamicPage aplicar INavigate para hacer lo que quiera, pero usted podría hacer lo mismo en cualquier subclase de la página (incluyendo cada una de sus páginas si no quería que una clase base común) . Aquí está mi aplicación simple (con un interruptor para apagar esta función en DynamicPages):
{ return ( bool )GetValue(RelativeLinksProperty); } set { SetValue(RelativeLinksProperty, value ); } } public static readonly DependencyProperty RelativeLinksProperty = DependencyProperty .Register( "RelativeLinks" , typeof ( bool ), typeof ( DynamicPage ), new PropertyMetadata ( true )); private static readonly Uri basePlaceHolderUri = new Uri ( "none:///" , UriKind .Absolute); #region INavigate Members public bool Navigate( Uri navigateUri) { string original = navigateUri.OriginalString; if (RelativeLinks && !navigateUri.IsAbsoluteUri && !original.StartsWith( "/" )) { Uri result; if (NavigationService.CurrentSource.IsAbsoluteUri) { result = new Uri (NavigationService.CurrentSource, navigateUri); } else { Uri baseUri = new Uri (basePlaceHolderUri, NavigationService.CurrentSource); result = new Uri ( "/" + basePlaceHolderUri.MakeRelativeUri( new Uri (baseUri, navigateUri)).OriginalString, UriKind .Relative); } return NavigationService.Navigate(result); } else { return NavigationService.Navigate(navigateUri); } } #endregion pública RelativeLinks bool (obtener (return (int) GetValue (RelativeLinksProperty);) set (SetValue (RelativeLinksProperty, valor);)) public static readonly DependencyProperty RelativeLinksProperty = DependencyProperty. Registro ("RelativeLinks", typeof (int), typeof (DynamicPage) , los nuevos PropertyMetadata (true)); privada estática de sólo lectura Uri Uri nueva basePlaceHolderUri = (":///" ninguno, UriKind. Absoluto); # region INavigate Miembros público bool Navegar (Uri NavigateUri) (cadena original navigateUri.OriginalString =, si (RelativeLinks & &! navigateUri.IsAbsoluteUri & &! original.StartsWith ("/")) (resultado Uri, si (NavigationService.CurrentSource.IsAbsoluteUri) (resultado = nuevo Uri (NavigationService.CurrentSource, NavigateUri);) else (Uri baseURI = nuevo Uri (basePlaceHolderUri, NavigationService.CurrentSource); resultado = nuevo Uri ("/" + basePlaceHolderUri.MakeRelativeUri (nuevo Uri (baseURI, NavigateUri)). OriginalString, UriKind. Relativa);) return NavigationService.Navigate (resultado);) else ( volver NavigationService.Navigate (NavigateUri);)) # endregion
Ahora, dentro de la página, puede utilizar la página-URI relativo en HyperlinkButtons. Todo lo que necesitas hacer es evitar el establecimiento de un TargetName (ya sea a través de un estilo o directamente en el HyperlinkButton), y la página se encargará de la navegación!
Page-URI relativo se puede tomar una variedad de formas. Suponiendo que la página que estás es en "/ MyLibrary;" component/Views/Main/Page1.xaml, las siguientes transformaciones se producen (como ejemplo):
- "Page2.xaml" -> "/ MyLibrary; component/Views/Main/Page2.xaml"
- "./Page2.xaml" -> "/ MyLibrary; component/Views/Main/Page2.xaml"
- "../Page3.xaml" -> "/ MyLibrary; component/Views/Page3.xaml"
- "../Secondary/Page3.xaml" -> "/ MyLibrary; component/Views/Secondary/Page3.xaml"
- "../../ BasePage.xaml "->" / MyLibrary; componente / BasePage.xaml "
- "SubMain/Page4.xaml" -> "/ MyLibrary; component/Views/Main/SubMain/Page4.xaml"
- "SubMain/Page4.xaml? A = b + c = d" -> "/ MyLibrary; component/Views/Main/SubMain/Page4.xaml? A = b + c = d"
- "/ MyLibrary; component/Views/Main/Page5.xaml" -> "/ MyLibrary; component/Views/Main/Page5.xaml" (sin cambios)
Cool! ¿Puedo verlo en acción?
¡Por supuesto!
Como siempre, usted puede jugar con una aplicación en ejecución que hace esto aquí:
Haga clic en el enlace situado en la parte inferior de esa página para una navegación peform relativa que se deben tomar en un viaje entre un número de páginas - todo lo cual navegar usando la navegación relativa.
Para referencia, aquí está la estructura de archivos para la aplicación de ejemplo.

Entonces, ¿cuál es su punto?
Bueno, para resumir - ser capaz de hacer aumentos de navegación de la página-relativa a la portabilidad de sus páginas. Es especialmente útil si se usa en conjunción con UriMapping. Con la técnica anterior, el "relativismo" se refiere a la facilidad de uso frente a Uri. Esto significa que usted puede crear UriMappings a fin de crear un "virtual" de la estructura de archivos, y todos los vínculos relativa debe seguir trabajando (y otros nuevos puede ser posible!). Darle un tiro y me dejó saber lo que lo que piensa! Sigo a experimentar con la navegación, siempre en busca de cosas que pueden mejorar la experiencia al trabajar con ella.
¡Ya basta! Dame la mercancía!
Paciencia! Usted realmente no pensaba que me iría el colgar, ¿verdad? Aquí van:
- bibliotecas DynamicNavigation (ver mis otros puestos para una introducción a lo que ofrece y cómo usarlo - 1 , 2 )
- Fuente de ejemplo
Deja de hablar para sí mismo!
Está bien. ![]()
Navegación dinámica , de navegación , vínculos relativos , Silverlight , Silverlight 3
Personas que conozco
Mensajes recientes
- Para XAML, con amor (un experimento con la serialización XAML en Silverlight)
- Teniendo Microsoft Silverlight 4 aplicaciones más allá del navegador (TechEd WEB313)
- Común de navegación de interfaz de usuario y autorización impulsada por sitemaps
- Las muestras y el código de actualización en los comentarios
- A "refrescante" de autenticación / autorización de experiencia con Silverlight 4
- Hacer más fácil la impresión de Silverlight 4
- Silverlight 4 Fecha de lanzamiento!
- Nuevo en el Silverlight 4 RC: Características XAML
Etiquetas
. NET Servicios RIA Actividad de Control de Autorización de Mezcla BusyIndicator CollectionView ContentLoader controles de enlace de datos dinámicos de navegación Diversión Código Konami tala MIX '10 navegación Off-Topic Fuera del navegador PDC PDC09 Personal Impresión Proyectos relativos Enlaces servidor Silverlight Silverlight 3 Silverlight 3 Beta 4 Silverlight Silverlight 4 Beta de Silverlight 4 RC de Silverlight y más allá (losa) Silverlight Toolkit Mapa del sitio TechEd TechEd de Norteamérica 2010 Aplicaciones de confianza de validación de Visual Studio 2010 Servicios RIA WCF XAML XamlSerializerTwitter: @ depoll
- @ JeffHandley considera usted globalizado. ;) 13 de agosto 2010 08:30
- rburger @ Es un coro increíble - bien vale la pena echar un vistazo si están cerca de 06 de agosto 2010 04:54
- @ Rburger Han sido campeones internacionales tiempo después de un tiempo (que se molestaron el año pasado - por primera vez en 30 años que no ganó) 06 de agosto 2010 04:53
Silverlight Otras entradas del blog - Carga de un archivo XML estático a su Windows Phone / Silverlight aplicación 27 de agosto 2010
- Puesto temporal usado para el tema de detección (9ce8ce41-59b5-4f6e-b7e6-b485f01bc218 - 3bfe001a-32de-4114-a6b4-4005b770f6d7) 27 de agosto 2010
- Aplicar y personalizar los nuevos temas de Silverlight 27 de agosto 2010
Renuncia
El contenido de este sitio representa mis propias opiniones personales y pensamientos en el momento del anuncio, y no reflejan las de mi empleador de ninguna manera.











