2009-08-29 10 views
9

Dans le cadre d'une application WPF de style de navigation (NavigationWindow, non XBAP):Passer des paramètres à une WPF page via son Uri

Est-il possible pour NavigateUri d'un lien hypertexte pour contenir des paramètres supplémentaires, comme les données de chemin ou d'une chaîne de requête? Par exemple, est-il possible de configurer mon NavigateUri sur /Product.xaml/123 ou /Product.xaml?id=123, et d'avoir ma page Product.xaml capable de voir qu'elle a été appelée avec un paramètre de 123?

Répondre

16

Vous pouvez le faire. Voir http://www.paulstovell.com/wpf-navigation:

Bien qu'il soit pas évident, vous pouvez passe les données de chaîne de requête à une page, et extraire du chemin. Par exemple, votre lien hypertexte pourrait passer une valeur dans l'URI:

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

Lorsque la page est chargée, il peut extraire les paramètres via NavigationService.CurrentSource, qui retourne un objet Uri. Il peut alors examiner l'Uri pour séparer les valeurs . Cependant, je recommande fortement contre cette approche, sauf dans le la plus grave des circonstances.

Une approche beaucoup mieux consiste à utiliser la surcharge pour NavigationService.Navigate qui prend un objet pour le paramètre. Vous pouvez initialiser l'objet vous-même, pour exemple:

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

Cela suppose que le constructeur de la page reçoit un objet client comme paramètre . Cela vous permet de passer des informations beaucoup plus riches entre les pages, et sans avoir à analyser les chaînes.

+0

D'où vient votre appel NavigationService? Dans le gestionnaire de clic de l'hyperlien? Cela semble conduire à beaucoup de câblage supplémentaire dans le code derrière. – dthrasher

+0

Oui, de la même manière que dans ASP.NET MVC le code pour rendre un lien hypertexte va dans la vue, pas le modèle/contrôleur. La navigation de la vue à la vue devrait être une préoccupation de vue. –

+0

D'une certaine manière, il ressemble à ASP.NET MVC: le "lien hypertexte" sera sur la vue, mais il appellera quelque chose pour effectuer le changement de page. J'ai créé un contrôleur pour le faire, avec des méthodes statiques et un objet 'MainWindow' statique, qui contient le cadre qui affiche toutes mes pages. Si je veux changer la page, j'appelle simplement 'MainController.ChangePage (page)' et cela fonctionne. –

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

Paul Stovell Je pense que l'utilisation de votre suggestion fera vos pages ne ramasse-miettes car l'instance entière restera sur Journal.

+0

La première suggestion activera la collection. La seconde suggestion peut toujours être collectée si vous appelez NavigationService.RemoveBackEntry suffisamment de fois pour «effacer» le journal. WPF Frame est vraiment nul pour ça: http://www.paulstovell.com/magellan-page-management –

0

Une autre méthode consiste à créer une variable publique sur la page destinée et à utiliser une propriété get/set pour lui affecter une valeur.

Sur la page:

private Int32 pMyVar; 

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

Lorsque vous naviguez vers elle:

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

this.MainFrameName.NavigationService.Navigate(NewPage); 

Lorsque NewPage est chargé, le MaVar entier sera égal à 10. MainFrameName est le cadre que vous utilisez dans le cas vous travaillez avec frame, mais si ce n'est pas le cas, la commande navigate reste la même. C'est mon avis, mais il semble plus facile de le suivre de cette façon, et plus convivial pour ceux qui sont venus de C# avant WPF.

Questions connexes