Skip to end of metadata
Go to start of metadata

Crosslight features a powerful data binding capabilities that allows you to centralize your entire business logic all in one place: the ViewModel. Using powerful MVVM pattern, you can create cross-platform apps in more than half of the time. This walkthrough shows you how you can create a simple tip calculator to your simplest Crosslight app.

At the end of this tutorial, you should have the following result:

Samples:

SimpleTipCalculator.zip

Follow these steps:

Prerequisites

Before starting the walkthrough, it is recommended that you have full mastery of the following topics:

It is also recommended that you have read through these conceptual topics in order to get a better understanding of how our app will work.

To use this walkthrough, you can use any version Crosslight in order to achieve the desired result. Let's get started. 

App Design Wireframe

For all mobile apps development, this is one of the most crucial prerequisite steps to be done. You need to have a clear goal in mind on how the app should look like and how your users will be able to interact with it. For our simple tip calculator app, we'll keep it as simple as possible. Below is the example design for iOS.

User interaction flow:

  • User inputs the Bill Amount to the text box with outlet set to TxtBill.
  • User inputs Tip % to the text box with outlet set to TxtTip.
  • User inputs No. of People (to share the tip with) to the text box with outlet set to TxtPeople.
  • User presses the Calculate Tip button (outlet set to CalculateTipButton).
  • The app calculates the Tip Amount with the following calculation: TxtBill * TxtTip / 100.
  • The app calculates the Total Amount with the following calculation: TxtBill + LblTip.
  • The app calculates the Amount per Person with the following calculation: LblTotal / TxtPeople.

We'll encapsulate this logic later in the ViewModel so that it will be shared across all platforms. Now that you've got a rough idea on how your app will look and work later, let's begin development right away.

Preparing the Project

For this tutorial, we're going to use a Blank template created using Crosslight Project Wizard. The project is created with the following configuration:

  • Project Name: SimpleTipCalculator

(screenshot New Project Wizard)

  • Project Template: Blank
  • iOS
    • Device: Universal
    • Template: N/A
  • Android
    • Device: Both
    • Minimum Target: Android 4.0.3
    • Target SDK: Android 5.0
    • Template: N/A
    • Theme: None

After you've created the project, you should get the following solution structure.

You're now ready to begin.

Preparing the ViewModel

The first thing we want to do now is to create the business logic per our design earlier, which will be shared across all platforms. To do this, let's open the up the SimpleViewModel.cs located inside the SimpleTipCalculator.Core project. Replace the entire code as follows:

SimpleViewModel.cs

Here, we have several VM properties:

  • BillText (decimal)
  • PeopleText (int)
  • TipAmount (decimal)
  • TipText (decimal)
  • TotalAmount (decimal)
  • TotalPerPerson (decimal)

VM properties are MVVM-ready properties that is backed with fields, and each time the value is set, OnPropertyChanged event is called. This is extremely important for data binding to work properly. When the OnPropertyChanged event is called, it notifies all the UI that is bound to that particular property.

In the ViewModel's constructor, we've also initialized the initial value for the BillText, TipText, PeopleText, the DelegateCommand for the button to work properly. The value initialization is completely optional, however, you need to initialize the DelegateCommand so that the Calculate Tip button can function well later. The DelegateCommand provides two methods that allows you to intercept whether a command is executable in the CanExecute (CanCalculateTip in this case) method, and the implementation of the command itself inside the ExecuteCommand method (in this case, the CalculateTip method).

In the CalculateTip method, we've defined our logic earlier that sets the TipAmount, TotalAmount, and TotalPerPerson, which will we bind later to the UI. Now you've successfully prepared the ViewModel. Let's move on to platform-specific implementation, starting with iOS.

iOS

For iOS, let's begin by creating the ViewController and the Storyboard as the iOS view. To do this, right click on the ViewControllers folder inside the SimpleTipCalculator.iOS project, and select Add, New Item.

From the dialog that appears, choose Crosslight, then select Crosslight iOS View Controller. Give the name of the ViewController as SimpleTipViewController.

Hit OK. For now, let's leave the ViewController be. Let's create the Storyboard first. Since Crosslight 4, iOS developers can work with the universal storyboard as it is the recommended design approach by Apple. To do this, right-click on the Views folder and select Add, New Item.

From the dialog that appears, choose iOS, then select Empty Storyboard. Give it a name of MainStoryboard.storyboard.

Right after you clicked the Add button, you might get the following error.

This is because you need to connect your Visual Studio to a Mac that has Xcode installed. You can fix this easily by connecting your Visual Studio to the Mac by following Xamarin's guide: https://developer.xamarin.com/guides/ios/getting_started/installation/windows/xamarin-mac-agent/. However, we recommend you to edit your project files directly on Mac instead. Save All of your files. Simply copy the entire solution and paste it on to the Mac. Open the solution using Xamarin Studio on Mac.

After opening the solution, expand the Views folder in the SimpleTipCalculator.iOS project and right click, select Open With, Xcode Interface Designer.

Editing the Storyboard

Using Xcode, drag a new ViewController onto the designer surface. Afterwards, using the identity inspector, specify the Custom Class of the ViewController as SimpleTipViewController, and the Storyboard ID as SimpleTipViewController, as shown in the following figure.

Since our initial design involves lots of horizontal and vertical stacking of the UI elements, let's leverage the new StackView layout introduced in iOS 9 to build our ViewController layout. In the final result, let's build a layout with the following structure:

  • Vertical StackView
    • Vertical StackView
      • Horizontal StackView
        • Label: Bill Amount
        • TextBox: TxtBill (set outlet)
      • Horizontal StackView
        • Label: Tip %
        • TextBox: TxtTip (set outlet)
      • Horizontal StackView
        • Label: No. of People
        • TextBox: TxtPeople (set outlet)
    • CalculateTipButton (set outlet)
    • Vertical StackView
      • Horizontal StackView
        • Label: Tip Amount
        • Label: LblTip (set outlet)
      • Horizontal StackView
        • Label: Total Amount
        • Label: LblTotal (set outlet)
      • Horizontal StackView
        • Label: Amount per Person
        • Label: LblPeople (set outlet)

For the complete step by step guidance, follow this video:

If you wish to learn more about layouting with Xcode, you can check out this excellent collection of articles by Apple: https://developer.apple.com/design/adaptivity/. Now that you got your storyboard ready, save it, and let's go back to our ViewController. Since iOS apps can only be run on the Mac, let's finish up the ViewController on the Mac for now, although you can go back to Visual Studio.

Modifying the ViewController

Open up the SimpleTipViewController.cs file inside the SimpleTipCalculator.iOS project and replace the contents as follows:

SimpleTipViewController.cs

Let's take a look at our ViewController above. It contains several important information:

  • The ViewController is decorated with the StoryboardAttribute which takes in "MainStoryboard" as string. This is necessary for the universal storyboard support to work flawlessly. The "MainStoryboard" string corresponds to the name of the storyboard file we've defined earlier in the Views folder. It tells the ViewController which storyboard file to use.
  • With the universal storyboard support in effect, you should provide a constructor that takes in one IntPtr object. This is also necessary for storyboard initialization to work properly.
  • The HideKeyboardOnTap feature provides a handy accessibility that collapses the keyboard whenever taps outside the keyboard area.
  • In the overridden OnViewInitialized method, we set the title of the ViewController to Simple Tip Calculator.
  • Tell the ViewController to use the SimpleViewModel we've created earlier by specifying it in the generic type parameter of the UIViewController(TViewModel) Class.
  • Tell the ViewController to use SimpleBindingProvider that will act as the glue between the ViewController and the SimpleViewModel. This is what we're going to modify next.

Providing Binding Definitions through Binding Provider

Let's open up SimpleBindingProvider.cs located inside the SimpleTipCalculator.Core/BindingProviders folder. Modify the contents of the file as follows.

SimpleBindingProvider.cs

In the SimpleBindingProvider, we've provided binding definitions for the UI and the ViewModel. The first line, tells the view with outlet TxtBill to bind its text to the BillText property in the ViewModel, two-way binding fashion. As stated in the prerequisites of this walkthrough, it is recommended that you have read through the Understanding Binding Providers article to get a good understanding of what the Binding Provider does. You can also customize the string format, as shown in the last three binding definitions. Now that you have the Binding Provider ready, all you need to do is run the iOS app.

Congratulations! Now you have your iOS app simple tip calculator ready. But how about the other platforms? Let's move on.

Android

For Android, all you need to do now is create the View layer, as you have completed the necessary core stuff: View Model and Binding Provider. Open up the main.axml file inside the SimpleTipCalculator.Android.Material/Resources/layout folder and replace the contents as follows:

main.axml

Save it and run the project. 

Boom. Now suddenly you have the Android version ready. Why is that? What's happening? Take a look at the code you pasted before. What matters is this:

  • EditText with @+id/TxtBill
  • EditText with @+id/TxtTip
  • EditText with @+id/TxtPeople
  • Button with @+id/CalculateTipButton
  • Label with @+id/LblTip
  • Label with @+id/LblTotal
  • Label with @+id/LblPeople

And take a look at SimpleFragment inside SimpleTipCalculator.Android/Fragments folder.

SimpleFragment.cs

As you can see, the Fragment is decorated with ImportBindingAttribute that takes in SimpleBindingProvider type. Since you've shared the exact same Binding Provider with iOS, all you have to do is make sure that your each view element in your layout inside uses the same IDs as defined in the Binding Provider.

Conclusion

Congratulations! You've just finished creating your simple tip calculator app using Crosslight. In this walkthrough, you've learned how to create a cross-platform app with shared UI logic, centralized in the ViewModel and glue them using Binding Provider.

Sample

You can also find the resulting sample here: SimpleTipCalculator.zip. Simply open this sample with Xamarin Studio or Visual Studio and run the project.