Nick's .NET Travels

Continually looking for the yellow brick road so I can catch me a wizard....

MVX=1: TipCalc - a second example - adding IoC and the Xamarin Android Designer (MVX+1 days of MvvmCross)

Following on from the first post in the MVX+1 series, in this post we’ll create a basic Tip Calculator (mirroring the original post from the N+1 series). However, in this case the first section is a more detailed set of instructions on how to get the basics of all three platforms setup with MvvmCross. Going forward we’ll use this as a starting point so that we don’t need to cover over this in each subsequent post.

Source code: https://github.com/nickrandolph/MvxPlus1DaysOfMvvmCross/tree/master/Mvx-01-TipCalc

Getting Started Instructions (Native Apps)

Note: In this case the name of the application is TipCalc but these instructions can be followed to get any new project started by simply replacing TipCalc with the name of your project.

  1. Create a the new solution by creating a new Class Library (.NET Standard) with the project name set to TipCalc.Core and the solution name to just TipCalc.
  2. Add a new project based on the Blank App (Universal Windows) project template called TipCalc.Uwp (make sure that the Minimum and Target versions are set to at least the Fall Creators Update)
  3. Add a new project based on the Android App (Xamarin) project template called TipCalc.Droid (use the Blank app template)
  4. Add a new project based on the iOS App (Xamarin) project template called TipCalc.iOS (use the Blank app template)
  5. Add a reference to MvvmCross NuGet package (v6.0.0 at time of writing to all four projects)
  6. TipCalc.Uwp: Update NuGet package Microsoft.NETCore.UniversalWindowsPlatform to the latest stable version (6.0.8 at time of writing)
  7. TipCalc.Droid: Update the Android version to Use Latest Platform (Project Properties –> Application –> Target Framework)
  8. TipCalc.Droid: Update Xamarin.Android.Support.Design to latest stable version (27.0.2 at time of writing)
  9. TipCalc.Droid: Add a reference to MvvmCross.Droid.Support.V7.AppCompat package
  10. TipCalc.iOS: Unload project; delete packages.config; edit TipCalc.iOS.csproj and add the following ItemGroup
    <ItemGroup>
       <PackageReference Include="MvvmCross" Version="6.0.0" />
    </ItemGroup>
  11. Add a reference to TipCalc.Core to each of the three head projects (ie TipCalc.Uwp, TipCalc.Droid and TipCalc.iOS)
  12. TipCalc.Core: Rename the default Class1.cs to App.cs, and allow Visual Studio to rename class to App
  13. TipCalc.Core: Change the App class to inherit from MvxApplication
  14. TipCalc.Core: Add a folder, ViewModels, and add a class called FirstViewModel.
  15. TipCalc.Core: Change FirstViewModel to inherit from MvxViewModel
  16. TipCalc.Core: Override Initialize method in App to register services and set startup view model to FirstViewModel
    public override void Initialize()
    {
         CreatableTypes()
                 .EndingWith("Service")
                 .AsInterfaces()
                 .RegisterAsLazySingleton();
         RegisterAppStart<FirstViewModel>();
    }
  17. TipCalc.Uwp: Add a help class ProxyMvxApplication
    public abstract class ProxyMvxApplication: MvxApplication<MvxWindowsSetup<Core.App>, Core.App> { }
  18. TipCalc.Uwp: Change App.xaml and App.xaml.cs to inherit from ProxyMvxApplication
  19. TipCalc.Uwp: Remove all code in App.xaml.cs other than the constructor which should contain a single call to InitializeComponent
  20. TipCalc.Uwp: Delete MainPage.xaml and MainPage.xaml.cs
  21. TipCalc.Uwp: Add a Views folder, and  add a FirstView based on the Blank Page template
  22. TipCalc.Uwp: Change FirstView.xaml and FirstView.xaml.cs to inherit from MvxWindowsPage
  23. TipCalc.Droid: Add a new class, MainApplication, that inherits from MvxAppCompatApplication
  24. [Application]
    public class MainApplication : MvxAppCompatApplication<MvxAppCompatSetup<App>, App>
    {
         public MainApplication(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
         {
         }
    }

  25. TipCalc.Droid: Rename MainActivity.cs to SplashScreen.cs and let Visual Studio rename the class
  26. TipCalc.Droid: Rename activity_main.axml to SplashScreen.axml, and adjust layout to indicate application loading
  27. TipCalc.Droid: Adjust SplashScreen class to inherit from MvxSplashScreenAppCompatActivity and set NoHistory to true (since we don’t want the user to be able to press the back button and go back to the splash screen)

    [Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true, NoHistory = true)]
    public class SplashScreen : MvxSplashScreenAppCompatActivity

  28. TipCalc.Droid: Add a folder, Views, and add a new Activity, FirstView.c
  29. [Activity(Label = "FirstView")]
    public class FirstView : MvxAppCompatActivity<FirstViewModel>
    {
         protected override void OnCreate(Bundle bundle)
         {
             base.OnCreate(bundle);

            SetContentView(Resource.Layout.FirstView);
         }
    }

  30. TipCalc.Droid: Add a new Android Layout to the Resources/Layout folder, FirstView.axml
  31. TipCalc.Droid: You may run into an error: “error XA4210: You need to add a reference to Mono.Android.Export.dll when you use ExportAttribute or ExportFieldAttribute.” If you do, you just need to Add Reference to Mono.Android.Export (search in the Add Reference dialog).
  32. TipCalc.iOS: Update AppDelegate class to inherit from MvxApplicationDelegate, and remove the default code.
    [Register("AppDelegate")]
    public class AppDelegate : MvxApplicationDelegate<MvxIosSetup<App>, App>
    {
    }
  33. TipCalc.iOS: Add an Empty Storyboard, called Main.storyboard, to the root of the project
  34. TipCalc.iOS: Add a ViewController to the Main.storyboard using the designer and set the Class and Storyboard ID to FirstView (also make sure the “User Storyboard ID” checkbox is set to true)
  35. TipCalc.iOS: Move the generated FirstView.cs and FirstView.designer.cs files (from the previous step) into a new folder called Views, and adjust the namespace of the FirstView class to FirstView.iOS.Views
  36. TipCalc.iOS: Update the FirstView class to inherit from MvxViewController
    [MvxFromStoryboard("Main")]
    public partial class FirstView : MvxViewController<FirstViewModel>


Now to actually build out the Tip Calculator. Rather than embed the calculation logic into our view model, we’re going to abstract it out into a service. To do this we’ll make use of the IoC container made available by MvvmCross. We’ll register a CalculationService which will be injected into our view model constructor.

Let’s continue our development of the Tip Calculator in TipCalc.Core:

  1. Add a folder called Services
  2. Add an interface ICalculationService into the Services folder
    public interface ICalculationService
    {
         double Tip(double subTotal, double generosity);
    }
  3. Add a class, CalculationService, which implements ICalculationService, again into the Services folder
    public class CalculationService : ICalculationService
    {
         public double Tip(double subTotal, double generosity)
         {
             return subTotal * generosity / 100.0;
         }
    }

  4. Add a constructor to the FirstViewModel which accepts an ICalculationService parameter
  5. private readonly ICalculationService _calculationService;
    public FirstViewModel(ICalculationService calculationService)
    {
         _calculationService = calculationService;
    }

  6. Add properties for SubTotal, Generosity, Tip and Total. Each property should take the following form where SetProperty is called within the setter
    private double _subTotal;
    public double SubTotal
    {
         get { return _subTotal; }
         set { SetProperty(ref _subTotal, value); }
    }
  7. Add a Recalc method which will invoke the Tip method on the ICalculationService
    private void Recalc()
    {
         Tip = _calculationService.Tip(SubTotal, Generosity);
         Total = SubTotal + Tip;
    }
  8. Add a call to Recalc into the setter for both SubTotal and Generosity
  9. Set some initial values for the SubTotal and Generosity (if you use the property setters, rather than setting the fields, the Recalc method will be invoked)

That’s it for the core logic for the application. Now we just need to wire up the UI for each platform.

One thing that’s worth noting is that in step 16 of the original setup where the Initialize method is overridden, there is logic in the Initialize method to interrogate the current assembly looking for all classes that end in Service and register them, based on their interface, with the MvvmCross IoC container – this is how MvvmCross knows about the implementation of the ICalculationService which is used when instantiating the FirstViewModel.

Let’s built out the UWP interface in TipCalc.Uwp:

  1. Add the following XAML inside the existing Grid element:
    <StackPanel>
         <TextBlock Text="SubTotal"/>
         <TextBox Text="{Binding SubTotal, Mode=TwoWay}"/>
         <TextBlock Text="How generous?"/>
         <Slider Value="{Binding Generosity, Mode=TwoWay}"
                 Minimum="0"
                 Maximum="100"/>
         <TextBlock Text="Tip:"/>
         <TextBlock Text="{Binding Tip}"/>
         <TextBlock Text="SubTotal:"/>
         <TextBlock Text="{Binding Total}"/>
    </StackPanel>

That’s the UWP interface done – four elements (with TextBlock headings): TextBox and Slider for inputting SubTotal and Generosity using two-way data binding, and two TextBlock for outputting the Tip and Total amounts.

Now let’s do Android:

  1. Add the following namespace declaration to FirstView.axml
    xmlns:local="http://schemas.android.com/apk/res-auto"
  2. Add the following xml to FirstView.axml
    <TextView
         android:text="SubTotal"
         android:textAppearance="?android:attr/textAppearanceMedium"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:id="@+id/textView1" />
    <EditText
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:id="@+id/editText1"
         local:MvxBind="Text SubTotal" />
    <TextView
         android:text="Generosity"
         android:textAppearance="?android:attr/textAppearanceMedium"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:id="@+id/textView2" />
    <SeekBar
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         local:MvxBind="Progress Generosity"
         android:id="@+id/seekBar1" />
    <TextView
         android:text="Tip"
         android:textAppearance="?android:attr/textAppearanceMedium"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:id="@+id/textView3" />
    <TextView
         android:textAppearance="?android:attr/textAppearanceMedium"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         local:MvxBind="Text Tip"
         android:id="@+id/textView4" />
    <TextView
         android:text="Total"
         android:textAppearance="?android:attr/textAppearanceMedium"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:id="@+id/textView5" />
    <TextView
         android:textAppearance="?android:attr/textAppearanceMedium"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         local:MvxBind="Text Total"
         android:id="@+id/textView6" />

In this case we’re leveraging the xml extensions offered by MvvmCross in order to do the data binding using the MvxBind syntax.

Finally, let’s do iOS:

  1. Add the following code to the FirstView.cs
    public override void ViewDidLoad()
    {
         base.ViewDidLoad();
  2.     // Perform any additional setup after loading the view
         var label = new UILabel(new RectangleF(10, 0, 300, 40));
         label.Text = "SubTotal";
         Add(label);

        var subTotalTextField = new UITextField(new RectangleF(10, 40, 300, 40));
         Add(subTotalTextField);

        var label2 = new UILabel(new RectangleF(10, 80, 300, 40));
         label2.Text = "Generosity?";
         Add(label2);

        var slider = new UISlider(new RectangleF(10, 120, 300, 40));
         slider.MinValue = 0;
         slider.MaxValue = 100;
         Add(slider);

        var label3 = new UILabel(new RectangleF(10, 160, 300, 40));
         label3.Text = "Tip";
         Add(label3);

        var tipLabel = new UILabel(new RectangleF(10, 200, 300, 40));
         Add(tipLabel);

        var label4 = new UILabel(new RectangleF(10, 240, 300, 40));
         label4.Text = "Total";
         Add(label4);

        var totalLabel = new UILabel(new RectangleF(10, 280, 300, 40));
         Add(totalLabel);

       var set = this.CreateBindingSet<FirstView, FirstViewModel>();
         set.Bind(subTotalTextField).To(vm => vm.SubTotal);
         set.Bind(slider).To(vm => vm.Generosity);
         set.Bind(tipLabel).To(vm => vm.Tip);
         set.Bind(totalLabel).To(vm => vm.Total);
         set.Apply();

    }

In this case for iOS we again make use of the data binding support provided by MvvmCross by using the CreateBindingSet method, followed by a call to Bind for each element property we want to bind, and then finally a call to Apply to complete the setup of data binding.

And that’s it – a Tip Calculator for all three platforms.

MVX=0 : A first MvvmCross Application (MVX+1 days of MvvmCross)

[Repost: Apologies for those who have already read this but there were some issues with the link generated for the previous post, so I’ve reposted it]

Updated 16/4/2018: Reference to MvvmCross have been updated to v6.0.0

Yes, this is going to be a sequence of posts reworking the infamous N+1 series that Stuart Lodge did starting almost exactly 5 years ago. As we approach the 5 year anniversary of these posts I thought it only fitting to cover this series again as a way of introducing MvvmCross v6 which will be released very shortly has just been released. Unlike the original series that were YouTube videos accompanied by blog posts, this series will only contain the posts, mainly because I find generating videos to be time consuming. Anyhow, here goes:

We’ll start by creating a Blank Solution.

image_thumb4_thumb

Into the solution we’ll add a Core Library that will contain an App class and our first ViewModel:

  1. Add a Class Library (.NET Standard) called FirstDemo.Core
    image_thumb3_thumb
  2. Add a reference to MvvmCross NuGet package (v6.0.0-beta.8 v6.0.0 at time of writing)
  3. Rename the default Class1.cs to App.cs, and allow Visual Studio to rename class to App
  4. Change App to inherit from MvxApplication
  5. Add a folder, ViewModels, and add a class called FirstViewModel.
  6. Change FirstViewModel to inherit from MvxViewModel
  7. Add logic to FirstViewModel to include FirstName, LastName and a calculated FullName
  8. Override Initialize method in App to call RegisterAppStart, specifying FirstViewModel as the startup ViewModel

Let’s start with a Universal Windows Platform UI:

  1. Add a Blank App (Universal Windows) called FirstDemo.Uwp
    image_thumb6_thumb
  2. Make sure Minimum and Target versions are set to at least the Fall Creators Update so that it supports .NET Standard 2.0
    image_thumb8_thumb
  3. Update NuGet package Microsoft.NETCore.UniversalWindowsPlatform to the latest stable version (6.0.8 at time of writing)
  4. Add a reference to MvvmCross NuGet package
  5. Add reference to FirstDemo.Core project
  6. Add a help class ProxyMvxApplication to the FirstDemo.Uwp project – this is a proxy class to compensate for the lack of generics support in XAML
  7. public abstract class ProxyMvxApplication: MvxApplication<MvxWindowsSetup<Core.App>, Core.App> { }

  8. Change App.xaml and App.xaml.cs to inherit from ProxyMvxApplication
  9. Remove all code in App.xaml.cs other than the constructor which should contain a single call to InitializeComponent
  10. Delete MainPage.xaml and MainPage.xaml.cs
  11. Add a Views folder, and  add a FirstView based on the Blank XAML page template
  12. Change FirstView.xaml and FirstView.xaml.cs to inherit from MvxWindowsPage
  13. Add some TextBoxes and a TextBlock to the FirstView, complete with databinding
  14. Hit F5 and run the application (you may have to set the FirstDemo.Uwp project as the startup project and make sure it’s set to build and deploy using the Configuration Manager)

Next let’s add the Android UI:

  1. Add a Android App (Xamarin) called FirstDemo.Droid
    image_thumb10_thumb
  2. Select the Blank App template, and the minimum Android version
  3. Update the Xamarin.Android.Support.Design NuGet package (at time of writing the latest is 27.0.2)
  4. Update the Android version to Use Latest Platform
    image_thumb12_thumb
  5. Add a reference to MvvmCross NuGet package
  6. Add a reference to MvvmCross.Droid.Support.V7.AppCompat package
  7. Add reference to FirstDemo.Core project
  8. Add a new class, MainApplication, that inherits from MvxAppCompatApplication
    public class MainApplication : MvxAppCompatApplication<MvxAppCompatSetup<App>, App>
  9. Rename MainActivity.cs to SplashScreen.cs and let Visual Studio rename the class
  10. Rename activity_main.axml to SplashScreen.axml, and adjust layout to indicate application loading
  11. Adjust SplashScreen class to inherit from MvxSplashScreenAppCompatActivity and set NoHistory to true (since we don’t want the user to be able to press the back button and go back to the splash screen)
  12. [Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true, NoHistory = true)]
    public class SplashScreen : MvxSplashScreenAppCompatActivity

  13. Add a folder, Views, and add a new Activity, FirstView.cs
    1. Add a new Android Layout to the Resources/Layout folder, FirstView.axml, with a couple of EditText and a TextView, all data bound using MvxBind
    2. You may run into an error: “error XA4210: You need to add a reference to Mono.Android.Export.dll when you use ExportAttribute or ExportFieldAttribute.” If you do, you just need to Add Reference to Mono.Android.Export (search in the Add Reference dialog).
    3. Set the startup project to be FirstDemo.Droid and press F5 to run the application

    Lastly, let’s add the iOS UI:

    1. Add an iOS App (Xamarin) called FirstDemo.iOS
      image_thumb2_thumb
    2. Select the Blank App template, Universal devices support and Minimum iOS Version of 11.2
      1. Add a reference to MvvmCross NuGet package
        1. Add reference to FirstDemo.Core project
        2. Update AppDelegate class to inherit from MvxApplicationDelegate
          public class AppDelegate : MvxApplicationDelegate<MvxIosSetup<App>, App>
        3. Add an Empty Storyboard, called Main.storyboard, to the root of the project
        4. Add a ViewController to the Main.storyboard using the designer and set the Class and Storyboard ID to FirstView (also make sure the “User Storyboard ID” checkbox is set to true)
        5. Move the generated FirstView.cs and FirstView.designer.cs files (from the previous step) into a new folder called Views, and adjust the namespace of the FirstView class to FirstView.iOS.Views
        6. Add two UITextField and a UILabel to the FirstView ViewController using the Main.storyboard designer (make sure each element has a Name set so it can be referenced from code)
        7. Update the FirstView class to inherit from MvxViewController
          [MvxFromStoryboard("Main")]
          public partial class FirstView : MvxViewController<FirstViewModel>
        8. Add logic to FirstView to enable databinding using the CreateBindingSet extension method
        9. Set the startup project to be FirstDemo.Droid and press F5 to run the application
          Update 16/4/2018: For some reason the iOS App (Xamarin) project template still uses a package.config. During the update to the stable v6.0.0 package the package.config file in FirstDemo.iOS was removed, the reference in FirstDemo.iOS.csproj to MvvmCross was manually removed and the following ItemGroup added:
          <ItemGroup>
             <PackageReference Include="MvvmCross" Version="6.0.0" />
          </ItemGroup>

        The final code is available at https://github.com/nickrandolph/MvxPlus1DaysOfMvvmCross/tree/master/Mvx-00-FirstDemo

        To get this to work I would suggest running the latest Visual Studio for Mac or PC. Hit me up on Twitter or Slack if you have any issues following the steps or running the samples.

        Slack, Teams and the Failings of the Universal Windows Platform (UWP)

        This is going to start of as a bit of a rant…. because it is – I’ve been building desktop and mobile applications using .NET since the first version of the .NET framework shipped many moons ago. In that time we’ve seen the rise and fall of various frameworks, patterns and technologies, all of which were supposed to make our lives as developers, designers and hopefully users better. Whilst the web seems to be this slowly devolving of JavaScript rot, you’d have thought that the .NET Framework after so many years would be everything that a developer needs in order to build amazing apps. Unfortunately, no, some idiot decided it would be great to run all that web-junk inside a native application.

        This brings me to the heart of my rant: Depending on our customers and suppliers, we toggle between Microsoft Teams, Slack, Skype, Skype for Business (now mostly deprecated in favour of Teams), HipChat, Hangouts and even Messenger. Whilst we all love to complain about how bad Skype is, the reality is that newer tools such as Teams and Slack are even worse. Both Slack and Teams are built using Electron and as far as desktop applications go, they are both as nasty as each other. They’re both slow; the user interface on both is painful and in no way takes advantage of the fact that I’m running on Windows. The operative word being Windows <<<—it has an S. I have to switch between multiple Slack channels and multiple Teams on a daily basis – they’re all in the same window; switching between them is slow (10-20secs); and it’s hard to keep track of conversations because notifications either don’t work, or are buried behind a single dot (not even a count as to how many unread messages).

        So why is it that things are so bad….. well it’s because the other options are no better. Take for instance the Universal Windows Platform – which is now only really Universal to desktop and Xbox because realistically they’re the only targets that you’ll consider (save some end cases for IoT and Hub). What a missed opportunity for Microsoft – they could have nuked the failed Xamarin Forms experiment in favour of extending UWP to really be the Universal Application Platform (UAP – oh wait, that’s the internal target framework for UWP already!!!); instead they’re sinking continued development effort into Xamarin Forms in the hope that it’ll one day be a viable alternative to Electron, Flutter, React Native….

        Talking of Xamarin Forms, is this such a bad platform? Well no, I actually quite like Xamarin Forms and I’ve personally invested a lot of time recently trying to help MvvmCross get to a stable v6 so that it can better support Xamarin Forms development. However, I would say that if you’re building for Xamarin Forms and you’re not using a third party Mvvm framework, you really need to – Microsoft’s continual assertion that Xamarin Forms has everything you need is just plain misleading and just leads to poorly architected applications.

        So, what is bad about Xamarin Forms? Well it’s hamstrung between at least three platforms (iOS, Android, Windows… Tizen, WPF….) in that they made a decision to rely on the native controls for each platform. React Native has a similar issue, since they decided on a similar approach. Flutter on the other hand has platform independent rendering and for that it’s getting a lot of attention. The design guidance from years ago that you should build for the platform UI is just plain wrong – you’ll end up with an application that just looks bad (lipstick on a pig!). You need to build applications that work for your brand – don’t design it multiple times, build it to suit your brand and your needs. You may decide to adopt some platform UX but the reality is that you want a button in your app to look the same on all platforms.

        Anyhow, enough of a rant about the failings of desktop apps…. until next time, enjoy losing hours of your day to responding to messages on Teams, Slack etc

        PWA Follow Up

        It’s clear that talking about Progressive Web Applications (PWAs) is all the rage. I noticed today that fellow Microsoft MVP, Adam Pedley who runs the Xamarin Help website and blog, posted about where PWAs and Xamarin.Forms fit. Whilst I’m not sure I agree with his opening statement about PWAs being started by Google (there is a long legacy of different browsers providing pseudo-offline features which pre-date the term PWA, so the concept itself isn’t new), I will definitely agree that it has been Google that has been championing the cause, with Microsoft adding some behind the curtain support (eg PWABuilder.com). One of the most interesting points that’s worth highlighting is the disconnect between the device features/capabilities that the web and client applications (native, Xamarin or Xamarin Forms) can take advantage of. Whilst the difference is being progressively eroded, there are still plenty of areas where a client application is the way to go. Shout out to https://whatwebcando.today/

        image

        Cross-platform applications – PhoneGap/Cordova, Xamarin, PWAs and now Flutter

        At Built to Roam we build applications that target a wide array of different platforms, using a wide variety of technologies depending on the project requirements. One of the most challenging things faced by organisation looking to build any form of software is often not what should I build, it’s often what technology should I use to build it. Unfortunately this is also where the most cycles are wasted and the poorest decisions are made.

        Nirvana would be building the software once, and for it to be available on every platform and device type, able to be instantly updatable and have a rich and engaging user interface (and I’m sure there’s more things that needed to be bolted onto this list of “ideals”). However, the reality is that there are different device types and sizes; there are different technologies with differing capabilities; and different developer and deployment workflows. Rather than being able to make an absolute decision on the best strategy, companies are limited by their own field of influence. Too often this includes Gartner reports, media hype and both internal and contractors with whom the decision makers have a relationship with.

        In addition to the number of options that are available, the optimum strategy also evolves over time. For example, five years ago in Australia it made sense for organisations to start their investment in mobile apps with a fairly basic iPhone application. Today the market expectation is that a mobile strategy encompasses at least Android and iOS, phone and tablet, and with a comprehensive set of features. In fact some applications, don’t even have a web presence, finding that their mobile apps were sufficient for their business model.

        So the question is really whether it is possible to define the optimum strategy for a business and is it possible to future proof it?

        To investigate this a bit further, let’s take a look at the progression of native application development. What’s quite interesting is that businesses have woken up to the fact that maintaining multiple applications written in the preferred technology for each platform is not sustainable. This has led to the emergency of a host of cross platform tools that generate native applications. There are tools such as Xamarin/Xamarin Forms which compile C# so that it can be run on the target platform; There has also been an explosion in Javascript based solutions, such as React Native where it generates the native components for each platform based on HTML mark-up (+CSS, JavaScript etc); More recently again there is Flutter, which aims to provide a user experience that has been drawn from the ground up to be platform agnostic. How do you make a decision between these technologies?

        More importantly is – are you making the decision about the right thing? It would seem that making a decision about which native application toolset to use would be right but actually the web and some of the hybrid solutions solve so many challenges that native application developers face, it would be foolish to ignore them. Take for example the recent hype around Progressive Web Applications. There are some who believe this is just another round of hype about the newest buzzword to arrive on the scene but in actual fact whilst the name is new, the concept is not. Back even in the days of Windows Vista, there were desktop gadgets that essentially allowed parts of the web to run in a container in an offline capacity. PWAs are just the latest name to be given to this concept.

        Where PWAs are set to make a difference is that they are being widely backed (eg Google: https://developers.google.com/web/progressive-web-apps/ and Microsoft: https://pwabuilder.com) and they also arrive at a point in time where devices have browsers and rendering engines that are capable of delivering a high-performance web experience whether in-browser, or in a hosted web application.

        Do you think the market is ready for PWAs? or are native applications going to rule for the foreseeable future?

        New BuildIt Release for NetStandard 2.0 (General, States and Forms)

        A new release of the following libraries is available via NuGet (v1.1.0.134):

        - BuildIt.General

        - BuildIt.States

        - BuildIt.Forms

        Whilst not much has changed in terms of features, behind the scenes there was quite a significant change as we adjusted the solution/project structure, and thus the nuget package structure. We took advantage of the ability to multi-target which meant we no longer have to have separate projects/libraries in order to support platform specific features. BuildIt.General, which used to have a UWP specific library, is now a single libary. Same goes for BuildIt.States. BuildIt.Forms has two libraries, down from the 5 that it used to have.

        Additionally we also added direct support for netstandard 2.0. As part of the build process, each library is compiled for netstandard 1.0, netstandard 2.0 and then any platforms that have additional features.

        In this release we’ve released multiple packages with the same version number, even though there is an interdependency between them (Forms –> States –> General).

        Please reach out and let me know if you see any issues in this release with any of these libraries. We’ll be working to release updates to the other BuildIt libraries over the coming weeks.

        Building Applications for Platform X

        As we get started with a new year it’s time to pause and think about how the app development ecosystem has evolved, what technologies continue or are emerging, and look at the decision matrix that will define what technology your next application is developed in. I’m going to treat this post as a bit of an intro to some of the technologies that I think are worth further investigation.

        I think the easiest way to do this is to walk the spectrum from web apps through to native platform apps:

        Web Apps

        When we talk about web apps, there is a natural assumption that these will be responsive web sites that will work across a wide range of devices and browsers. However, they can be divided further into what I would consider traditional web sites and single page applications. Whilst this division can be blurred, for example when you host an Angular application within a .NET core application, the point is that there is a difference in the mindset of the developers building the web app.

        Of course, this section includes the obvious ASP.NET Core, React and Angular. Whilst ASP.NET is still a valid choice, I specifically left it out of the list as I think most new projects will favour ASP.NET Core unless there is an impediment that requires full ASP.NET.

        Progressive Web Applications allow web developers to extend their applications to leverage more device capabilities. This is a particularly hot area of development for most platforms as this is seen as one of the best long term solution for minimising mobile development fatigue.

        Hybrid

        Next in the progression are hybrid applications which combine web technologies with a platform specific deployment package – this sounds a bit cryptic but that’s because there are a couple of different models for this.

        Firstly there’s the Cordova/PhoneGap model where the application is defined using html, css, javascript, and wrapped in a native platform deployment package. The deployment step is required in order for most stores to accept applications. The important thing here is that the layout and logic for the application is packaged with the application and that the platform web rendering engine is used to display the application.

        The second model is much more interesting and is one that’s being used by React Native and Native Script where the logic and layout is defined in javascript, css and a form of HTML. The HTML actually defines native elements that will be rendered in the correct location.

        Cross Platform

        Before we get to native platform tools and technologies, we’ll stop in on a long time friend, Xamarin. As with the previous sections there are again two options with Xamarin: traditional Xamarin, and Xamarin Forms. With the traditional Xamarin approach the developer is much closer to the metal and has a higher degree of control. However, the Xamarin Forms option allows for user interfaces to be rapidly developed once, and then feedback/issues are resolved on a platform by platform basis.

        Native Platform

        Lastly, we have the Native platform options for developers:

        Android

        Java, C++ with Eclipse, Android Studio

        iOS

        Objective C, Switft, Interface Builder (now part of XCode)

        UWP

        C#, XAML, Visual Studio (or Visual Studio for Mac)

        As this is hopefully one in a sequence of posts on the topic of framework selection, I’d love some feedback on what technology you think will be important to you and those you work with – comments are off but hit me up on twitter @thenickrandolph if you have thoughts on this.

        Making MvvmCross with Xamarin Forms Friction Free

        My last two posts (part 1 and part 2) outlined all the steps necessary to get a new Xamarin Forms with MvvmCross project setup. What I thought was going to be a simple post ended up being much longer due to all the unnecessary steps to setup both Xamarin Forms and MvvmCross. I’ve recently been contributing a little to MvvmCross and one of my concerns with it is that there are just way to many things that you need to get right in order to get it to work nicely with Xamarin Forms. If you don’t follow one of the introductory posts, such as the one provided by Martjin van Dijk, you’ll probably start hacking around with the numerous extension points in order to get it to work. I spent time over the last day seeing if I could reduce this initial friction to getting started.

        When you adopt a framework, or any library for that matter, you do so to reduce the need to reinvent the wheel – there’s no point in recreating, or creating something new, if there are existing solutions available. However, I’m of the opinion that you should be able to determine how much the framework influences the way that your code is structured. You should only have to modify your code if the framework offers a clear advantage. If we do a quick review of some of the changes required to take advantage of MvvmCross in our Xamarin Forms project you’ll see that quite a few of these are artificial requirements, mandated by the current MvvmCross implementation, rather than for any specific need. Here are just a couple:

        • App needs to inherit from MvxFormsApplication – this doesn’t add anything other than a couple of events, so unless you want to use those events, this is unnecessary
        • All pages need to inherit from the Mvx equivalent (eg MvxContentPage instead of ContentPage) – the Mvx equivalent expose a ViewModel property which can be useful but is not required in order to take advantages of data binding to the corresponding ViewModel since all Forms elements have a BindingContext that’s used for this purpose. The actual requirement here is for views/pages to implement IMvxView but unless you need the ViewModel property this shouldn’t be a requirement.
        • You need to create a class that inherits from MvxApplication which can do things like register services but most importantly defines what the starting ViewModel is going to be. This is kind of unnecessary if the only thing that it’s doing is defining the starting ViewModel, although I do understand the desire to have the starting ViewModel defined somewhere that is independent of the head projects.
        • All ViewModels need to inherit from MvxViewModel or implement IMvxViewModel – again this is somewhat unnecessary since ViewModels should just be a regular class. Now I do agree that in most cases your ViewModel is likely to implement INotifyPropertyChanged, so this additional requirements isn’t a massive addition but needless to say it shouldn’t be a requirement.

        Ok, so after a bit of experimenting without modifying MvvmCross or MvvmCross.Forms (ie I’m just using the NuGet packages) what I came up with is BuildIt.MvvmCross.Forms (currently in prerelease!) which is a NuGet package which adds a couple of helper classes to get you going just that bit quicker. Here are the steps to get started using BuildIt.MvvmCross.Forms:

        Start by following the steps outlined in part 1 – this will give you a Xamarin Forms project that’s completely up to date. I’ll call this project LowFriction

        Next, follow the early steps in part 2 to add an additional project for your ViewModels, LowFriction.Core, and subsequently add references to MvvmCross (to all projects) and MvvmCross.Forms (to all projects except the Core project).

        Add a reference to the BuildIt.MvvmCross.Forms NuGet package to all projects except the Core project. A primary requirement here is that the Core project should not have a reference to the view technology, which in this case is Xamarin Forms – if you find yourself adding a reference (directly or otherwise) to Xamarin Forms to your Core project, you’ve done something wrong and you should rethink the decisions that led you to that point.

        You still need to change App.xaml to inherit from MvxFormsApplication – I couldn’t find a work around this requirements

        Your pages do not need to change to implement iMvxView – MainPage inherits from ContentPage

        In your Core project you will need to create ViewModels that map to your pages, and they need to implement iMvxViewModel – again I couldn’t find a work around for this requirement. MainViewModel inherits from MvxViewModel.

        In your Core project you do not  need to create a class that inherits from MvxApplication – we’ll come to this later but essentially BuildIt.MvvmCross.Forms has class called TypedMvxApplication whose type parameter is the starting ViewModel. If you do want to extend the MvxApplication you can still create your own application but I would recommend using TypedMvxApplication as a starting point

        UWP

        In App.xaml.cs replace

        Xamarin.Forms.Forms.Init(e);

        with

        var setup = new SetupFromViewModel<MainViewModel, LowFriction.App>(rootFrame, e);
        setup.Initialize();

        You can see here that the SetupFromViewModel class accepts the starting ViewModel as a parameter. If you’d prefer to define the starting ViewModel in the Core project I recommend defining a class that inherits from TypedMvxApplication, specify the starting ViewModel as the type parameter, and then use the SetupFromApplication class in App.xaml.cs.

        Change MainPage to inherit from BuildIt.MvvmCross.Forms.UWP.MvxFormsWindowsPage (I also updated the layout of MainPage to show some data coming from databinding from the ViewModel, similar to what I did in my previous post)

        Change the MainPage constructor to

        public MainPage()
        {
             this.InitializeComponent();

            MvxLoadApplication();
        }

        Android

        Change MainActivity to inherit from CustomMvxFormsAppCompatActivity<SetupFromViewModel<MainViewModel, LowFrictionApp>, MainViewModel>

        Comment out the Xamarin Forms init code:

        //global::Xamarin.Forms.Forms.Init(this, bundle);
        //LoadApplication(new App());

        iOS

        Change AppDelegate to inherit from CustomMvxFormsApplicationDelegate

        Change FinishedLaunching

        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
             Window = new UIWindow(UIScreen.MainScreen.Bounds);

            var setup = new SetupFromViewModel<MainViewModel, App>(this, Window);
             setup.Initialize();

            MvxLoadApplication();

            Window.MakeKeyAndVisible();

            //global::Xamarin.Forms.Forms.Init();
             //LoadApplication(new App());

            return base.FinishedLaunching(app, options);
        }

        And we’re done! Build and run on each platform and you should be good to go.

        As you can see there are significantly fewer steps involved in getting started, and few additional classes to be created. I do note that there is still room for improvement and I feel that as frameworks go MvvmCross has been developed with extensibility in mind – which is why I was able to streamline the getting started experience so much.

        Getting Started: MvvmCross with Xamarin Forms (Part 2)

        In my previous post I covered the first part of this post on Getting Started with MvvmCross and Xamarin Forms where I covered the initial steps in getting a new Xamarin Forms project started. In this post I’m going to continue on and show how you can configure a Xamarin Forms solution to make use of MvvmCross.

        Before I get started with MvvmCross I’m going to add a new project which will contain all my ViewModels. Whilst not entirely necessary, particularly with Xamarin Forms where the views/pages are in a .NET Standard library, it’s good practice to completely separate your ViewModels away from the views/pages to avoid any accidental interdependencies forming. I’ll add a new project based on the .NET Standard class library template.

        image_thumb11[1]

        For this library I’m going to adjust the .NET Standard version back to 1.0 – I prefer to start with a low .NET Standard version and increase it only when I need to take advantage of features in the higher versions. This ensures that the library can be referenced by the widest set of targets platforms.

        image_thumb11

        I’ll add a reference to the new project to each of the other projects in the solution.

        image_thumb31

        The next step is to add a reference to the MvvmCross NuGet package. Currently MvvmCross is still distributed as a set of Portable Class Libraries and if we attempt to add the NuGet package to either our MvvmcrossGettingStarted or MvvmcrossGettingStarted.Core projects, we’ll get an error as they’re both .NET Standard library. What’s annoying about this is that the MvvmCross PCLs are fully compatible with .NET Standard, meaning that it should be possible to add a reference to them. Unfortunately Visual Studio isn’t clever enough to be able to resolve this, and as such we need to adjust the csproj files for both projects before attempting to add a reference to MvvmCross.

        Add the following line into the first PropertyGroup of the csproj files for both MvvmcrossGettingStarted or MvvmcrossGettingStarted.Core projects. One saving grace is that it’s now easy in Visual Studio to edit a csproj by right-clicking on the project and selecting “Edit <project name>.csproj”.

        <PackageTargetFallback>$(PackageTargetFallback);portable-net45+win8+wpa81</PackageTargetFallback>

        Eg.

        image_thumb23

        Next we can go ahead and add a reference to MvvmCross to all our projects. Right-click on the solution node in Solution Explorer and select Manage NuGet Packages for Solution, and then search for mvvmcross. Select the most recent stable version of MvvmCross (this image is a little old as the version is at 5.6.3 at time of writing this)

        image_thumb9

        In addition to the main MvvmCross package, we also want to add in the Xamarin Forms support library, MvvmCross.Forms. Note that we do not add this to the MvvmcrossGettingStarted.Core project – this is the separation of concerns we setup at the beginning of this post to ensure there is no dependencies on the viewing technology within our ViewModels.

        image_thumb21

        Now that we have added the references to MvvmCross there are a bunch of small changes we need to apply to our application in order to get it all up and running. We’ll start in the MvvmcrossGettingStarted.Core project where we need to create two classes.

        The first class we’ll create inherits from MvxApplication and is used to setup the application within the ViewModel world. MvvmCross has an opinionated navigation model whereby navigation is defined at a ViewModel level, and simply implemented at a View level. As such the MvxApplication class, in this case GettingStartedApplication, defines the first ViewModel for the application.

        public class GettingStartedApplication : MvxApplication
        {
             public override void Initialize()
             {
                 RegisterNavigationServiceAppStart<MainViewModel>();
             }
        }

        The second class is the ViewModel that matches the first view or page of the application. MainPage was created back when we created the Xamarin Forms application, so we’ll create a class called MainViewModel. Whilst you can override the default view to viewmodel mapping in MvvmCross, it’s preconfigured to align views and viewmodels based on a naming convention. I typically stick with XXXViewModel and XXXPage but XXXView is also supported out of the box.

        In this case MainViewModel exposes a simple property that we’ll data bind to later to show that the Page and ViewModel have been glued together correctly.

        public class MainViewModel: MvxViewModel
        {
             public string WelcomeText => "Welcome to my data bound Xamarin Forms + MvvmCross application!";
        }

        Now we’ll switch over to the MvvmcrossGettingStarted project and make some changes to both the App and MainPage classes.

        In the App.xaml, we need to change the root element to reference MvxFormsApplication

        <?xml version="1.0" encoding="utf-8" ?>
        <mvx:MvxFormsApplication xmlns="
        http://xamarin.com/schemas/2014/forms"
                             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                             xmlns:mvx="clr-namespace:MvvmCross.Forms.Platform;assembly=MvvmCross.Forms"
                            
        x:Class="MvvmcrossGettingStarted.App">
             <Application.Resources>
             </Application.Resources>
        </mvx:MvxFormsApplication>

        And in App.xaml.cs, remove the inheritance – the Microsoft templates insist on including the inheritance in both the xaml and xaml.cs files which is quite unnecessary and should be removed.

        public partial class App
        {
             public App()
             {
                 InitializeComponent();
             }
        }

        We need to make a similar change to MainPage.xaml, changing the root element to MvxContentPage. We’ll also change the Label to use data binding to return the WelcomeText property from the MainViewModel.

        <?xml version="1.0" encoding="utf-8" ?>
        <mvx:MvxContentPage xmlns="
        http://xamarin.com/schemas/2014/forms"
                             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                             xmlns:local="clr-namespace:MvvmcrossGettingStarted"
                             xmlns:mvx="clr-namespace:MvvmCross.Forms.Views;assembly=MvvmCross.Forms"
                            
        x:Class="MvvmcrossGettingStarted.MainPage">
             <Label Text="{Binding WelcomeText}"
                    VerticalOptions="Center"
                    HorizontalOptions="Center" />
        </mvx:MvxContentPage>

        Again, remove the inheritance specified in MainPage.xaml.cs

        public partial class MainPage
        {
             public MainPage()
             {
                 InitializeComponent();
             }
        }

        The next step involves adding a Setup class to each of the head projects, and then creating an instance of the Setup class to invoke MvvmCross when the application starts up.

        UWP

        The UWP Setup inherits from MvxFormsWindowsSetup and unlike the Android and iOS Setup classes, the UWP Setup needs to override the default log behaviour by setting the log provider type to None and then creating an instance of the EmptyVoidLogProvider  (the implementation of this is coming up soon) – this should be fixed in a future MvvmCross version.

        public class Setup : MvxFormsWindowsSetup
        {
             public Setup(Frame rootFrame, LaunchActivatedEventArgs e) : base(rootFrame, e)
             {
             }

            protected override MvxLogProviderType GetDefaultLogProviderType() => MvxLogProviderType.None;

            protected override IMvxLogProvider CreateLogProvider() => new EmptyVoidLogProvider();

            protected override IEnumerable<Assembly> GetViewAssemblies()
             {
                 return new List<Assembly>(base.GetViewAssemblies().Union(new[] { typeof(MvvmcrossGettingStarted.App).GetTypeInfo().Assembly }));
             }

            protected override MvxFormsApplication CreateFormsApplication() => new MvvmcrossGettingStarted.App();

            protected override IMvxApplication CreateApp() => new Core.GettingStartedApplication();
        }

        Now in App.xaml.cs we need to replace

        Xamarin.Forms.Forms.Init(e);

        with

        var setup = new Setup(rootFrame, e);
        setup.Initialize();

        And in Main.xaml.cs replace

        LoadApplication(new MvvmcrossGettingStarted.App());

        with

        var start = Mvx.Resolve<IMvxAppStart>();
        start.Start();

        var presenter = Mvx.Resolve<IMvxFormsViewPresenter>() as MvxFormsUwpViewPresenter;
        LoadApplication(presenter.FormsApplication);

        Finally, we need to add the EmptyVoidLogProvider

        public class EmptyVoidLogProvider : IMvxLogProvider
        {
             private readonly EmptyVoidLog voidLog;

            public EmptyVoidLogProvider()
             {
                 voidLog = new EmptyVoidLog();
             }

            public IMvxLog GetLogFor<T>()
             {
                 return voidLog;
             }

            public IMvxLog GetLogFor(string name)
             {
                 return voidLog;
             }

            public IDisposable OpenNestedContext(string message)
             {
                 throw new NotImplementedException();
             }

            public IDisposable OpenMappedContext(string key, string value)
             {
                 throw new NotImplementedException();
             }

            public class EmptyVoidLog : IMvxLog
             {
                 public bool Log(MvxLogLevel logLevel, Func<string> messageFunc, Exception exception = null, params object[] formatParameters)
                 {
                     return true;
                 }
             }
        }

        Now when we build and run the UWP project we can see that the MainPage is shown and is data bound to the MainViewModel.

        image

        iOS

        The iOS Setup is the simplest out of the three platforms.

        public class Setup : MvxFormsIosSetup
        {
             public Setup(IMvxApplicationDelegate applicationDelegate, UIWindow window)
                 : base(applicationDelegate, window)
             {
             }

            protected override IEnumerable<Assembly> GetViewAssemblies()
             {
                 return new List<Assembly>(base.GetViewAssemblies().Union(new[] { typeof(MvvmcrossGettingStarted.App).GetTypeInfo().Assembly }));
             }

            protected override MvxFormsApplication CreateFormsApplication() => new MvvmcrossGettingStarted.App();

            protected override IMvxApplication CreateApp() => new Core.GettingStartedApplication();
        }

        In AppDelegate we need to change the inheritance from  global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate to MvxFormsApplicationDelegate and change the FinishedLaunching method as follows:

        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
             Window = new UIWindow(UIScreen.MainScreen.Bounds);

            var setup = new Setup(this, Window);
             setup.Initialize();

            var startup = Mvx.Resolve<IMvxAppStart>();
             startup.Start();

            LoadApplication(setup.FormsApplication);

            Window.MakeKeyAndVisible();

            return base.FinishedLaunching(app, options);
        }

        Now we’re good to build and run the iOS project

        image

        Android

        Lastly, add Setup to the Android project. Note this is slightly different from the iOS and UWP projects in that the GetViewAssemblies method excludes the assembly for the Android head project. This is to avoid the MainActivity being added as a view, that based on our naming convention would match with MainViewModel giving a duplicate when attempting to resolve the View that should be rendered.

        public class Setup : MvxFormsAndroidSetup
        {
             public Setup(Context applicationContext) : base(applicationContext)
             {
             }

            protected override IEnumerable<Assembly> GetViewAssemblies()
             {
                 return new List<Assembly>(base.GetViewAssemblies()
                     .Union(new[] { typeof(MvvmcrossGettingStarted.App).GetTypeInfo().Assembly })
                     .Except(new[] {this.GetType().Assembly})
                     );
             }

            protected override MvxFormsApplication CreateFormsApplication() => new MvvmcrossGettingStarted.App();

            protected override IMvxApplication CreateApp() => new Core.GettingStartedApplication();
        }

        The MainActivity needs to be updated to change its inheritance from global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity to MvxFormsAppCompatActivity<MainViewModel>. And the OnCreate needs to be updated to

        [Activity(Label = "MvvmcrossGettingStarted", Icon = "@drawable/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
        public class MainActivity : MvxFormsAppCompatActivity<MainViewModel>
        //global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
        {
             protected override void OnCreate(Bundle bundle)
             {
                 TabLayoutResource = Resource.Layout.Tabbar;
                 ToolbarResource = Resource.Layout.Toolbar;

                base.OnCreate(bundle);

                var startup = Mvx.Resolve<IMvxAppStart>();
                 startup.Start();
                 InitializeForms(bundle);

             }
        }

        Finally the last platform, Android, is good to build and run. Note however that Android has a tendency to be a pain and that after setting everything up correctly you may still run into issues building, deploying and running. Before you waste hours looking at your code to see what you’ve done wrong, make the assumption that the tools are crap – delete both bin and obj folders from the Android head project, and uninstall the application from the device/emulator (assuming it has already been installed). Try building and running again – if this still fails, then you may indeed have something wrong with your code!

        image

        Getting Started: MvvmCross with Xamarin Forms

        Over the past 6-12 months we’ve seen dramatic changes in Xamarin Forms and the support within Visual Studio. The most recent update, which I covered in my previous post, included a number of new features for cross platform developers. However, despite these updates, getting started with cross platform development is still quite complex. In this post I wanted to take the opportunity to reiterate how to start a new Xamarin Forms project. From there I’ll cover adding in MvvmCross and discuss the importance of having a framework that will make development that much easier (for the record MvvmCross isn’t the only option, there are plenty of great alternatives such as Prism and FreshMvvm).

        Part 1: Getting Started with Xamarin Forms

        Before getting started, make sure you’ve run the Visual Studio Installer and have upgraded to the latest stable release of Visual Studio. The team at Microsoft have been putting a lot of focus on stability and performance, so upgrading to the latest version does help (still not perfect but a marked improvement over this time last year!). Upgrading Visual Studio continually can be a bit of a pain, especially since Microsoft haven’t quite worked out how to automatically download updates in the background for VS – meaning that you have to stop whatever you’re doing whilst the updates download and then install. Recommendation is to run the installer periodically at the end of your day, or when you’re heading to a long meeting; hopefully the installation is complete by the time you return.

        Now that you’re all up to date, let’s create a new solution by selecting the Cross-Platform App (Xamarin Forms) template from the New Project dialog. Note that if you don’t see this template, you may have to adjust the workloads you selected in the VS Installer so that you have all the cross-platform development components selected.

        image

        After clicking OK you should be presented with a second dialog that allows you to specify parameters for how your cross platform project should be setup. As you can see from the image, I recommend always selecting all three platforms (even if you’re only planning on targeting one or two of them initially); In this case we’re going with Xamarin.Forms with a simple Blank App; The last option I’m particularly passionate about – do NOT select Shared Project – for the good of your project, the team and general good programming practice, please select the .NET Standard option for Code Sharing Strategy. At time of writing the .NET Standard option is only available in the preview build of Visual Studio; the stable build uses a Portable Class Library, which is still preferable over using a Shared Project.

        image

        This time clicking OK will create a new solution.

        Unexpected Error when Creating Solution

        Unfortunately, at time of writing this post there is also a bug in the current cross platform template that results in the following error:

        image

        If you see this error, a quick Google will yield the following bugzilla issue (https://bugzilla.xamarin.com/show_bug.cgi?id=60995) which describes the issue, along with how to fix it yourself – you just need to edit the Android csproj file and remove the " from around the TargetFrameworkVersion ie:

        replace:

        <TargetFrameworkVersion>"v8.0"</TargetFrameworkVersion>

        with
        <TargetFrameworkVersion>v8.0</TargetFrameworkVersion>

        After fixing up the csproj file you’ll need to add the existing projects into the solution file.

        Assuming you didn’t run into any issues creating the solution, or you were able to fix up the Android csproj file, you should be able to build and run each of the head projects:

        UWP

        image

        Note: When building the UWP project I was seeing a build warning stating “warning APPX0108: The certificate specified has expired.” which I thought was a bit odd since I had just created the project and normally the certificate that is used for debug builds is created alongside the new project. Double-clicking the package.appxmanifest and switching to the Packaging tab I see that the Publisher display name isn’t set correctly – I’m guessing at this point that the cross platform template contains an existing certificate, instead of creating one each time. You can easily fix this by changing the publisher display name, clicking Choose Certificate and then from the dropdown select “Create test certificate”.

        image

        Now when you build the project you won’t see this warning – I’m guessing this is also a bug in the preview version of the cross platform template.

        Android

        image

        For Android I’m using the Google Android Emulator that can now be installed using the Visual Studio Installer. This is significantly better than it used to be, and the images are much more recent than those for the Visual Studio Android Emulator which has been deprecated now.

        iOS

        image

        For iOS, as I’m working from a Windows laptop, I use the Remote Simulator which works really well and means I don’t need to continually VNC to my MacMini or have to deploy to a real device.

        Again there was an issue with the iOS template in that the MinimumOSVersion was set to “11.2” instead of just 11.2 in the Info.plist file.

        <key>MinimumOSVersion</key>
        <string>11.2</string>

        Correcting the MinimumOSVersion will allow your application to run on a device or emulator.


        Now that we’ve validated that all the platforms run, it’s time to make sure they’re setup correctly ready for us to add in Mvvmcross and to set the foundation of our application. Android and iOS should be setup correctly, although you may want to double-check to make sure Android is set to use the latest platform version (see Application tab of the Android project properties); UWP defaults to using the Fall Creators Update (FCU) as the minimum version, which is way to recent for applications wanting to target the widest set of customers. Our preferences is to set this back to the November Update

        image

        Note however, that this does preclude your application from using .NET Standard 2.0 libraries, as these are not compatible with UWP projects prior to the FCU. Unfortunately the .NET Standard library that holds the Xamarin Forms views for the solution is set to .NET Standard 2.0 by default. This is completely unnecessary, so it can be reduced back to 1.4 (or below, depending on your preferences)

        image

        Next, we want to make sure we’re using the latest NuGet packages – right-click on the solution node in Solution Explorer and select Manage NuGet Packages for Solution

        image

        After upgrading all the NuGet packages, double-check to make sure all platforms build and run. Now’s a great time to check your solution in to your repository of choice (Note: make sure you check in the pfx file that is part of the UWP solution. You’ll probably have to manually add this file to your repository as most repositories ignore pfx files by default).

        Update: Part 2 is now available.

        View Model States and Connecting them to Xamarin Forms Visual States using BuildIt

        In my previous post on Getting Started with Visual States in Xamarin Forms using BuildIt.Forms I showed a very basic example of defining and triggering Visual States within a Xamarin Forms application. However, most applications have more complexity where each page is typically data bound to a corresponding ViewModel and it is the ViewModel which encapsulated the logic of the application.

        Let me walk through working with a ViewModel using the same basic example I started in my previous post. In this case I’m going to add another panel to the page which will be displayed after the user clicks the Login button, effectively simulating the experience of showing a progress indicator whilst the application is authenticating the user.

        <!-- Authenticating Prompt -->
        <Grid BackgroundColor="LightPink"
                 x:Name="AuthenticatingIndicator"
                 IsVisible="false">
             <Label Text="Attempting to authenticate you..."
                     HorizontalTextAlignment="Center"
                     VerticalOptions="Center" />
        </Grid>
        <!-- END Authenticating Prompt –>

        In this case I’m going to add a new VisualStateGroup to define the visual states to hide and show the AuthenticatingIndicator Grid.

        <vsm:VisualStateGroup Name="AuthenticationStates">
             <vsm:VisualState Name="Authenticating">
                 <vsm:VisualState.Setters>
                     <vsm:Setter Element="{x:Reference AuthenticatingIndicator}"
                                 Property="IsVisible"
                                 Value="true" />
                 </vsm:VisualState.Setters>
             </vsm:VisualState>
             <vsm:VisualState Name="NotAuthenticating" />
        </vsm:VisualStateGroup>

        A VisualStateGroup is designed to hold mutually exclusive states. A page can have any number of VisualStateGroups, and at any given point in time the current state of the page can consist of being in one VisualState from each group. In this scenario we have broken the authenticating states away from the loading states because in theory you might want to disply both the AuthenticatingIndicator, as well as the LoadingIndicator.

        The last piece of XAML that I need to update is to attach an event handler to the Clicked event of the Button:

        <Button Text="Login"
                 Clicked="LoginPressed" />

        And in the code behind, define the corresponding LoginPressed method (and yes, those MVVM purist will argue that this would be better using the Command property through to the ViewModel but we’ll leave that for another post):

        protected async void LoginPressed(object sender, EventArgs e)
        {
        }

        Now that we have the XAML defined, it’s time to look at how we can drive this from our ViewModel. In my case the page I’m working with is called MainPage.xaml, so I’m going to define a class called MainViewModel in a separate .NET Standard library. I’m not going to add a reference to BuildIt.Forms to the .NET Standard library because that would bring in a reference to Xamarin Forms, which should not be referenced by the library that holds your ViewModels – they should be abstracted away from any concrete interface, which includes Xamarin Forms, even though it is itself an abstraction from the native platform interfaces. What I am going to reference is the BuildIt.States library, which is a .NET Standard library that has no reference to any specific user interface framework, making it perfect for managing states within your ViewModel.

        Alongside the MainViewModel class I’m also going to define an enumeration where the names match the corresponding visual states: the enum type name has to match the VisualStateGroup name and the enum values have to match the VisualState name.

        public enum AuthenticationStates
        {
             Base,
             Authenticating,
             NotAuthenticating
        }

        The enum also has an additional value, Base, which is will be the default enum value. The name of this value is irrelevant but it’s important to have it as the first value and should not correspond to any VisualState name.

        The MainViewModel class includes a StateManager property. In this case the constructor calls the extension method DefineAllStates to define states for each value of the AuthenticationState enum. The BuildIt States library has a host of great features that are worth explaining but I’ll save that topic for another post. The important thing is that each of the states for the AuthenticationState enum are defined.

        public class MainViewModel
        {
             public IStateManager StateManager { get; } = new StateManager();

            public MainViewModel()
             {
                 StateManager.Group<AuthenticationStates>().DefineAllStates();
             }

            public async Task Login()
             {
                 await StateManager.GoToState(AuthenticationStates.Authenticating);

                await Task.Delay(2000);

                await StateManager.GoToState(AuthenticationStates.NotAuthenticating);
             }
        }

        The Login method simply calls the GoToState method prior to calling Task.Delay, to simulate attempting to authenticate the user, and then again calling GoToState to change the state back to the NotAuthenticating state.

        Now that we have our MainViewModel defined, I need to connect it to my MainPage. For real applications we work on at Built to Roam, we use frameworks such as MvvmCross to connect the View and ViewModels. However, for brevity I’m going to simply create an instance of the MainViewModel as part of the MainPage:

        private MainViewModel ViewModel { get; } = new MainViewModel();

        And then set the instance as the BindingContext of the page, in the constructor:

        public MainPage()
        {
             InitializeComponent();

            BindingContext = ViewModel;
        }

        Lastly, I’ll update the LoginPressed method to call the method on the MainViewModel:

        protected async void LoginPressed(object sender, EventArgs e)
        {
             await ViewModel.Login();
        }

        At this point we’re almost done: We have a ViewModel that defines the states of the application in a way that they can be tested in absence of any user interface implementation, and the View (in this case the MainPage) will invoke the Login method to trigger the state changes. The only missing component is connecting the Visual States defined on the MainPage XAML, with the states defined in the MainViewModel. This is done using the Bind method within the OnAppearing override:

        await VisualStateManager.Bind(this, ViewModel.StateManager);

        Now I’m ready to go – at this point the user experience is entirely defined in XAML, with all my logic, including the states, encapsulated within my ViewModel, ready to be tested.

        Getting Started with Visual States in Xamarin Forms using BuildIt.Forms

        Over the past couple of months we’ve been working on getting the BuildIt.Forms library to a point where it was stable enough to promote and talk about. With the recent release of the 2.4 update for Xamarin Forms, we’re finally able to push out a stable release.

        The BuildIt.Forms library brings with it quite a few features but probably the best reason to use the library is the support it adds for defining Visual States within your Xamarin Forms application within the XAML, just like you would if you were building using XAML for UWP (or any other XAML platform such as WPF etc). We’ve tried to stay as true as possible to the syntax for Visual States used on other platforms but like all things Xamarin Forms there are some differences that you’ll need to get your head around.

        Ok, before we jump in, let’s take a back step and look at what a Visual State really is, and why you’d want to use them. Let’s start with a very simple example – imagine you have a page within your application that needs to load some data and you want to provide a visual cue that something is happening. In this case I’m going to add a simple overlay with some text indicating that information is being loaded:

        <!-- Loading Prompt -->
        <Grid BackgroundColor="LightGray"
                 x:Name="LoadingIndicator"
                 IsVisible="false">
             <Label Text="Loading..."
                     HorizontalTextAlignment="Center"
                     VerticalOptions="Center" />
        </Grid>
        <!-- END Loading Prompt –>

        Note that the default IsVisible value is false, meaning that the LoadingIndicator Grid will not be visible. In the codebehind of the page I can then add code that would show the LoadingIndicator Grid, simulate loading content (ie Task.Delay), and then hide the LoadingIndicator Grid.

        protected override async void OnAppearing()
        {
             base.OnAppearing();

            LoadingIndicator.IsVisible = true;

            await Task.Delay(2000);

            LoadingIndicator.IsVisible = false;
        }

        Of course in a real application you wouldn’t do this, as there should be at least a ViewModel that would do the loading but we’ll come back to the use of ViewModels later. For the moment, it’s enough to point out that we controlling the appearance of individual elements based on the state of the page (ie showing the LoadingIndicator when the page is in the loading state). What would be great is if we could declare these states in XAML, which is where the BuildIt Forms library comes in.

        I’ll add a few namespaces to the XAML for the page (mainly so I don’t forget to add them later when we talk about animations and other controls in the BuildIt Forms library):

        xmlns:ctrl="clr-namespace:BuildIt.Forms.Controls;assembly=BuildIt.Forms.Controls"
        xmlns:vsm="clr-namespace:BuildIt.Forms;assembly=BuildIt.Forms.Core"
        xmlns:anim="clr-namespace:BuildIt.Forms.Animations;assembly=BuildIt.Forms.Core"

        Next, immediately inside the root tag of the page, I’ll define two visual states:

        <vsm:VisualStateManager.VisualStateGroups>
             <vsm:VisualStateGroups>
                 <vsm:VisualStateGroup Name="LoadingStates">
                     <vsm:VisualState Name="Loading">
                         <vsm:VisualState.Setters>
                             <vsm:Setter Element="{x:Reference LoadingIndicator}"
                                         Property="IsVisible"
                                         Value="true" />

                         </vsm:VisualState.Setters>
                     </vsm:VisualState>
                     <vsm:VisualState Name="Loaded" />
                 </vsm:VisualStateGroup>
             </vsm:VisualStateGroups>
        </vsm:VisualStateManager.VisualStateGroups>

        The important things to note are the names of the states: Loading and Loaded, and the use of a Setter element to adjust the IsVisible property on the LoadingIndicator element. Note that I didn’t need to set the IsVisible property to false in the Loaded state – this is because the default value of the IsVisible property on the LoadingIndicator is set to false, and the Visual State manager is clever enough to remember that when switching between states.

        Now that we have visual states defined, let’s switch to the code behind and adjust the code to use the visual states:

        protected override async void OnAppearing()
        {
             base.OnAppearing();
            await VisualStateManager.GoToState(this, "Loading");
            await Task.Delay(2000);
             await VisualStateManager.GoToState(this, "Loaded");
        }

        It looks like we haven’t made any great improvements but here’s where the power is – let’s add some content to the screen that will be shown when the loading is complete:

        <!-- Login Prompt -->
        <Grid x:Name="LoginPrompt"
                 IsVisible="False">
             <StackLayout>
                 <Label Text="Username:" />
                 <Editor />
                 <Label Text="Password:" />
                 <Editor />
                 <Button Text="Login" />
             </StackLayout>
        </Grid>
        <!-- END Login Prompt –>

        In the past, this would have required more code in the code behind to adjust the IsVisible property on the LoginPrompt Grid in order to show the content. With visual states, there is no need to alter the logic of the application, I just need to adjust the Loaded visual state by adding a Setter to set the IsVisible property to true.

        <vsm:VisualState Name="Loaded">
             <vsm:VisualState.Setters>
                 <vsm:Setter Element="{x:Reference LoginPrompt}"
                             Property="IsVisible"
                             Value="true" />

             </vsm:VisualState.Setters>
        </vsm:VisualState>

        At the moment I have built an interface that provides useful feedback to the user about the loading state of the application. However, there is a rather abrupt change between the LoadingIndicator Grid and the LoginPrompt. It would be nice to be able to add animations to make the transition smoother. Again without adjusting the logic of the application I can do this by adding animations directly to the visual states. The following animation can be added after the Setters of the Loading state.

        <vsm:VisualState.LeavingAnimations>
             <anim:AnimationGroup>
                 <anim:AnimationGroup.PreAnimations>
                     <anim:FadeAnimation Duration="500"
                                         Opacity="0"
                                         Element="{x:Reference LoadingIndicator}" />
                 </anim:AnimationGroup.PreAnimations>
             </anim:AnimationGroup>
        </vsm:VisualState.LeavingAnimations>

        In this case the animation will be run prior to (ie a PreAnimation) any state change away from (ie a LeavingAnimation) the Loading state, and will fade the LoadingIndicator Grid out to 0 Opacity over a duration of 500 milliseconds.

        In this post I’ve covered the basics of creating Visual States. In my next post I’ll cover using states in a ViewModel and how you can link them to the Visual States on the page to give you a more testable application.

        Getting Started: Xamarin Forms with .NET Standard 2.0

        In my earlier post Getting Started: Xamarin Forms with .NET Standard I covered how to create a new Xamarin Forms project which uses a .NET Standard 1.4 library to share the views between iOS, Android and UWP. At the time, whilst iOS and Android supported .NET Standard 2.0, support still wasn’t available for UWP. Almost immediately after publishing the blog post, Microsoft announced that Visual Studio 2017 preview 15.4 would allow UWP applications to reference .NET Standard 2.0 libraries. Unfortunately this didn’t work in the first drop, 15.4.0 Preview. This was just updated to 15.4.0 Preview 2 (Release Notes: https://www.visualstudio.com/en-us/news/releasenotes/vs2017-preview-relnotes), which brings with it the support we’ve been after. In this post, I’m going to repeat the previous post on getting started with .NET Standard, this time using .NET Standard 2.0 for the UI project.

        Let’s walk through the basics – create a new Cross Platform App (same as before)

        image

        Select the Xamarin.Forms (UI Technology) and Portable Class Library (PCL) (Code Sharing Strategy) – Don’t pick the Shared Project option!

        image

        Select the Insider Preview version of UWP for both Minimum and Target version – this is required for .NET Standard 2.0 support. If you want to target earlier versions of Windows 10, you’ll have to stick with .NET Standard 1.4.

        image

        Next, we’re going to replace the PCL with a new .NET Standard library

        image

        I’ll copy the App.xaml, App.xaml.cs, MainPage.xaml and MainPage.xaml.cs from the PCL into the .NET Standard library, before deleting the PCL from the project (see https://nicksnettravels.builttoroam.com/post/2017/08/26/Getting-Started-Xamarin-Forms-with-NET-Standard.aspx for more detailed instructions).

        The big difference is that I’m not going to change the default Target Framework, leaving it as .NET Standard 2.0.

        image

        Next I need to make sure I add and upgrade references to Xamarin.Forms to each of the projects – this isn’t actually required, since the stable release of Xamarin Forms will actually work with .NET Standard but I’ve been working with the pre-release version quite a bit lately, so I’ll go with that for this example.

        image

        I also need to remember to add a reference to the .NET Standard project to each of the head projects for iOS, Android and UWP.

        image

        If you attempt to build and run at this point iOS and Android should work without issue. UWP will most likely compile but will raise an exception “Could not load file or assembly ‘netstandard, Version=2.0.0.0….” at runtime.

        image

        Essentially the UWP project structure has evolved a little, so you need to upgrade it. Now I think that you may be able to do this via package manager but I’ve never got it to work for UWP projects, so I will make the changes manually to the csproj file. Start by deleting the project.json file from the UWP project.

        Next right-click the UWP project in Solution Explorer and select unload project. Next, right-click on the UWP project node and select Edit MySecondXamarinFormsApp.UWP.csproj.

        Add a new PropertyGroup – this changes the way packages are referenced, eliminating the need for the project.json file, replacing it with references within the csproj file.

        <PropertyGroup>
           <RestoreProjectStyle>PackageReference</RestoreProjectStyle>
        </PropertyGroup>

        image

        Next we need to add back the package references that were in the project.json – if you’re doing this on an existing project, you may want to keep the project.json file handy so you know which packages to add. In this case there are just two projects:

        <ItemGroup>
           <PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
             <Version>6.0.0-preview1-25631-01</Version>
           </PackageReference>
           <PackageReference Include="Xamarin.Forms">
             <Version>2.4.0.269-pre2</Version>
           </PackageReference>
        </ItemGroup>

        image

        Now you can right-click on the UWP project in Solution Explorer and select Reload project. Trigger a rebuild and now you should be able to run the UWP project.

        image

        Getting Started: Xamarin Forms with .NET Standard

        With the recent release of Visual Studio 2017 v15.3 (and subsequent patch release 15.3.1 and 15.3.2…. yes, it does say something about ship quality Sad smile) came the release and support for .NET Standard 2.0. The Xamarin team also made a lot of noise about support for .NET Standard 2.0; unfortunately this doesn’t yet translate into Visual Studio templates that easily get you started. My particular annoyance is the about of steps you need to go through in order to just spin up a new Xamarin Forms application that can reference .NET Standard libraries. I thought I’d piggyback of a post done a couple of months back by Pierce Boggan. Here goes:

        Start by creating a new project in Visual Studio 2017, selecting the Cross Platform App (Xamarin) project template:

        image

        Next, select the template you want (I’m going with the Blank App), the UI Technology and Code Sharing Strategy. As I’m going to be walking through how to use Xamarin Forms, it makes sense to pick that as the option for UI Technology. Only select the Portable Class Library option. Don’t use the Shared Project – using a shared project will lead you down the evil road of using conditional compilation which will be a maintenance nightmare, just don’t use it. I don’t care how great you think it is, don’t use it. One last time, don’t use the Shared Project option.

        image

        Now that I’ve expressed my opinion on code sharing strategies, let’s click the OK button and get on with building our application. As the template goes through generating the head projects for iOS, Android and UWP, it will prompt you to select the target and minimum platforms for UWP. For the most part, unless you have specific target platform requirements for UWP, you can leave the default settings.

        image

        The generated solution will have four projects: three head or target platform projects (for iOS, Android and UWP) and a portable class library (PCL) which contains the XAML pages that will make up your Xamarin Forms application layout. In order to proceed with .NET Standard support we need to replace the PCL with a .NET Standard library. Whilst Visual Studio used to have a mechanism for upgrading a library from a PCL to a .NET Standard library, this has been removed. Now the easiest way is to simply create a new project, and copy the relevant files into the new project. From the Add New Project dialog, select the Class Library (.NET Standard) template.

        image

        I use the .UI naming convention for the library that will contain my XAML pages. Other developers use .Core but my preference is to separate my XAML pages away from my view models. Whilst technically with Xamarin Forms they can reside in the same library, I prefer to have a clean separation between them. I have <applicationname>.UI with my XAML pages in it and <applicationname>.Core with my view models, services, entities, essentially all the business logic for my application.

        For this example I’m going to keep it simple and we’ll just create the .UI project for the moment.

        image

        I don’t need the default Class1.cs, so I’ll remove that. I’ll add a reference to the .NET Standard library to all the head projects.

        I’m also going to drop the .NET Standard version back from 2.0 (now the default in Visual Studio) back to 1.4. Whilst the tooling has been updated for the head projects for iOS and Android to support .NET Standard 2.0, of course, UWP is still lagging the field, as so you won’t be able to use a .NET Standard 2.0 library until that’s fixed. To be honest though, not much is lost by lowering the version of the .UI project to 1.4 since all the features of Xamarin Forms are still there.

        image

        Next I’m going to copy App.xaml (and App.xaml.cs) and MainPage.xaml (and MainPage.xaml.cs) from the PCL into the newly created .NET Standard library. Once I’ve copied these files across I can remove the PCL project from the solution – this will remove the references to this library from each of the head projects. After coping these files across, you may well see a compilation error similar to the following:

        1>------ Build started: Project: MyFirstXamarinFormsApp.UI, Configuration: Debug Any CPU ------
        1>C:\Program Files\dotnet\sdk\2.0.0\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Sdk.DefaultItems.targets(274,5): error : Duplicate 'EmbeddedResource' items were included. The .NET SDK includes 'EmbeddedResource' items from your project directory by default. You can either remove these items from your project file, or set the 'EnableDefaultEmbeddedResourceItems' property to 'false' if you want to explicitly include them in your project file. For more information, see
        https://aka.ms/sdkimplicititems. The duplicate items were: 'App.xaml'; 'MainPage.xaml'
        1>Done building project "MyFirstXamarinFormsApp.UI.csproj" -- FAILED.

        If you do, you just need to edit the project file for the .UI project and remove the App.Xaml and MainPage.xaml EmbeddedResource elements. The new project format includes files by default and the tooling isn’t smart enough to realise that the sample files are being added multiple times. Removing these elements will fix the compilation:

        <ItemGroup>
           <EmbeddedResource Include="App.xaml">
             <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
           </EmbeddedResource>
           <EmbeddedResource Include="MainPage.xaml">
             <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
           </EmbeddedResource>
        </ItemGroup>

        The last thing to do is to make sure that the .NET Standard library references Xamarin Forms. I’m going to do that by right-clicking the solution node in Solution Explorer and selecting Manage Nuget Package for Solution.

        image

        I’m going to select the new prerelease version of Xamarin Forms (which is the one where they’ve apparently added .NET Standard support). In addition to adding a reference to Xamarin Forms to the UI project, I also take this opportunity to upgrade all the package references in the application. Note that I’ve even selected the Android support packages – this used to be a big No-No but with the latest version of the tooling you can now go ahead and update them, and I would definitely encourage you to do so.

        image

        Now, go make yourself a coffee – Nuget is slow, so slow! The good news is that once you’ve done all these steps, you’re ready to go with a .NET Standard based Xamarin Forms project. If you’re following this post to get started on your own project, you can finish up here, as you’re good to go.

        Ok, so all of that, and what can we do. We’ll for a starters, it makes it super easy to add nuget packages such as BuildIt Forms which has a bunch of helper controls and features to get you building richer applications. Let’s add a reference to the BuildIt.Forms Nuget package the project:

        image

        After adding the reference to BuildIt.Forms we can make use the added controls. For example the ContentButton allows us to easily add a button that contains any XAML content, whilst still maintaining the pressed and hover states:

        <?xml version="1.0" encoding="utf-8" ?>
        <ContentPage xmlns="
        http://xamarin.com/schemas/2014/forms"
                      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                      xmlns:local="clr-namespace:MyFirstXamarinFormsApp"
                      xmlns:ctrls="clr-namespace:BuildIt.Forms.Controls;assembly=BuildIt.Forms.Controls"
                      x:Class="MyFirstXamarinFormsApp.MainPage">
         
             <StackLayout VerticalOptions="Center"
                          HorizontalOptions="Center">
                 <Label Text="Welcome to Xamarin Forms!" />
                 <ctrls:ContentButton>
                     <Label Text="Press m!" />
                 </ctrls:ContentButton>
             </StackLayout>
        </ContentPage>

        I’ll cover more on the BuildIt.Forms library in coming posts.

        Visual State Transitions in Xamarin Forms with Animations

        In previous posts (Visual States in Xamarin.Forms using BuildIt.Forms and Xamarin.Forms Visual States with View Models) I demonstrated how the BuildIt.Forms library (https://www.nuget.org/packages/BuildIt.Forms) could be used to declare visual states for pages, and controls, within Xamarin Forms. Today we just added some basic support for animations so that as you transition between visual states you can animate elements of the screen:

        The following visual states define animations for rotating a green square:

        <Grid HeightRequest="100" WidthRequest="100" x:Name="AnimateGrid" HorizontalOptions="Start" BackgroundColor="Green" />

        The Hide visual state defines three animations that run in parallel, with the rotation being a sequence of animations. The Show visual state has the reverse animations to return the green square to the original starting position. Unlike the setters, there’s no built in support for returning the element to its unchanged state.

        <vsm:VisualStateManager.VisualStateGroups>
             <x:Array Type="{x:Type vsm:VisualStateGroup}">
                 <vsm:VisualStateGroup Name="SampleStates">
                     <vsm:VisualState Name="Show">
                         <vsm:VisualState.Animations>
                             <vsm:TranslateAnimation TranslationX="0" Duration="500" Target="AnimateGrid"/>
                             <vsm:FadeAnimation Opacity="1" Duration="500" Target="AnimateGrid"/>
                             <vsm:RotateAnimation Rotation="0" Duration="500" Target="AnimateGrid"/>
                         </vsm:VisualState.Animations>
                     </vsm:VisualState>
                     <vsm:VisualState Name="Hide">
                         <vsm:VisualState.Setters>
                             <vsm:Setter Value="false"
                                         Target="WelcomeText.IsVisible" />
                         </vsm:VisualState.Setters>
                         <vsm:VisualState.Animations>
                             <vsm:ParallelAnimation>
                                 <vsm:TranslateAnimation TranslationX="200" Duration="3000" Target="AnimateGrid"/>
                                 <vsm:FadeAnimation Opacity="0.2" Duration="3000" Target="AnimateGrid"/>
                                 <vsm:SequenceAnimation>
                                     <vsm:RotateAnimation Rotation="135" Duration="750" Target="AnimateGrid"/>
                                     <vsm:RotateAnimation Rotation="0" Duration="750" Target="AnimateGrid"/>
                                     <vsm:RotateAnimation Rotation="135" Duration="750" Target="AnimateGrid"/>
                                     <vsm:RotateAnimation Rotation="0" Duration="750" Target="AnimateGrid"/>
                                 </vsm:SequenceAnimation>
                             </vsm:ParallelAnimation>
                         </vsm:VisualState.Animations>
                     </vsm:VisualState>
                 </vsm:VisualStateGroup>
             </x:Array>
        </vsm:VisualStateManager.VisualStateGroups>

        This is how these animations play out:

        animations

        Adding Fluent Design Acrylic Material to UWP via Xamarin.Forms.

        At Build Microsoft made a big deal out of the new Fluent Design that they’re encouraging developers to start taking advantage of. Out of the box it’s a little harder to take advantage of these features but using BuildIt.Forms it’s easy to start using acrylic material resources. Let’s extend the example I’ve covered in the last couple of posts (Visual States in Xamarin.Forms using BuildIt.Forms and Xamarin.Forms Visual States with View Models). I’ve added a Grid, that will span the whole page (the StackLayout was positioned to keep all the elements in the centre of the page) and included the BackgroundEffect to set the background of the whole page.

        <Grid>
             <Grid.Effects>
                 <ctrls:BackgroundEffect Resource="SystemControlAcrylicWindowBrush" />
             </Grid.Effects>

             <StackLayout VerticalOptions="Center"
                             HorizontalOptions="Center">

                <Label x:Name="WelcomeText"
                         Text="{Binding WelcomeText}" />
                 <StackLayout Orientation="Horizontal">
                     <Button Text="Show"
                             Clicked="ShowClicked" />
                     <Button Text="Hide"
                             Clicked="HideClicked" />
                 </StackLayout>
             </StackLayout>
        </Grid>

        The Resource attribute defines the UWP brush resource that will be used as the background. In this case the SystemControlAcrylicWindowBrush is one of the build in arcylic brushes. As you can see the page appears as translucent, allowing what’s behind the app to taint the background of the app.

        image

        It’s also possible to use a custom acrylic resource, defined in the App.xaml of the UWP application

        <Application
             x:Class="FormsWithStates.UWP.App"
             xmlns="
        http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="using:FormsWithStates.UWP"
             RequestedTheme="Light">
             <Application.Resources>
                 <ResourceDictionary>
                     <ResourceDictionary.ThemeDictionaries>
                         <ResourceDictionary x:Key="Default">
                            <AcrylicBrush x:Key="MyAcrylicBrush"
                                           BackgroundSource="HostBackdrop"
                                           TintColor="#FFFF0000"
                                           TintOpacity="0.4"
                                           FallbackColor="#FF7F0000" />

                         </ResourceDictionary>

                        <ResourceDictionary x:Key="HighContrast">
                             <SolidColorBrush x:Key="MyAcrylicBrush"
                                              Color="{ThemeResource SystemColorWindowColor}" />

                         </ResourceDictionary>

                        <ResourceDictionary x:Key="Light">
                             <AcrylicBrush x:Key="MyAcrylicBrush"
                                           BackgroundSource="HostBackdrop"
                                           TintColor="#FFFF0000"
                                           TintOpacity="0.4"
                                           FallbackColor="#FFFF7F7F" />

                         </ResourceDictionary>
                     </ResourceDictionary.ThemeDictionaries>
                 </ResourceDictionary>
             </Application.Resources>
        </Application>

        image

        The BackgroundEffect also supports a FallbackColor attribute which can be used to set the background colour on all platforms.

        Xamarin.Forms Visual States with View Models

        In my previous post, Visual States in Xamarin.Forms using BuildIt.Forms, I showed how to use BuildIt.Forms (https://www.nuget.org/packages/BuildIt.Forms) to create visual states that can be used to define how the user interface changes to reflect different states of the page. The example demonstrated switching between visual states in the code behind with calls to VisualStateManager.GoToState. In this post I’m going to extend the example to allow the states to be switched from a view model.

        I’ll start by creating a view model that will be data bound to the page. Usually I’d use a framework like MvvmCross to drive the view model/view instantiation but for this example I’ll keep it simple. I will however still put the view model in a separate project – again this promotes good separation between the view models and their associated view. I’ll create a new .NET Standard library, FormsWithStates.Core, and add a reference to it into the FormsWithStates.UI project.

        image

        I’ll add a new class to the project, MainViewModel, which will be the view model for the MainPage of the application. To track states within the view model, I need to add a reference to the BuildIt.States library on NuGet.

        image

        The MainViewModel will define a simple property WelcomeText to demonstrate that the view model is indeed data bound to the page. It also implements the interface IHasStates which defines a property StateManager – you can think of the IStateManager implementation as an object that can track states and state transitions.

        public enum SampleStates
        {
             Base,
             Show,
             Hide
        }

        public class MainViewModel : IHasStates
        {
             public IStateManager StateManager { get; } = new StateManager();

            public string WelcomeText => "Welcome to Forms!";

            public MainViewModel()
             {
                 StateManager.Group<SampleStates>().DefineAllStates();
             }

            public void Show()
             {
                 StateManager.GoToState(SampleStates.Show);
             }
             public void Hide()
             {
                 StateManager.GoToState(SampleStates.Hide);
             }
        }

        The enumeration SampleStates defines the states that the MainViewModel references – both the enumeration and the states themselves have to match the names of the visual state group and visual states defined in the XAML for the page. The final step is to link the visual states on the page to the IStateManager instance, so that when there is a state change in the IStateManager, it will be reflected on the page via a change to the visual states. This is done by the Bind method on the VisualStateManager class.

        public partial class MainPage : ContentPage
        {
             private MainViewModel ViewModel { get; } = new MainViewModel();
             public MainPage()
             {
                 InitializeComponent();

                BindingContext = ViewModel;
                 VisualStateManager.Bind(this, ViewModel.StateManager);
             }

            public void ShowClicked(object sender, EventArgs e)
             {
                 ViewModel.Show();
             }
             public void HideClicked(object sender, EventArgs e)
             {
                 ViewModel.Hide();
             }
        }

        Whilst from the perspective of a user, there is no difference (since the Show and Hide buttons do the same thing), state management has been shifted to the view model where it can be tested. This separation of views and view models is important to ensure all application logic can be tested.

        Visual States in Xamarin.Forms using BuildIt.Forms

        A couple of weeks ago I started building out some helpers to make working with Xamarin.Forms a little nicer (see Styling Pages and Controls in Xamarin Forms using Visual States,Rebuilding the Xamarin.Forms Button with Visual States and Control Templates and Ambient Properties in Xamarin.Forms). Since then we’ve been working on building out a library that encapsulates these features, again making it easier for us and others to build apps using Xamarin.Forms. There is now a pre-release version of BuildIt.Forms (https://www.nuget.org/packages/BuildIt.Forms) that anyone can reference to take advantage of these helpers. The library makes use of some methods/properties that are only available in the pre-release version of Xamarin.Forms, which is why we don’t have an actual release out yet.

        In this post I’m going to walk through using visual states in a Xamarin.Forms project. To set the scene, I’m going to step through creating a new Xamarin.Forms project in Visual Studio 2017 (current RTM build, not the preview, although the preview build should be similar). I’ll do this in this post to make sure the basics of creating a Xamarin.Forms project that uses a .NET Standard Library instead of a PCL library is covered. I highly recommend switching to a .NET Standard library as soon as possible to avoid issues with upgrading nuget references etc (most third party library now have a .NET Standard version and it will become increasingly harder to maintain and update your old PCL libraries).

        Ok, so let’s get started with a new project – I’m going with the Cross Platform App (Xamarin) template in the New Projects dialog:

        image

        Next, I’ll select the Blank App template, using Xamarin.Forms (UI Technology) and Portable Class Library (Code Sharing Strategy). Side note here – I highly recommend not using the Shared Project option for Code Sharing Strategy; using this option is a recipe for disaster as it promote poorly separated UI logic and allows for using conditional compilation based on #defines which is not a good strategy if you want maintainable code.

        image

        After clicking OK my solution has four projects: A PCL which has got the Xamarin.Forms UI defined in XAML files, and three “head” projects, one for each target platform. At this point, I would suggest running each project to make sure you have a working application before going any further (and commit this code to your source repository before going any further!)

        image

        Now to replace the PCL with a .NET Standard library. I’ll add a new .NET Standard class library. I like to make it clear that this library will contain the UI for my Xamarin.Forms project by using the .UI suffix. I do not include my view models in this library – I’ll talk about this in a subsequent post.

        image

        After creating the new class library, I just need to copy across the XAML and .cs files that were in the PCL library (App.xaml, App.xaml.cs, MainPage.xaml, MainPage.xaml.cs).  I can then remove the PCL library from the solution. Of course, I need to go through each of the head projects and add a reference to the UI project.

        image

        At this point I would again build and run the application on each platform – If you do this without doing anything the solution won’t compile as the UI library doesn’t have a reference to the Xamarin.Forms NuGet library. I suggest adding a reference to the Xamarin.Forms NuGet library and then upgrading any libraries where there is an update available. Again before proceeding, build and run each platform.

        The next step is to add a reference to BuildIt.Forms. This is a prerelease library so you’ll need to check the “Include prerelease” option when searching. You need to add this library to all projects, even though you’ll only be adding code into the UI project – this makes sure the platform specific libraries that are included in BuildIt.Forms are correctly referenced and will be included.

        image

        As part of referencing BuildIt.Forms you will notice that the reference to Xamarin.Forms has also been updated to the prerelease version – as BuildIt.Forms takes advantage of some prerelease APIs this is unavoidable at the moment. The official release of BuildIt.Forms will not be available until the next drop of Xamarin.Forms where these APIs come out of prerelease.

        Now we can start to make use of some of the helpers in BuildIt.Forms. In this case we’re going to use visual states in the XAML for the MainPage to hide and show a Label. The following XAML includes a Label and two Button elements. There are two visual states defined: Show and Hide (the actual names are only relevant when switching visual states, they have no bearing on what the visual states do). Note that the Show visual state doesn’t need to explicitly set the IsVisible property on the WelcomeText Label to true, since this is the default value for that property.

        <?xml version="1.0" encoding="utf-8" ?>
        <ContentPage xmlns="
        http://xamarin.com/schemas/2014/forms"
                      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                      xmlns:vsm="clr-namespace:BuildIt.Forms.Core;assembly=BuildIt.Forms.Core"
                      xmlns:local="clr-namespace:FormsWithStates"
                      x:Class="FormsWithStates.MainPage">
             <vsm:VisualStateManager.VisualStateGroups>
                 <x:Array Type="{x:Type vsm:VisualStateGroup}">
                     <vsm:VisualStateGroup Name="SampleStates">
                        <vsm:VisualState Name="Show" />
                         <vsm:VisualState Name="Hide">
                             <vsm:VisualState.Setters>
                                 <vsm:Setter Value="false"
                                             Target="WelcomeText.IsVisible" />
                             </vsm:VisualState.Setters>
                         </vsm:VisualState>

                     </vsm:VisualStateGroup>
                 </x:Array>
             </vsm:VisualStateManager.VisualStateGroups>
             <StackLayout VerticalOptions="Center"
                          HorizontalOptions="Center">
                 <Label x:Name="WelcomeText"
                        Text="Welcome to Xamarin Forms!" />
                 <StackLayout Orientation="Horizontal">
                     <Button Text="Show"
                             Clicked="ShowClicked" />
                     <Button Text="Hide"
                             Clicked="HideClicked" />
                 </StackLayout>
             </StackLayout>
        </ContentPage>

        The code for the event handlers for the two button is relatively simple:

        public void ShowClicked(object sender, EventArgs e)
        {
             VisualStateManager.GoToState(this, "Show");
        }
        public void HideClicked(object sender, EventArgs e)
        {
             VisualStateManager.GoToState(this, "Hide");

        }

        And the final result is an interface that shows and hides the welcome text on the page:

        imageimage

        Feel free to try out the BuildIt.Forms library and get started using visual states within your Xamarin.Forms project.

        Ambient Properties in Xamarin.Forms

        One of the aspects of XAML that is often misunderstood is that of ambient properties. Probably the best example of this is being able to set the foreground colour on a Page in UWP and for the foreground color to be set on every element on the page. Unfortunately this doesn’t seem to be something that’s available in Xamarin.Forms, which lead me to wonder how hard it would be to implement.

        The implementation would be slightly different from UWP which uses the AmbientAttribute. Instead I’ll create an attached property which can be set on any element. The ForeColor will be then set on each child element, unless the TextColor is explcitly set on an element.

        For example the following XAML

        <StackLayout
            vsm:Ambient.ForeColor="Blue">
             <Label Text="Hello World - Blue!" />
             <Label TextColor="Red"
                     Text="Hello World - Red!" />
        </StackLayout>

        would generate the following output

        image

        Over the next couple of days the Ambient.ForeColor property will be added to BuildIt.Forms, which also includes the VisualStateManager I described in my past two posts (here and here).

        Rebuilding the Xamarin.Forms Button with Visual States and Control Templates

        In my previous post I provided a demonstrable way that visual states could be used in a Xamarin.Forms application to adjust layout. Whilst I showed how this can be used on a page to show/hide a piece of text, it can also be used to define the different states of a button. Before I get onto using visual states within a button, I’ll first show how a ContentView can be adapted to provide the basic button behaviour, whilst allowing both Content and ControlTemplate to be defined. Ok, perhaps that doesn’t make sense but let’s walk through an example:

        <controls:ContentButton Pressed="ToggleButtonPressed">
            <StackLayout>
                <Label Text="Hello!" />
                <Label Text="Hello!" />
                <Label Text="Hello!" />
                <Label Text="Hello!" />
                <Label Text="Hello!" />
                <Label Text="Hello!" />
            </StackLayout>
        </controls:ContentButton>

        In this code, I can add any XAML elements as Content within the ContentButton tags. The ContentButton raises a Pressed event, instead of a Click or Clicked event, to which an event handler can be attached. In the next code snippet, I’ve overridden the default ControlTemplate, wrapping the ContentPresenter in a Grid which has a yellow background.

        <controls:ContentButton VerticalOptions="Center"
                                x:Name="DisabledButton"
                                HorizontalOptions="Center">
            <ContentView.ControlTemplate>
                <ControlTemplate>
                    <Grid BackgroundColor="Yellow">
                        <ContentPresenter x:Name="ContentPresenter"
                                            Content="{TemplateBinding Content}" />
                    </Grid>
                </ControlTemplate>
            </ContentView.ControlTemplate>
            <StackLayout>
                <Label Text="Hello!" />
                <Label Text="Hello!" />
                <Label Text="Hello!" />
                <Label Text="Hello!" />
                <Label Text="Hello!" />
                <Label Text="Hello!" />
            </StackLayout>
        </controls:ContentButton>

        Overriding the ControlTemplate demonstrates an easy way to override the style of the button in a way that can be replicated across all instances of the button in an application.

        Let’s take a look at the inner workings of the ContentButton, in particular the default ContentTemplate which is used to define different visual states of the button. In this case there are four visual states: Normal, PointerOver, Pressed and Disabled.

        <ContentView.ControlTemplate>
            <ControlTemplate>
                <Grid x:Name="RootGrid" BackgroundColor="{TemplateBinding BackgroundColor}">
                    <local:VisualStateManager.VisualStateGroups>
                        <x:Array Type="{x:Type local:VisualStateGroup}">
                            <local:VisualStateGroup Name="CommonStates">
                                <local:VisualState Name="Normal" />
                                <local:VisualState Name="PointerOver">
                                    <local:VisualState.Setters>
                                        <local:Setter Value="#33000000" Target="Background.BackgroundColor" />
                                    </local:VisualState.Setters>
                                </local:VisualState>
                                <local:VisualState Name="Pressed">
                                    <local:VisualState.Setters>
                                        <local:Setter Value="#66000000" Target="RootGrid.BackgroundColor" />
                                    </local:VisualState.Setters>
                                </local:VisualState>
                                <local:VisualState Name="Disabled">
                                    <local:VisualState.Setters>
                                        <local:Setter Value="#33000000" Target="Background.BackgroundColor" />
                                    </local:VisualState.Setters>
                                </local:VisualState>
                            </local:VisualStateGroup>
                        </x:Array>
                    </local:VisualStateManager.VisualStateGroups>
                   
        <BoxView BackgroundColor="Transparent" x:Name="Background" />
                    <ContentPresenter x:Name="ContentPresenter" Content="{TemplateBinding Content}" />
                </Grid>
            </ControlTemplate>
        </ContentView.ControlTemplate>

        In this code you can see how the visual states (which I introduced in my previous post) are used to adjust the background colour of the BoxView that sits behind the Content of the button.

        The sample project that demonstrates the ContentButton can be downloaded here