WPF provides support for browser style navigation inside standalone
application using Page class. User can create multiple pages, navigate between those pages along with data.There are multiple ways
available to Navigate through one page to another page.
Page can be implemented as root element in Xaml file and can contain single element similar to
window.
<Page x:Class="WpfApplication1.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Page1">
Welcome to WPF Page Navigation.
</Page>
Here you noticed that instead of Window element Page element is
the root element. Similar to normal xaml file you can specify page name StartupUrl inside App.xaml to open specific
page.
<Application x:Class="WpfApplication1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Page1.xaml">
</Application>
Navigate to another page
using hyperlink
The simplest way to navigate from one page to another page
is using hyperlink. Hyperlink requires two things one is the URL or page name to
navigate and another is content on which user can click and navigate to page. Let’s have a look on below code snippet.
Page1
<Page x:Class="WpfApplication1.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Page1">
<StackPanel>
<TextBlock>
Go to <Hyperlink NavigateUri="Page2.xaml"> Page 2 </Hyperlink>
</TextBlock>
</StackPanel>
</Page>
Page 2
<Page x:Class="WpfApplication1.Page2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Page2">
<StackPanel>
<TextBlock Margin="10">Welcome to Page2.</TextBlock>
<TextBlock Margin="10">
Go back to <Hyperlink NavigateUri="Page1.xaml"> Page 1 </Hyperlink>
</TextBlock>
</StackPanel>
</Page>
Navigate to page using Navigation Service
Alternatively you can use navigation service implemented
with Page class to navigate to another page. The navigate method of navigation
service enables the current page to be changed to another page. This method
accepts page name or URI.
<Page x:Class="WpfApplication1.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Page1">
<StackPanel>
<TextBlock Margin="10"> Welcome to Page 1.</TextBlock>
<TextBlock Margin="10">
Go to <Hyperlink Click="Hyperlink_Click"> Page 2 </Hyperlink>
</TextBlock>
</StackPanel>
</Page>
private void
Hyperlink_Click(object sender, RoutedEventArgs e)
{
Page2 p2 = new Page2();
this.NavigationService.Navigate(p2);
}
In above example, navigate method has been used to navigate
to page2. Navigation service is implemented in Page class by default. So In
above example instead of NavigateUri property of hyperlink click event is used
to navigate to page2.
You can also navigate to an external or internal page by
specifying URI in navigate method. The below line of code will open Google page.
this.NavigationService.Navigate(new Uri("http://www.google.com"));
Navigate to page using Journal
Journal keeps history of navigated page and user can also
navigate Back, Forward using journal. User can navigate journal using xaml code
as well code behind. Let’s have a look on below code.
<StackPanel>
<TextBlock Margin="10">
Navigate to <Hyperlink Command="BrowseBack">previous page. </Hyperlink>
</TextBlock>
<TextBlock Margin="10">
Navigate to <Hyperlink Command="BrowseForward">next page. </Hyperlink>
</TextBlock>
</StackPanel>
this.NavigationService.GoForward();
this.NavigationService.GoBack();
Navigating between pages inside Frame
Sometimes, application might not need whole page hosted as
navigation window but it requires some small part inside window, in such
cases we can use frame control to host page navigation framework. Frame class provides inbuilt support NavigationFramework. Let’s have a look on below code.
<StackPanel>
<TextBlock Margin="10">This is Main Window.</TextBlock>
<Frame Margin="10"
Source="Page1.xaml"
JournalOwnership="OwnsJournal"></Frame>
</StackPanel>
Above example demonstrate frame control which contains Page.
Frame control is capable to hold page and it also support navigation. Frame
also maintains its own journal if JournalOwnership property of Frame control set to
“OwnsJournal”. If you specify “UsesParentJournal” then it will use parent
page’s journal.
Passing data between pages
There are multiple ways available to pass data between pages
using page navigation. The simplest and easiest way to pass data between pages using page's constructor.
Page2 p2 = new Page2("This is
Page2");
this.NavigationService.Navigate(p2);
public Page2(string
message)
{
Console.WriteLine(message);
}
Another way to pass data is you can send extra data with
Navigate method of NavigationService and get extra data on target page.
Page1
private void
Hyperlink_Click(object sender, RoutedEventArgs e)
{
Page2 p2 = new Page2();
this.NavigationService.Navigate(p2,10);
}
Page2
void Page2_Loaded(object
sender, RoutedEventArgs e)
{
NavigationService
ns = this.NavigationService;
if (this.NavigationService != null)
this.NavigationService.LoadCompleted
+= new LoadCompletedEventHandler(NavigationService_LoadCompleted);
}
void NavigationService_LoadCompleted(object sender, NavigationEventArgs e)
{
if
(e.ExtraData != null)
Console.WriteLine(e.ExtraData);
}
In above example, data has been pass to Navigate method on
page 1 and the same handled and retrieved on page 2 using NaivgationService’s
LoadCompleted method.
Another way to keep data shred across multiple pages is
using Application object’s property collection which stores data shared across
pages.
Page1
Page2 p2 = new Page2();
Application app = Application.Current;
app.Properties["PageData"]
= 10;
this.NavigationService.Navigate(p2);
Page2
Application app = Application.Current;
if (app.Properties["PageData"]
!= null)
Console.WriteLine(app.Properties["PageData"].ToString());
Returning data back from page with PageFunction
Sometimes you might require some user input for particular
action so to achieve that you might need to create one user input page and return
data. But WPF has inbuilt facility to do the same using PageFunction. PageFunction is special class which allows user to return data back
to caller page.
Let’s have a look on below code to get some more idea on
PageFunction class.
Page1
XAML
<Page x:Class="WpfApplication1.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Page1">
<StackPanel>
<TextBlock Margin="10"> Welcome to Page 1.</TextBlock>
<TextBlock Margin="10">
Go to <Hyperlink Click="Hyperlink_Click"> data entry page </Hyperlink>
</TextBlock>
<TextBlock Name="lblName" Margin="10"></TextBlock>
</StackPanel>
</Page>
Code
private void
Hyperlink_Click(object sender, RoutedEventArgs e)
{
DataEntryPage userInputPage = new DataEntryPage();
userInputPage.Return += new ReturnEventHandler<string>(userInputPage_Return);
NavigationService.Navigate(userInputPage);
}
void userInputPage_Return(object
sender, ReturnEventArgs<string> e)
{
lblName.Text = string.Format("Your name is {0}", e.Result);
}
Data Entry Page
XAML
<PageFunction
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
x:Class="WpfApplication1.DataEntryPage"
x:TypeArguments="sys:String"
Title="DataEntryPage">
<StackPanel>
<TextBlock Margin="10">Welcome to Data
Entry Page.</TextBlock>
<WrapPanel>
<TextBlock Margin="10">Enter
your Name:</TextBlock>
<TextBox Name="txtName" Height="25" Width="150" />
</WrapPanel>
<TextBlock Margin="10">
Return back to <Hyperlink Click="Hyperlink_Click"> Page 1 </Hyperlink>
</TextBlock>
</StackPanel>
</PageFunction>
Code
public partial class DataEntryPage
: PageFunction<String>
{
public DataEntryPage()
{
InitializeComponent();
}
private void
Hyperlink_Click(object sender, RoutedEventArgs e)
{
OnReturn(new
ReturnEventArgs<string>(txtName.Text));
}
}
Output
Page1
Data Entry Page
Return Back to Page1 with Data
As per above output, When
user clicks on goto data entry page link from page1 it will redirect to data entry
page. User enters name in textbox and clicks on return back to page1 hyperlink
it will redirect back to Page1 with entered name.
So Data entry page implements PageFunction class which is
generic type where the type argument represents return type.
public partial class DataEntryPage
: PageFunction<String>
<PageFunction
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
x:Class="WpfApplication1.DataEntryPage"
x:TypeArguments="sys:String"
Title="DataEntryPage">
</PageFunction>
OnReturn method of PageFunction class automatically returns
the data or value to the caller page. In above example it will redirect back to
Page1 with data.
private void
Hyperlink_Click(object sender, RoutedEventArgs e)
{
OnReturn(new ReturnEventArgs<string>(txtName.Text));
}
On caller page, we need to handle the return value coming from data
entry page. For that we need to register and handle return event. Return value
can be retrieved from e.Result property.
void userInputPage_Return(object
sender, ReturnEventArgs<string> e)
{
lblName.Text = string.Format("Your name is {0}", e.Result);
}
See Also –
Thank you very much, it's very usefull and interesting article.
ReplyDeleteCould you tell how to close Page? I'd like to place button on Page and close Page by button's click.
ReplyDelete