When I’m building a mobile application one of the first things I want to get right is the flow of navigation. My demo cross platform application is no different. So the first thing to do is to work out how each of the navigation systems work, how to control it from C# code and of course wire up a simple navigation.
Windows Phone 7
Yeh, so this one should be easy since I’m so familiar with it. Essentially the navigation model is that an application is made up of a series of pages. To proceed within the application you make a call to Navigate and supply the relative Uri of the page that you want to navigate to. When the user presses the Back button the default behaviour is for the application to return to the previous page. If they press the Back button on the first page of the application, the application will be terminated.
– Add a new page to the application (Right-click the project in Solution Explorer > Add > New Item)
– Select the Windows Phone Portrait Page, give it a name, SecondPage.xaml, and click OK
– Add a button to the first page of the application (ie to MainPage.xaml)
> Double-click MainPage.xaml in solution explorer to open it
> Find “<Grid x_Name=”ContentPanel” Grid.Row=”1″ Margin=”12,0,12,0″></Grid>” and replace with
<StackPanel x_Name=”ContentPanel” Grid.Row=”1″ Margin=”12,0,12,0″>
<Button Content=”Go To Second Page”
Click=”SecondPageClick” />
</StackPanel>
– Right-click anywhere in the MainPage.xaml code/design window and select View Code
– Add the following code into the MainPage class. This is the event handler for the button you just added and causes the application to navigate to the second page.
private void SecondPageClick(object sender, RoutedEventArgs e) {
this.NavigationService.Navigate(new Uri(“/SecondPage.xaml”, UriKind.Relative));
}
– F5 to run the application. Click the “Go To Second Page” button an note that a new page is displayed. Click the Back Button (bottom left of emulator) to return to the main page. Click Back again to exit the application.
iOS
– Double-click MainWindow.xib to open it in Interface Builder
– From the Library window (Tools > Library if not already visible) drag a Navigation Controller element onto the MainWindow.xib
In order to reference this Navigation Controller from within your code you’re going to need to create an Outlet. You can think of this as a backing variable (although not strictly the same) to allow you to reference this element from code.
– In the Library window, select the Classes tab; Select AppDelegate from the list; Select Outlets from the AppDelegate sub-window.
– Click the + button, and give the new outlet a name, rootNavigation
– Lastly you need to wire the Navigation Controller to the outlet you just created. Select the App Delegate node in the MainWindow.xib window – the Inspector window (Tools > Inspector if not already visible) will update to display information about the App Delegate. Select the App Delegate Connections tab (second one from left) to display the list of outlets available and then drag the empty ring from alongside rootNavigation across onto the Navigation Controller node in MainWindow.xib.
We’ve wired up the navigation controller, the last thing to do in order to get the application to display something when we run it (if you recall from when we initially created this application there was nothing displayed on screen when we ran it) is to add the Navigation Controller as a sub-view of the main application window.
– Save changes in Interface Builder and return to MonoDevelop
– Open Main.cs and uncomment and update the line that starts // window.AddSubView (~line 25) to the following:
window.AddSubview(rootNavigation.View);
If you run at this point you will now see a heading of Root View Controller at the top of your application. We now need to add a button which will invoke the navigation to a new view.
– Go back to Interface Builder and find the Navigation Controller window. From the Objects tab of the Library window, drag a View object into the main area of the Navigation Controller window. The newly created View should take up the majority of the window, displacing the “View” placeholder.
– Again from the Library window, drag on a Round Rect Button. Resize the button across the top of the view area, and in the Inspector window change the Title property to read “Go To Second View”
We’ve created both the initial view and a button within the view. Now we need to be able to reference the button from code so that we can wire up an event handler to when the user taps the button. To do this we extend the view controller (if you look in the MainWindow.xib you will see that nested under the Navigation Controller node is a View Controller node) so that when an instance is created, we can wire up an event handler for the button click.
– In the MainWindow.xib window. Select the View Controlller (Root View Controller) node and then switch to the Identity tab of the Inspector window.
– Set the Class value to be MainPageController (we need to give the controller a name here so that we can write code in a code-behind file for a partial class with the same name).
– In the Library window, select the MainPageController on the Classes tab. Then select Actions from the MainPageController dropdown.
– Click the + button to create a new Action (think of actions as event handlers) and call it navigationButtonClick
– Switch over to the MainWindow.xib window; Select the Rounded Rect Button and find the Touch Down connector on the Connections tab of the Inspector window.
– Drag the circle alongside the Touch Down connector across onto the Main Page Controller node of the MainWindow.xib window. When prompted click on the navigationButtonClick action to complete the wiring up process. This has wired up the Touch Down event on the button to the navigationButtonClick action.
So now all we need is some code to be invoked when that action occurs. This is where Mono comes in – it’s already created a stub for us. All we need to do is to fill in the code.
– Switch back to MonoDevelop and create a new class file, MainPageController.cs, based on the Empty Class file template. Replace the contents of the file with the following.
using System;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace NicksNetTravelsiOS {
public partial class MainPageController: UIViewController {
public MainPageController (IntPtr p) : base (p) { }
partial void navigationButtonClick (UIButton sender) {
}
}
}
Note that the MainPageController is a partial class, and the navigationButtonClick method is a partial method. The class and method definitions are in the MainWindow.xib.designer.cs file and are automatically generated by MonoDevelop (don’t hack around in the designer generated files!!!)
Ok, to round out this we’re going to need another view to switch in when the button is clicked
– In MonoDevelop select File > New > File; Select the iPhone View with Controller template; give it a name, SecondPageController and click New.
– Open the MainPageController.cs file and modify the navigationButtonClick event handler you created earlier.
private SecondPageController secondPage;
partial void navigationButtonClick (UIButton sender) {
if(secondPage==null){
this.secondPage = new SecondPageController();
}
this.NavigationController.PushViewController(secondPage,true);
}
– Build and run this and when you click on the button, the second view will animate in.
Android
The initial application that we created already comes with a button on the first view in the application. All we need to do is add a second view and navigate to it. Ok, just to be clear on the terminology here: In an Android application there are views and activities – and you should think of them in the context that an activity manages the current view and that you can either transition views within the current activity, or you can transition between activities. In this case we’re actually going to do the latter which will involve creating both an additional activity and a corresponding additional view.
– In the Solution Explorer window, right click on the Layout node; Select Add > New Item; Select the View template and give it a name, SecondPage; Click Add
– Next we need to add an additional activity, so right-click the project node and select Add > New Item; Select the Activity template and give it a name, Activity2
– Update the Activity2 class in Activity2.cs as follows. This sets the SecondPage view as the current view for Activity2
[Activity(Label = "My Activity")]
public class Activity2 : Activity
{
protected override void OnCreate(Bundle bundle){
base.OnCreate(bundle); SetContentView(Resource.Layout.SecondPage); }
}
– The last thing to do is to add the navigation from Activity1 to Activity2, which is in Activity1.cs. Change the delegate for the Click event to the following:
button.Click += delegate { StartActivity(typeof(Activity2)); };
– Press F5 to build and run
And there you have it – basic navigation across all three platforms. Not that they all use slightly different conventions but all support some level of “back” operation. On Windows Phone 7 it’s a dedicated hardware back button, Android has a back button in the on screen menu area (or I believe it can be a hardware button) and iOS has it as part of the navigation controller on screen infrastructure.