How to Navigate and Pass Values between Pages using Silverlight 2 Beta 2

Posted by: Suprotim Agarwal , on 6/25/2008, in Category Silverlight 2, 3, 4 and 5
Views: 87783
Abstract: While discussing Silverlight with one of my colleagues, he popped up a question. Can we navigate between pages using Silverlight? Honestly, I did not have an answer to it. But it did pep me up to explore and find an answer to that question. This article discusses how to do so.
How to Navigate and Pass Values between Pages using Silverlight 2 Beta 2
 
Note: This article is written based on a pre-release version of Silverlight and could change in future.
While discussing Silverlight with one of my colleagues, he popped up a question. Can we navigate between pages using Silverlight? Honestly, I did not have an answer to it. But it did pep me up to explore and find an answer to that question. This article discusses how to do so.
I would like to thank my colleague David who helped me with this method of navigating between pages in Silverlight 2. David got some ideas from a new book released by Matthew Macdonald on Silverlight 2 called ‘Silverlight Visual Essentials’.
If you are not familiar with hosting Silverlight 2 in ASP.NET, I hope you have read the previous article which talks about the prerequisites of creating Silverlight applications. The article can be found over here Hosting Silverlight Content in ASP.NET 3.5.
Context: In this article, we will create two pages: Page1.xaml and Page2.xaml and demonstrate navigation between the two. We will also demonstrate how to pass the value of the textbox kept on Page1.xaml to Page2.xaml.
Step 1: Open Visual Studio 2008 > File > New Project > Select the language (C# or VB) > Select ‘Silverlight’ in the Project Types > from the templates, select ‘Silverlight Application’. Type a name NavigatingBetweenPagesWeb (for VB.NET users - NavigatingBetweenPagesVBWeb) and location for the project and click ok.
Note: If you are unable to view the templates, you do not have Microsoft Silverlight Tools Beta 2 for Visual Studio 2008.
Step 2: You will see that there are two projects created. The project ‘NavigatingBetweenPages’ or ‘NavigatingBetweenPagesVB’ gets created with a default page called ‘Page.xaml’. Delete that Page. We will be adding two new pages to the project. To do so, right click the project > Add > New Item > Select Silverlight in the categories pane > ‘Silverlight User Control’ from the templates > Rename it to ‘Page1.xaml’ and click Add. Similarly repeat the steps and add Page2.xaml.
Note: A page in Silverlight 2 is a UserControl.
Step 3: Now open your App.xaml.cs or App.xaml.vb file and observe the contents. You will find an Application_Startup method:
C#
 private void Application_Startup(object sender, StartupEventArgs e)
 {
      this.RootVisual = new Page();
 }
VB.NET
 Private Sub Application_Startup(ByVal o As Object, ByVal e As StartupEventArgs) Handles Me.Startup
        Me.RootVisual = New Page()
    End Sub
Over here, the main application UI (Application.RootVisual) is set to an instance of the page. However, using this approach, it is not possible to change the main application UI later at runtime. What we need is a mechanism that lets us switch the UI to some other object at runtime. To do so, we will declare a container element and then set that container to be the main application UI. We will then add the Page (that we have to navigate to) as a child to the container element as shown below:
C#
Grid mainUI = new Grid();
private void Application_Startup(object sender, StartupEventArgs e)
{
        this.RootVisual = mainUI;
        mainUI.Children.Add(new Page1());
}
 
VB.NET
    Dim mainUI As Grid = New Grid()
   Private Sub Application_Startup(ByVal sender As Object, ByVal e As StartupEventArgs)
        Me.RootVisual = mainUI
        mainUI.Children.Add(New Page1())
    End Sub
I hope you get the idea behind the approach. Using this technique, you can add and remove new pages from the Grid (which is the rootvisual) anytime, thereby emulating a navigation. If you are not yet clear on why we chose this approach, I am sure you will be, by the end of this article. We will shortly see how to pass values between pages.
Step 4: In the beginning of the article, we had mentioned about passing the value from the textbox kept on Page1.xaml to Page2.xaml. App.xaml allows you to define global resources that are available to all the pages in the application. To pass the values between pages, we will use get/set properties in the App.xaml and then access these properties from the respective pages.
C#
        private string userName;
 
        public string UserName
        {
            get
            {
                return userName;
            }
            set
            {
                userName = value;
            }
        }
VB.NET
    Private userName_Renamed As String
 
    Public Property UserName() As String
        Get
            Return userName_Renamed
        End Get
        Set(ByVal value As String)
            userName_Renamed = value
        End Set
    End Property
As shown above, we have declared a property called userName (userName_Renamed in VB.NET). We will set the value of this property in Page1 and access it from Page2.
Step 5: Our next step is to add functionality to facilitate navigation between pages. In Step 3, I had mentioned that we will be setting the RootVisual to a container element, in our case Grid. We will now create a method that will manipulate the children of the Grid element at runtime. Add the following code to your App.xaml.cs or App.xaml.vb
C#
       public static void GoToPage(UserControl nextPg)
        {
            App app = (App)Application.Current;
            // Remove the displayed page
            app.mainUI.Children.Clear();
            // Show the next page
            app.mainUI.Children.Add(nextPg);
        }
VB.NET
    Public Sub GoToPage(ByVal nextPg As UserControl)
        Dim app As App = CType(Application.Current, App)
        ' Remove the displayed page
        app.mainUI.Children.Clear()
        ' Show the next page
        app.mainUI.Children.Add(nextPg)
    End Sub
In this method, we accept a UserControl (remember page is a usercontrol) and then set that UserControl to be the child of the Grid (mainUI). This way, we can emulate the navigation between different pages by adding and removing elements from the container representing the Main UI.
Step 6: Switch to Page1.xaml and add the xaml as shown below. The xaml creates a TextBox and a Button control. We will add functionality on the button click, which will help us navigate to the Page2 and also pass the value of the textbox to Page2 with the help of the property declared in the application file.
<UserControl x:Class="NavigatingBetweenPages.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="40"/>
            <RowDefinition Height="*"/>           
        </Grid.RowDefinitions>
        <TextBox x:Name="txtUser" Grid.Row="0" Background="AliceBlue" Height="50"></TextBox>
        <Button x:Name="btnPage2Go" Height="50" Grid.Row="1" Content="Go to Page 2" Click="btnPage2Go_Click"/>
    </Grid>
</UserControl>
 
Note: Creating events is quiet simple. For eg: To create the button click event, just type Click= to invoke the intellisense. You get the option of creating a ‘New Event Handler’ or use the default event handler, which is in the form of object_Click.
Step 7: We will now add functionality to the click event of the button
C#
      private void btnPage2Go_Click(object sender, RoutedEventArgs e)
        {
            if (txtUser.Text != String.Empty)
            {
                App app = (App)Application.Current;
                app.UserName = txtUser.Text;
                App.GoToPage(new Page2());
            }
        }
VB.NET
    Private Sub btnPage2Go_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        If txtUser.Text <> String.Empty Then
            Dim app As App = CType(Application.Current, App)
            app.UserName = txtUser.Text
            app.GoToPage(New Page2())
        End If
    End Sub
In the code above, we are referring to the application object by using the Application.Current property. To access properties (UserName) in the application class, we have to cast a reference to the App type as shown above. We then call the method GoToPage() and pass the instance of the new page, in our case Page2.
Step 8: The task that remains now, is to access the value of the textbox in the new page. Add the following xaml to the Page2. The xaml represents a textblock to display the value passed from Page1 and a button to go back to Page1.
<UserControl x:Class="NavigatingBetweenPages.Page2"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
        <TextBlock x:Name="lblDisplay" Text="Welcome"/>
        <Button Height="50" x:Name="btnPage1Go" Click="btnPage1Go_Click" Content="Go Back to Page1"></Button>
    </Grid>
</UserControl>
Step 9: Add the following code to the code behind of Page2.xaml
C#
    public partial class Page2 : UserControl
    {
        App app = null;
 
        public Page2()
        {
            InitializeComponent();
            app = (App)Application.Current;
            lblDisplay.Text = lblDisplay.Text + " " + app.UserName;
        }
 
      
        private void btnPage1Go_Click(object sender, RoutedEventArgs e)
        {           
            app.GoToPage(new Page1());
        }
    }
VB.NET
Partial Public Class Page2
    Inherits UserControl
 
    Private app As App = Nothing
 
    Public Sub New
        InitializeComponent()
        app = CType(Application.Current, App)
        lblDisplay.Text = lblDisplay.Text & " " & app.UserName
    End Sub
 
    Private Sub btnPage1Go_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        app.GoToPage(New Page1())
    End Sub
 
End Class
 
That’s it. You are all set to test out the functionality. Run the application. In the textbox on Page1, type your name and click the button. You will see that you have navigated to Page2 and the text has been transferred from Page1 to Page2.
The source code of the article can be found over here.
After I wrote this article, I came across a cool technique of navigating between pages shared in one of the blogs of Jesse Liberty. You can find the blog over here. I hope this article was useful and I thank you for viewing it.

This article has been editorially reviewed by Suprotim Agarwal.

Absolutely Awesome Book on C# and .NET

C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.

We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).

Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.

Click here to Explore the Table of Contents or Download Sample Chapters!

What Others Are Reading!
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+

Author
Suprotim Agarwal, MCSD, MCAD, MCDBA, MCSE, is the founder of DotNetCurry, DNC Magazine for Developers, SQLServerCurry and DevCurry. He has also authored a couple of books 51 Recipes using jQuery with ASP.NET Controls and The Absolutely Awesome jQuery CookBook.

Suprotim has received the prestigious Microsoft MVP award for Sixteen consecutive years. In a professional capacity, he is the CEO of A2Z Knowledge Visuals Pvt Ltd, a digital group that offers Digital Marketing and Branding services to businesses, both in a start-up and enterprise environment.

Get in touch with him on Twitter @suprotimagarwal or at LinkedIn



Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!
Comment posted by Fred on Sunday, July 13, 2008 8:55 AM
Hi
I try your sample and all is working perfect.
I add a listbox or DataGrid and try to switch from the SelectionChanged event. but in each case i obtain this error
An unhandled exception("Unhandled Error in Silverlight 2 Application Code:4004 Category ManagedRuntimeError Message: system.Argument exception: Value does not fall within the expected range)

did you try this case ?
I eant my first page contains a listBox and when the user is selecting a specific item switch to a new page.
Regards
Fred
Comment posted by Mike Crystal on Wednesday, August 13, 2008 12:38 PM
Your VB version download does not work!
Comment posted by Suprotim Agarwal on Wednesday, August 13, 2008 8:44 PM
Mike: Thanks. What is the error you get?
Comment posted by Nirav on Tuesday, August 19, 2008 2:14 AM
Hi Suprotim
Happy I-Day.Mike is absolutely write.Your C# version which i downloaded is wrkin nicely but when i tried same code convertin in VB I am gettin the error messsge as below.One more thing can i use hyperlink button for navition b/w pages or button are the only option.I am using VB so i will try to get the solution or wait till you reply.Thanks again.

System.Windows.Markup.XamlParseException occurred
  LineNumber=7
  LinePosition=100
  Message="AG_E_PARSER_BAD_PROPERTY_VALUE [Line: 7 Position: 100]"
  StackTrace:
       at System.Windows.Application.LoadComponent(Object component, Uri xamlUri)    at NavigationExample.page2.InitializeComponent()    at NavigationExample.page2..ctor()
  InnerException:
Comment posted by Nirav on Tuesday, August 19, 2008 5:13 AM
Hey I am sorry
At first i didnt noticed the VB project which was downloded with sample.But later I found it but it is not giving any output, i.e am getting blank page not any error.
Comment posted by Nirav on Tuesday, August 19, 2008 5:51 AM
Hey I am sorry
At first i didnt noticed the VB project which was downloded with sample.But later I found it but it is not giving any output, i.e am getting blank page not any error.
Comment posted by Suprotim Agarwal on Wednesday, August 20, 2008 1:40 PM
Nirav, Mark: Let me check the sample at my end and get back to you. Thanks.
Comment posted by Nirav on Thursday, August 21, 2008 1:51 AM
Hi Suprotim
I dont knw whts wrong wid ur sample but.I tried to follow your instructions in article and proceeded in same manner you described and guess what i succeded.Thanks for guiding me.
Comment posted by Nirav on Thursday, August 21, 2008 3:38 AM
Before you go through I would like to trouble you more I am really sorry for that.I am trying to add one class in my SL app.,in which I want to write each and every functions used thru out application.But while importing some of namespaces I am getting error.Can u tell me y it is so.Below are some

"Imports System.Web.HttpContext
Imports System.Data.SqlClient
Imports System.Drawing
Imports System.Drawing.Image
Imports System.Drawing.Imaging
Imports System.Net.Mail"
Comment posted by Suprotim Agarwal on Thursday, August 21, 2008 9:23 PM
Nirav: What is the error you get?
Comment posted by Nirav on Friday, August 22, 2008 5:42 AM
I had come to know that namespaces like "system.Net.Mail" are not allowed in SL for they are not in class libraries of SL.Can you now please tell me that what are substitute for it I am facing so many problems.Bcoz "..Net.Mail",".System.data" and others are important And almost neccesary namespaces.M i been misguided or wht i dont knw.
Comment posted by Suprotim Agarwal on Friday, August 22, 2008 6:06 AM
Nirav: You cannot do that directly from Silverligt. You will have to use a webservice to do so. Write a webservice that can send mail. Consume that webservice in Silverlight. The webservice can then be called asynchronously.
Comment posted by Nirav on Monday, August 25, 2008 2:22 AM
Thanks Suprotim
Comment posted by Mike on Monday, August 25, 2008 2:04 PM
How come I can not find any tutorials on naviagtion where one doesn't move between pages, rather a "master page" has a canvas control whereby the different Xaml pages are populated into depending on which nav buttonone presses? I think that is more of a real world app that completely switching pages.
Comment posted by Donavan on Wednesday, August 27, 2008 1:55 PM
I have a menu bar with links and a grid that will display each links' content (as children). Each content has a animation that changes the y value. How would one use your example to load each new content, since I am not loading a new page each time?
Comment posted by Daze55 on Tuesday, September 9, 2008 5:21 AM
It works but the only thing I can't understand is the reason of declaring an intermediate variable (UserName) in App.xaml.cs. Why not declare it directly on Page2.xaml.cs and retrieve it in the Loaded event handler of the grid.

On page1 in the btnPage2Go_Click method:
app.GoToPage(new Page2 {LabelText = txtUser.Text});

On page2 in the LayoutRoot_Loaded_1 method:
lblDisplay.Text = lblDisplay.Text + " " + LabelText;
Comment posted by Suprotim Agarwal on Tuesday, September 9, 2008 9:30 PM
Mike: That is because once you set the RootVisual, it is not possible to change the main application UI later at runtime. I have explained this point in this article.

Donavan: Still facing an issue? If you found a solution, please share it with the users here.

Daze55: Declaring a property in the App.xaml keeps it accessible in all the pages. The approach is neat and you do not need to pass in the value of txtUser everytime you call a new page.
Comment posted by Samuel on Tuesday, November 11, 2008 12:07 AM
Hi Suprotim, great article
Do you have another solution to this problem :
I create two asp.net we pages. Let say page1.aspx & page2.aspx Each page has a silverlight control. Each control should has own xaml. When i open the web pages, all controls refer to main xaml (usually page.xaml). How to redirect the control of the web page to its own xaml?

many-many thanks
Comment posted by Samuel on Tuesday, November 11, 2008 1:18 AM
Hi Suprotim, great article
Do you have another solution to this problem :
I create two asp.net we pages. Let say page1.aspx & page2.aspx Each page has a silverlight control. Each control should has own xaml. When i open the web pages, all controls refer to main xaml (usually page.xaml). How to redirect the control of the web page to its own xaml?

many-many thanks
Comment posted by Murali Krishna on Sunday, January 4, 2009 6:07 AM
Hi Supportim, Nice work
can u share the solution for my problem.
I have 3 silverlight pages page.xaml, banner.xaml and footer.xaml in a single web site. I want to place banner.xaml at website header and footer.xaml at website footer.How can we display these 2 silverlight contents in a single webpage by using html?  
<div id="header">
<asp:Silverlight id="xaml1" runat="server" source="~/ClientBin/SLApplication.xap" MinimumVersion="2.0" />
</div>
it displaying only header but not footer. Can u share the solution for this?

Thanks in advance
Murali
Comment posted by Suprotim Agarwal on Wednesday, January 7, 2009 7:20 AM
Murali: How have you written the footer code? You can use the ContactUs page to send an email with the code.
Comment posted by Arun on Monday, February 16, 2009 12:40 AM
Hi Murli,
You can add two silverlight user control(Silverlight Pages)into one .aspx page.Create two instace of the .xap file by passing parameter to the silverlight control....eg..

<div id="header">
<asp:Silverlight id="xaml1" runat="server" source="~/ClientBin/SLApplication.xap" MinimumVersion="2.0" InitParameters="PageName=banner" />
</div>

<div id="header">
<asp:Silverlight id="xaml1_1" runat="server" source="~/ClientBin/SLApplication.xap" MinimumVersion="2.0" InitParameters="PageName=footer" />
</div>

And in your app.xaml.cs file Application_Startup()event catch the parameter and display the pages. eg...

if (parameters["PageName"].ToString() == "banner")
            {
                this.RootVisual = new banner();
            }
            else if (parameters["PageName"].ToString() == "footer")
            {
                this.RootVisual = new footer();
            }          
Comment posted by Arun on Monday, February 16, 2009 12:47 AM
Hi Suprotim,

I am new to silverlight and facing one problem while passing data from one silver light control to another silverlight control resides in a singl;e .aspx page. i.e.
I have two .xaml page (page1 and page2 .xaml). I have two text boxes in page1.xaml page and one button and in page2.xaml page there are two text boxes. I am creating two instance in a single.aspx page (two silverlight control (page1 and page2) ina single table row but in two column) and its working fine. Now my question is I have entered value in text1 and text2 field in page1.xaml page and need to display that in page.xaml page. How..? and also if I want to get the entered value from page1.xaml into the .aspx page. How..

Thanks and Regards,
Arun
Comment posted by nacho on Wednesday, March 18, 2009 3:45 PM
Great article! it helped a LOT!
Comment posted by ScCrow on Monday, March 30, 2009 4:05 PM
VB note!  Using VB (VS 2008), you have to make your new sub Shared.  I dont know about the C# code.
Public Shared Sub GoToPage(ByVal nextPg As UserControl)
Comment posted by shanks on Wednesday, November 11, 2009 2:30 PM
hi,
i get this error on page2 on the app.GoToPage(new Page1()); line.

Member 'SilverlightApplication1.App.GoToPage(System.Windows.Controls.UserControl)' cannot be accessed with an instance reference; qualify it with a type name instead

wonder what that would be....
Comment posted by Hari on Wednesday, February 2, 2011 11:01 AM
The idea to store information by creating a Application level Property is awesome. Kudos and Thank You.
Comment posted by deepali on Wednesday, November 2, 2011 5:08 AM
how to pass data form page1 to page2,page3 without setting data