2009-08-29 11 views
9

En el contexto de una aplicación WPF de estilo de navegación (NavigationWindow, no XBAP):Paso de parámetros a una WPF página a través de su URI

¿Es posible que NavigateUri de un hipervínculo a contener parámetros adicionales, como datos de la trayectoria o una querystring? Por ejemplo, ¿hay alguna manera de configurar mi NavigateUri en /Product.xaml/123 o /Product.xaml?id=123, y hacer que mi página Product.xaml pueda ver que se llamó con un parámetro de 123?

Respuesta

16

Puede hacerlo. Ver http://www.paulstovell.com/wpf-navigation:

Aunque no es obvio, puede datos de cadena consulta de paso a una página, y extraerlo de la ruta. Por ejemplo, el hipervínculo podría pasar un valor en el URI:

<TextBlock> 
    <Hyperlink NavigateUri="Page2.xaml?Message=Hello">Go to page 2</Hyperlink> 
</TextBlock> 

Cuando se carga la página, se puede extraer los parámetros a través de NavigationService.CurrentSource, que devuelve un objeto Uri. Puede entonces examinar el Uri para separar los valores . Sin embargo, recomiendo encarecidamente en contra de este enfoque, excepto en el más grave de las circunstancias.

Un enfoque mucho mejor implica el uso de la sobrecarga para NavigationService.Navigate que toma un objeto para el parámetro. Puede inicializar el objeto mismo, por ejemplo :

Customer selectedCustomer = (Customer)listBox.SelectedItem; 
this.NavigationService.Navigate(new CustomerDetailsPage(selectedCustomer)); 

Esto asume la página constructor recibe un objeto de cliente como parámetro . Esto le permite pasar información mucho más rica entre las páginas, y sin tener que analizar las cadenas.

+0

¿A dónde pertenece su llamada de NavigationService? En el controlador de clic del hipervínculo? Eso parece conducir a mucho cableado adicional en el código. – dthrasher

+0

Sí, de la misma manera que en ASP.NET MVC el código para representar un hipervínculo entra en la vista, no en el modelo/controlador. La navegación de la vista a la vista debe ser una preocupación de la vista. –

+0

En cierto modo, parece ASP.NET MVC: el "hipervínculo" estará en la vista, pero llamará a algo para realizar el cambio de página. Creé un controlador para hacer eso, con métodos estáticos y un objeto estático 'MainWindow', que contiene el marco que muestra todas mis páginas. Si quiero cambiar la página, simplemente llamo 'MainController.ChangePage (page)' y funciona. –

0
Customer selectedCustomer = (Customer)listBox.SelectedItem; 
this.NavigationService.Navigate(new CustomerDetailsPage(selectedCustomer)); 

Paul Stovell creo que el uso de su sugerencia hará que sus páginas no basura recogida porque toda la instancia permanecerá en Diario.

+0

La primera sugerencia permitirá la recolección. La segunda sugerencia aún se puede recopilar si llama a NavigationService.RemoveBackEntry suficientes veces para 'borrar' el diario. WPF Frame definitivamente apesta por esto: http://www.paulstovell.com/magellan-page-management –

0

Otra forma es crear una variable pública en la página de destino y usar una propiedad get/set para asignarle un valor.

En la página:

private Int32 pMyVar; 

public Int32 MyVar 
{ 
    get { return this.pMyVar; } 
    set { this.pMyVar = value; } 
} 

Cuando navegando hacia él:

MyPagePath.PageName NewPage = new MyPagePath.PageName(); 
NewPage.MyVar = 10; 

this.MainFrameName.NavigationService.Navigate(NewPage); 

Cuando se carga NewPage, la MiVar número entero será igual a 10. MainFrameName es el marco que está utilizando en el caso estás trabajando con frame, pero si no, el comando de navegación sigue siendo el mismo independientemente. Es mi opinión, pero parece más fácil rastrearlo de esa manera, y más fácil de usar para aquellos que vinieron de C# antes de WPF.

Cuestiones relacionadas