Windows Phone–Sending Messages Between Pages

Windows Phone Tutorials

Last week I began work on prototyping a new application as part of the Full Stack series. PassingDataToPage1  In this application I would like to open a dialog box, retrieve some information from the user, and return that information to the calling page.

There is a dialog box in Windows Phone (System.Windows.MessageBox) but unfortunately it cannot retrieve data entered by the user. No problem, I’ll create a new page, put in a label and a textBox and two buttons (OK and Cancel).  The only issue is how do I get the data entered on page 2 back to page 1 (the calling page)?

The answer is to use the NavigationService.Navigate method to add the data in page 2, and the  NavigationContext.QueryString property to retrieve the data in page 1.  Let’s create a small sample to see this at work.

To begin, open a new Windows Phone application and in MainPage.xaml add two rows. Add a Button to the first row and a TextBlock in the second row.  The content for the Button is Retrieve Data From User and the TextBlock should have nothing (i.e., an empty string) in the Text property for now.  Set the PageTitle to Page 1,

 <StackPanel
     x:Name="TitlePanel"
     Grid.Row="0"
     Margin="12,17,0,28">
     <TextBlock
         x:Name="ApplicationTitle"
         Text="Sending Messages"
         Style="{StaticResource PhoneTextNormalStyle}" />
     <TextBlock
         x:Name="PageTitle"
         Text="Page 1"
         Margin="9,-7,0,0"
         Style="{StaticResource PhoneTextTitle1Style}" />
 </StackPanel>

 <Grid
     x:Name="ContentPanel"
     Grid.Row="1"
     Margin="12,0,12,0">
     <Grid.RowDefinitions>
         <RowDefinition
             Height="1*" />
         <RowDefinition
             Height="1*" />
         <RowDefinition
             Height="4*" />
     </Grid.RowDefinitions>
     <Button
         Name="RetrieveData"
         Content="Retrieve Data From User"
         Width="400"
         Grid.Row="0" />
     <TextBlock
         Text=""
         Name="DisplayText"
         Grid.Row ="1" />
 </Grid>

Create a second Windows Page. Set its PageTitle to Page 2.  Add two rows and two columns.  In the first row add a TextBlock whose text is Enter Data, and in the second column, a TextBox named Entered Data.  In the second row add a StackPanel and within the panel two Buttons whose content are OK and Cancel respectively.

<Grid
    x:Name="ContentPanel"
    Grid.Row="1"
    Margin="12,0,12,0">
    <Grid.ColumnDefinitions>
        <ColumnDefinition
            Width="124*" />
        <ColumnDefinition
            Width="332*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition
            Height="1*" />
        <RowDefinition
            Height="1*" />
        <RowDefinition
            Height="4*" />
    </Grid.RowDefinitions>
    <TextBlock
        Height="30"
        HorizontalAlignment="Left"
        Text="Enter Data"
        VerticalAlignment="Bottom" />
    <TextBox
        Name="DataEntered"
        HorizontalAlignment="Left"
        VerticalAlignment="Bottom"
        Width="300"
        Grid.Column="1" />
    <StackPanel
        HorizontalAlignment="Stretch"
        VerticalAlignment="Stretch"
        Grid.Row="1"
        Grid.Column="1"
        Orientation="Horizontal">
        <Button
            Name="OK"
            Content="OK"
            Width="150"
            Margin="5" />
        <Button
            Name="Cancel"
            Content="Cancel"
            Width="150"
            Margin="5" />
    </StackPanel>
</Grid>

 

In MainPage.xaml.cs create the event handler for the RetrieveData button. The job of this event handler is to navigate to Page 2.  (No data is passed from MainPage to Page 2).

public MainPage()
{
    InitializeComponent();
    RetrieveData.Click += ( RetrieveData_Click );
}

void RetrieveData_Click( object sender, RoutedEventArgs e )
{
    NavigationService.Navigate( 
       new Uri( "/Page2.xaml", UriKind.Relative ) );
}

 

Open Page2.xaml.cs and let’s add the logic for passing the user’s entry to MainPage.xaml.cs.  To do this we want to respond to either the OK or the Cancel Button, but only if the user clicks OK will we pick up the data in the TextBox.  Begin by creating a unified event handler for the two buttons,

public Page2()
{
    InitializeComponent();
    OK.Click += ButtonClick;
    Cancel.Click += ButtonClick;
}

The implementation of the click event handler needs to differentiate which button called it, and thus must cast the sender object to an object of type Button (which is what it will really be). Once we have a button we can ask for the Name or Content property to see which button called the handler.  If it is OK we can then retrieve the Text property from the TextBox and pass it to Page 1. In either case, we’ll navigate to Page 1. 

void ButtonClick( object sender, RoutedEventArgs e )
{
    Button btn = sender as Button;
    string msg = string.Empty;
    if (btn.Name == "OK")
    {
        msg = DataEntered.Text;
    }
    NavigationService.Navigate( 
        new Uri( "/MainPage.xaml?DataEntered=" + msg, 
            UriKind.Relative ) );
}

The string following the question mark will be passed back to MainPage.xaml in the NavigationContext’s QueryString property.

Return to MainPage.xaml and add an override of the OnNavigatedTo method. In that method you’ll retrieve the QueryString if it exists and add the string retrieved to the TextBlock. 

protected override void OnNavigatedTo( 
    System.Windows.Navigation.NavigationEventArgs e )
{
    string newText = string.Empty;
    if (NavigationContext.QueryString.TryGetValue( 
        "DataEntered", 
        out newText ))
    {
        DisplayText.Text = newText;
    }
    base.OnNavigatedTo( e );
}

 

Note, by the way, that you could use a Border on Page 1 and animate it so that it grows into place and then shrinks away, giving you more of the Dialog Box experience. I’ll cover that approach in an upcoming posting. 

Share

About Jesse Liberty

Jesse Liberty is an independent consultant and programmer with three decades of experience writing and delivering software projects. He is the author of 2 dozen books and multiple Pluralsight courses, and has been a Senior Technical Evangelist for Microsoft, a Distinguished Software Engineer for AT&T, a VP for Information Services for Citibank and a Software Architect for PBS. He is a Xamarin Certified Mobile Developer and a Xamarin MVP, Microsoft MVP and Telerik MVP.
This entry was posted in Essentials, Mango, Mini-Tutorial, Patterns & Skills, WindowsPhone and tagged . Bookmark the permalink.

8 Responses to Windows Phone–Sending Messages Between Pages

  1. Pingback: Removing the BackStack Entry in Windows Phone | WP7 Developers Links

  2. Pingback: Windows Phone – Sending Messages Between Pages – www.nalli.net

  3. I feel several bad smells with this sample but I think most of it coming from keeping the sample simple. One I consider a bad practice. The cancel button is a relict from the desktop, better to use the back button for that on the phone.

  4. Ben says:

    I’m astonished that a query string is the recommended way to communicate information between anything other than two network endpoints. Is there really nothing less kludgey?

    • Patrick Long says:

      Ben what is kludgy about a querystring ? I think it is excellent and seeing as the entire URL is on the back stack it makes bringing views back to life after a tombstoning much easier IMHO

      • Hithredin says:

        I don’t know what kludgy mean, but I am also a bit astonished.
        It’s very useful to pass a plain object to a new Page. We can do this in BlackBerry and in Android if the object is Serializable or Parcelable. One does not always want to go through a singleton container to retrieve an object by its Id.

  5. Patrick Long says:

    Doesn’t that go against the idea of “Places”(not sure of the correct name) and the idea of keep “Pages” like dialogs off of the back stack.

    Doesn’t your example above, that uses Forward navigation to update values onto the querystring, cause the user to be dragged back through the dialog box when they press the Hardware back button?

Leave a Reply

Your email address will not be published.