Before starting the walkthrough, it is recommended that you have followed these walkthroughs in order:
It is also recommended that you have read through these conceptual topics in order to get a better understanding:
To use this walkthrough, you can use any version of Crosslight in order to achieve the desired result.
Let's get started.
Preparing the Project
For this tutorial, we're going to continue from the finished project used in the first tutorial (Walkthrough: Creating Your First Crosslight App). If you recall, in the first tutorial, we have covered some grounds on how to convert a Xamarin app to a Crosslight app. As the end result, we have a button with a click counter that increments every time it is clicked. We're going to modify the functions of those buttons to perform navigation instead, and add some more buttons to it to perform modal navigation as well.
Let's begin with the iOS project. To start off, let's begin by creating the main menu for our sample.
Preparing the Main Menu
Download this file: Main.storyboard and replace with the one you have inside the Views folder of the iOS project. If you open the file using Xcode, you'll see that we have several ViewControllers ready here.
Let's begin by removing the myButton reference for now and add these outlets for the following UI elements.
Your ViewController.h file should look as follows.
After you add the outlets, save the storyboard, return to Xamarin Studio and run the iOS project. Upon running the project, you might encounter an error as follows.
This happens because the project isn't targeted for iOS 9. Since we've used StackView in our storyboard layout, this project must be targeted for iOS 9. To fix this, open the Info.plist file and change the Deployment Target to at least iOS 9.
In this case, we're going with iOS 9.2. Save the file and re-run the project.
By now, you should have your main menu ready, but you can't click any of the buttons yet, since we haven't provided the bindings, ViewModels and the ViewControllers for each of the view.
Preparing the Binding Provider for the Main Menu
Next, open up the SimpleBindingProvider.cs file located inside the Core PCL project, in the BindingProviders folder. Replace the contents of the file with the following code
Here, all we did is just provide the bindings and commands for our buttons. Next, we're going to modify the ViewModels to see how we can perform each of the navigation.
Performing Standard Navigation
Now, let's focus on the top two buttons get those two buttons to work.
In this part, we're going to perform the most basic navigation techniques available in Crosslight: Push Navigation and Standard Navigation. Open up the SimpleViewModel.cs file inside the Core PCL project, ViewModels folder and modify the code as follows.
The navigation techniques available in Crosslight are centered around the NavigationService. To perform a push navigation, simply call the NavigationService from the ViewModel and specify the target ViewModel, in this case, it's the NewViewModel, which we'll create shortly. Then, to perform a modal navigation, similar to the push navigation, call the NavigationService and specify the target ViewModel with NavigationParameter similar to the above code. The EnsureNavigationContext = true option allows automatic NavigationController creation in iOS.
Preparing the target View
Next, let's create a new ViewController and the ViewModel for our target view. Create a new ViewController under the ViewControllers folder and name it NewViewController.cs. Replace the contents as follows.
If you recall previously, we've prepared the view for our NewViewController. Open up the Main.storyboard file. Ensure that the Custom Class and the Storyboard ID for the New View Controller has been specified correctly to point to the newly created NewViewController, as follows.
In the New View Controller, there's only a Label specified there that will hold the information text when we succesfully performed a push or modal navigation. So, let's bind the Label to an outlet called InformationText.
Save the storyboard file and return to Xamarin Studio. Next, let's bind the InformationText to a property called Info inside the ViewModel. Create a new ViewModel file called NewViewModel.cs inside the Core PCL project and replace the contents as follows.
Here, we've prepared a string VM property called Info. What we're going to do is to display different information text, depending on how the navigation performed. Before we run the project, let's create the BindingProvider for this new view. Create a new file called NewBindingProvider inside the Core PCL project, BindingProviders folder. Replace the content as follows.
Now that we've provided everything, let's run the iOS project and see what happens.
As you can see, now we've (not quite yet) successfully perform standard navigation in iOS. If you notice closely, we can't close return to the previous navigation when you use modal navigation. There's one last thing we need to add so that we can close the modal navigation.
Closing the Modal Navigation in iOS
To close the modal navigation in iOS, we need to add a Done button to the UIBarButtonItems. To do this, let's modify the NewViewModel.cs as follows.
Here, we've added two new properties: a DelegateCommand called CloseCommand, and an additional boolean property called ShouldShowDoneButton. The ExecuteClose command simply calls NavigationService.Close in order to close the current modal navigation, while the ShouldShowDoneButton is simply an additional property not to show the Done button when the ViewModel is used in a simple push navigation scenario.
Next, modify the NewViewController.cs file and modify the file as follows.
Here, we've overridden the InitializeView method in order to provide the Done button the NavigationController so that we can close the modal navigation. Here, we've utilized the previously defined ShouldShowDoneButton in order to decide whether to show the Done button or not. We've also registered the Done button at runtime so that we can bind the button to the ViewModel. Therefore, we need to insert an additional entry for the binding provider. Let's modify the NewBindingProvider.cs as follows.
Let's run the iOS project to verify it works as expected.
Performing Navigation with Parameter
Now that you've learned the basics of standard navigation, let's try to learn how you can perform standard navigation with parameter. For now, let's reuse the existing ViewModels and ViewControllers to learn how to pass parameters while performing push or modal navigation. Now we're going to focus on the second part.
Before we proceed further, let's modify the SimpleViewModel.
Here, we simply add two more DelegateCommands (PushParamsCommand and ModalParamsCommand) for the buttons and another string (Text) to hold the text from the text box. As you can see, to pass parameters during navigation, it is simply done by passing an additional parameter when calling NavigationService.Navigate. Now that we have the ViewModel in order, let's modify the SimpleBindingProvider next so that the controls are properly bound to the ViewModel.
Next, let's modify the NewViewModel's Info text to show more information when we pass extra data during navigation to distinguish between the navigation states.
As you can see, we've only added more information during Navigated to properly show the extra data when it's available. Let's run the iOS project and see what happens.
Capturing Navigation Result
Often times, you'll need to launch a modal screen and capture user input and return that value to the caller ViewModel. With Crosslight, it's very easy to do achieve such scenario. Right now, we're going to focus on the third part on how to achieve such result.
To see this feature in action, we're going to create a new ViewController, new ViewModel and a new BindingProvider.
Let's create a new ViewController called ModalViewController.cs inside the ViewControllers folder. This is just a simple ViewController similar to the NewViewController.
Then, let's open the Main.storyboard file and ensure that the Custom Class, Storyboard ID and the outlets are properly defined.
Set the outlet of the text box as InputText. We're going to bind this later in the BindingProvider.
Proceed by creating a ModalBindingProvider inside the BindingProviders folder in the Core PCL project.
Next, we're going to prepare the Input property and also a CloseCommand to close the modal view in the ViewModel. Create a new ModalViewModel and replace the contents as follows.
Seems we're pretty much done preparing the ModalViewController. Let's revise our SimpleBindingProvider so that the button responds when you click on it. Add another entry as follows.
Also, add a new DelegateCommand called ModalCallbackCommand inside the SimpleViewModel, so your SimpleViewModel looks as follows.
Let's take a closer look at the ExecuteModalCallback method that we've just added. What we've done is pretty similar to the Modal navigation, except this time we can intercept its result when the modal view is closed with a callback. Here we just simply check whether the user has entered any values or not in the InputText of the ModalViewController, then display the entered message with a ToastPresenter. Let's run our iOS project to see the result.
Performing Navigation with Identifier
So far you've learned how to perform navigation to a new screen paired with a ViewModel. But, what if you want to perform navigation using the same ViewModel, but present a different view instead? This section will teach you how to do so. Let's make the last button work, shall we? We're going to create a new ViewController that will use the previously created NewViewModel. Let's call this ViewController as MyViewController and paste the content as follows.
This is just a simple, empty ViewController that uses the NewViewModel as its ViewModel. Pay close attention to the RegisterNavigationAttribute decorating the MyViewController class. This is the key to perform a navigation with a view identifier.
If you wish to inspect the view in the storyboard, you can see that we have nothing except for a dummy text just to indicate that the navigation we're going to perform is made using the view identifier.
That's basically it for the view target. Let's modify the SimpleBindingProvider and the SimpleViewModel to make our last button work.
Let's run the project to see it in action.
What About Android?
You've successfully finished the sample for iOS. But how about Android? This is where the beauty of Crosslight comes in. All you have to do is just prepare the views and everything will work automagically.
Open up SimpleFragment.cs inside the Fragments folder and modify its contents as follows.
Modify the Main.axml inside the Resources/layout folder as follows. This will be our main menu.
If you try to run this project, you'll get the following result. Just ensure that the IDs for the buttons and textboxes match the ones in the SimpleBindingProvider.
This ensures that our main menu is ready. Great. Let's move on by creating NewFragment.cs inside the Fragments folder.
Proceed by creating a new XML file called new_fragment.axml inside the Resources/layout folder. Replace its contents as follows.
Resume by creating a ModalFragment.cs inside the Fragments folder.
Then an XML file called modal_fragment.axml inside the Resources/layout folder.
Lastly, create our last Fragment, called MyFragment.cs, still inside the Fragments folder.
This Fragment is similar to the MyViewController.cs we've created in iOS, where this view is marked with a RegisterNavigationAttribute to perform navigation with view identifier.
Then our last layout, called my_fragment.axml inside the Resource/layout folder.
Let's run this project to see it in action.
As you can see, the Android version just works after we've finished preparing the view. This is the true power of code sharing in Crosslight. Once you've got one platform ready, you'll only need to prepare the views on other platforms. And it will just work, automagically.
Congratulations! You've learned how to navigate between screens in Crosslight with various navigation techniques available through the built-in Crosslight navigation service.
You can also find the resulting sample here: CrosslightNavigation.zip. Simply open this sample with Xamarin Studio or Visual Studio and run the project.