Passing parameters to a WPF Page via its Uri
Asked Answered
O

3

11

In the context of a navigation-style WPF application (NavigationWindow, not XBAP):

Is it possible for a Hyperlink's NavigateUri to contain extra parameters, like path data or a querystring? E.g., is there some way I could set my NavigateUri to /Product.xaml/123 or /Product.xaml?id=123, and have my Product.xaml page be able to see that it was called with a parameter of 123?

Outpost answered 29/8, 2009 at 14:20 Comment(0)
C
18

You can do this. See http://www.paulstovell.com/wpf-navigation:

Although it's not obvious, you can pass query string data to a page, and extract it from the path. For example, your hyperlink could pass a value in the URI:

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

When the page is loaded, it can extract the parameters via NavigationService.CurrentSource, which returns a Uri object. It can then examine the Uri to pull apart the values. However, I strongly recommend against this approach except in the most dire of circumstances.

A much better approach involves using the overload for NavigationService.Navigate that takes an object for the parameter. You can initialize the object yourself, for example:

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

This assumes the page constructor receives a Customer object as a parameter. This allows you to pass much richer information between pages, and without having to parse strings.

Creditor answered 9/10, 2009 at 15:39 Comment(4)
Where does your NavigationService call belong? In the click handler of the Hyperlink? That seems like it would lead to a lot of extra wiring in the code behind.Simp
Yes, in the same way that in ASP.NET MVC the code to render a hyperlink goes in the view, not the model/controller. Navigation from view to view should be a view concern.Creditor
In a way it looks like ASP.NET MVC: the "hyperlink" will be on the view, but it will call something to perform the page change. I created a controller to do that, with static methods and a static 'MainWindow' object, which contains the frame that displays all my pages. If I want to change the page, I simply call 'MainController.ChangePage(page)' and it works.Sunday
note that the official MSDN documentation suggests passing parameters in the URL: msdn.microsoft.com/en-us/library/ff626521(v=vs.92).aspx; also, the Naviagte method does not seem to take a page as argument, but only an URI objectZenaidazenana
P
0
Customer selectedCustomer = (Customer)listBox.SelectedItem; 
this.NavigationService.Navigate(new CustomerDetailsPage(selectedCustomer)); 

Paul Stovell I think that using your suggestion will make your pages not garbage collected because the whole instance will remain on Journal.

Perisarc answered 16/10, 2010 at 18:34 Comment(1)
The first suggestion will enable collection. The second suggestion can still be collected if you call NavigationService.RemoveBackEntry enough times to 'clear' the journal. WPF Frame definitely sucks for this though: paulstovell.com/magellan-page-managementCreditor
S
0

Another way is to create a public variable on the destiny page and use a get/set property to assign a value to it.

On Page:

private Int32 pMyVar;

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

When navigating to it:

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

this.MainFrameName.NavigationService.Navigate(NewPage);

When NewPage is loaded, the integer MyVar will be equal to 10. MainFrameName is the frame you are using in case you are working with frame, but if not, the navigate command remains the same regardless. Its my opinion, but it seems easier to track it that way, and more user friendly to those who came from C# before WPF.

Sanitize answered 8/10, 2012 at 18:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.