Category Archives: Xamarin Forms

Custom Fonts in Xamarin Forms

First off, this post Fonts in Xamarin.Forms is a far more complete description of all things font related in Xamarin Forms than this post will be, so go check it out.

In this post I’m just going to discuss how we can add and use “custom” fonts, i.e. fonts not on a device by default.

Custom Fonts

In this instance a custom font simply means a font that’s not, by default, loaded onto a device.

We can find lots of free fonts etc. via Google Fonts.

As per the previously mentioned Microsoft/Xamarin post, we’ll demonstrate things using the Lobster-Regular.ttf font.

Within Google Font simply search for Lobster and then download the Lobster.zip to your machine. If you then unzip this file you’ll have two files, the .ttf and a license file.

To look at the font and/or to get the Font name, in Windows we can right mouse click the .ttf file and select Preview. Hence we see the following

  • Font name: Lobster
  • Version: Version 2.100
  • OpenType Layout, TrueType Outlines

We also see a sample of the font for the alphabet, but more interestingly a sample for different font sizes, 12, 18, 24, 36 etc.

Preview Feature

Within the previously mentioned post they talk about adding your custom font to the shared project of your Xamarin Forms application. This was a preview feature and at the time of writing this post, I was unable to see this work. Hence this post will be out of data as soon as this is implemented. However for completeness I’ll relay what the post says on this.

To add a custom font to your shared project…

  • Create a Resources/Fonts folder (this folder configuration isn’t a requirement)
  • Add your .ttf or otf font files to this new folder and mark their properties as Embedded Resource
  • In the AssemblyInfo.cs file (for example) ad the ExportFont attribute, for example
    using Xamarin.Forms;
    
    [assembly: ExportFont("Lobster-Regular.ttf")]
    
  • Using the font is then as simple as writing the following

    <Label Text="Hello Xamarin.Forms"
       FontFamily="Lobster-Regular" />
    

    Existing/non-preview usage

    So, as mentioned, I was unable to get the preview working at this time, so let’s look at the “current” way to implement custom fonts. Let’s therefore assume we did not do any of the Preview steps.

    For Android…

    Copy your .ttf or .otf files into your Android project’s Assets folder and mark them as AndroidAsset via the file’s properties option in Visual Studio.

    Now it the shared project we need to reference the font slightly differently

    <Label Text="Hello Xamarin.Forms"
       FontFamily="Lobster-Regular.ttf#Lobster Regular" />
    

    For iOS…

    Copy your .ttf or .otf files into your iOS project’s Resources folder and mark them as BundleResource via the file’s properties option in Visual Studio.

    There’s and addition step, where we need to add the font(s) to the info.plist, i.e.

    <key>UIAppFonts</key>
    <array>
        <string>Lobster-Regular.ttf</string>
    </array>
    

    The big difference to the Android example is that the code only has the typeface name, for example

    <Label Text="Hello Xamarin.Forms"
       FontFamily="Lobster-Regular" />
    

    For UWP…

    Copy your .ttf or .otf files into your UWP project’s Assets folder and mark them as Content via the file’s properties option in Visual Studio.

    As per the Android example, the code would look like this within the shared project

    <Label Text="Hello Xamarin.Forms"
       FontFamily="Lobster-Regular.ttf#Lobster Regular" />
    

    Different fonts for different OS’s

    As you’ve seen in the examples for setting the FontFamily attribute, Android and iOS differ in what they expect, so we’re going to need a better way to supply this value. Or it may be we actually want different font’s on different devices.

    We can create a style and use OnPlatform capabilities of Xamarin Forms to achieve this.

    i.e. in this example we’ll set the fonts

    <ResourceDictionary>
      <OnPlatform x:TypeArguments="x:String" x:Key="LabelFont">
        <On Platform="Android" Value="Lobster-Regular.ttf#Lobster Regular" />
        <On Platform="UWP" Value="/Assets/Lobster-Regular.ttf#Lobster Regular" />
        <On Platform="iOS" Value="Lobster-Regular" />
      </OnPlatform>
    </ResourceDictionary>
    

    and then we can change our Label sample code to the following

    <Label Text="Hello Xamarin.Forms"
       FontFamily="{StaticResource LabelFont}" />
    

    Sample Project

    See https://github.com/putridparrot/blog-projects/FontTestApp

Multilingual App Toolkit (MAT)

I’ve previously looked at the MAT in the post Adventures in UWP – Globalization & Localization UWP – Globalization & Localization. I’ve also used this within mobile applications using Xamarin Forms which I was about to update, but then realised I’d forgotten how this stuff worked.

Requirements

Before we start, we need to install a couple of things.

  • From Visual Studio 2019 (if not already installed) select Extensions | Manage Extensions and download the Multilingual App Toolkit. You’ll need to restart Visual Studio for the installation to take place.
  • Install (if not already installed) the Multilingual app toolkit 4.0 Editor as this is extremely useful for managing our translated files, but is NOT required.

Note: This does not currently seem to be supported in Visual Studio for Mac.

Mobile Application

Let’s start by creating a Xamarin Forms application to see how things work.

  • Create a Mobile App (Xamarin.Forms) in Visual Studio
  • Add a Resources folder to the shared project and then add a Resource File item to this folder, named AppResources.resx
  • Right mouse click on the shared project and select Properties, now select Package and towards the bottom of this screen, change the Assembly neutral language to your default language – for example mine’s English (United Kingdom). In other words our project culture will be set to en-GB
  • Enable MAT by selecting Tools | Multilingual App Toolkit | Enable on your solutions

At this point we now have the basics in place to begin localizing our application. We can now start adding strings to our AppResources.resx or alternatively we could start adding new languages, so let’s do that.

  • Right mouse click on your shared project and select Multilingual App Toolkit and from this select, Add translation languages…

Note: You may get and error regarding the need to install translation providers, this requires us to add an Azure subscription, but we don’t actually need this to use the tools, so just ignore this error for now.

From the Translation Languages check on any languages you want to support (you can also add languages at any point so don’t worry if you need to add more at a later date).

In my case I’m going to add German [de] and French (France) [fr-FR]. Once you press OK you’ll see two additional AppResources files added to the Resources folder, AppResources.de.resx for German and AppResources.fr-FR.resx for French.

You’ll also see the MultiligualResources folder with two .xlf files, one for German and one for French, these are used by MAT to generate our new AppResources files.

Note: Do not edit the localized AppResources.*.resx files by hand. Only AppResources.resx should be edited.

Editing our resources

Now that we have the xlf files and the default culture AppResources.resx file, we’ll want to start adding some strings.

Open the AppResources.resx file in Visual Studio and add some named strings, the Name being the identifier or key, the Value being the string to display and we can also add comments which might be useful for somebody who handles the subsequent translations.

So I’m going to create a basic login page, hence we’ll add the following

  • Name: Welcome, Value: Welcome to the application
  • Name: Login, Value: Login
  • Name: Username, Value: Username or email address
  • Name: Password, Value: Enter your password

Now build your application before we look to create some translations.

There’s a couple of ways to proceed with this, the simplest is as follows

  • From Visual Studio. Select you MultilingualResources folder or each .xlf in turn.
  • Right mouse click on the folder or file then select Multilingual App Toolkit | Generate Machine Translations.

You may find that some values are not translated, for example in my case Welcome to the application was not translated, we can edit the de.xlf file directly. In this case I change the target element to Willkommen bei der Anwendung and changed the target state to needs-review-translation

Once you’ve made your changes then build the project and MAT will generate the AppResources.*.resx files.

The second way to handle the translations and probably one that would be useful for people who are working on translations of your application. In this case we use the Multilingual Editor that was installed earlier. Open each of your xlf files in turn. For each one we’ll see a list of the strings as entered into the AppResources.rex file. So let’s concentrate on editing the .de.xlf German translation file.

  • Having opened the .de.xlf file, select the Strings tab at the bottom of the screen to ensure all the strings were added, now here we could manually translate each row by selecting the each row in turn, then changing the Translation in the editor in the middle of the editor UI.
  • If you edit the translation yourself then the State on the right of the screen will switch to Translated. This state will tell the MAT editor whether it should try to translate the value. If the user has marked the state as Translated we can assume this is correct and the editor will not attempt to translate the string using it’s generate translation option. You can change this State back to New if you want the auto-translation to take place.
  • If you prefer or like me you’re simply going to use something like Bing or Google to do the translations, i.e. https://www.bing.com/translator/. Then the Editor offers the Translate button. Clicking this will generate translations for all the text and mark them with the State Needs Review which is basically saying that the translation was made but needs somebody to review whether this makes sense in each language. You can leave this State as is or change to Translated if you’re happy with these translations.
  • Once completed, save the file(s) and build your solution to get the AppResources.*.rexr updated.

Displaying our translations in an application

Note: This post has been updated as the previously used Multilingual plugin is no longer required.

We can display translations is XAML using the AppResources generated code, for example

Title="{x:Static resources:AppResources.Settings}

and in code just as easily we use

var title = AppResources.Settings;

To test your translations you can set things up in code, i.e.

In your App.xaml.cx, after the InitializeComponent you can place the following code to set the culture to that of the device

var culture = CrossMultilingual.Current.DeviceCultureInfo;
AppResources.Culture = culture;

If you want to test your German translation, for example, replace these two lines with

var culture = new CultureInfo("de");
AppResources.Culture = culture;
CrossMultilingual.Current.CurrentCultureInfo = culture;

See https://github.com/putridparrot/blog-projects/tree/master/MatTestMobile for a sample application.

If you prefer to use the Android Emulator to set your language – which ofcourse makes a lot of sense, then go to Android Settings | System | Languages & input | Languages then Add a language if the one you want is not listed, then drag and drop that language to the top of the Languages list and Android will switch to that language.

Application lifecycle within Xamarin Forms

You’ve got your Xamarin Forms (or native Android/iOS) application up and running and now you need to start thinking about what happens when your application hibernates.

An application can go into hibernation (or sleep mode) and then resume at some point. The OS hibernates an application in response to events, such as power off or lock screen but also if it’s running low on memory. Therefore, so that our application “places nicely” on the OS, we need to think about how we will persist state and restore state during this hibernation phases.

Let’s look at the various methods in Xamarin Forms for handling different aspects of the application’s life cycle…

Xamarin Forms

Initialization/Starting

By default a Xamarin Forms application will create an OnInitialized method which is basically where the InitializeComponent method is called. It’s a good place to set up any initialization for your UI elements etc.

Assuming we’re starting our application from cold (i.e. first start) Then the following lifecycle methods are called in order

  1. OnInitialized
  2. OnStart

According to the App Lifecycle documentation “On Android, the OnStart method will be called on rotation as well as when the application first starts, if the main activity lacks ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation in the [Activity()] attribute”.

So OnInitialized remains the best place to set defaults up, but OnStart may be the best place to make any UI changes based upon orientation etc.

Entering sleep mode

If the device goes into sleep mode (we can simulate easily by hitting the power button on our emulator or device). The following is called

  1. OnSleep

This is our opportunity to persist state from the device so that when we resume the application it’ll appear in the same state as when it went into sleep mode.

There’s various ways to achieve this, if we’re using a pure MVVM approach with Prism (for example) we might use the EventAggregator to send a sleep message to all listening view models etc., which would then persist their data, or maybe we hold a cache (or similar) as a single data store and we persist this. Whichever way we go, the intention is that everything that is required to get the application back to the state pre-sleep, needs persisting. This also includes things such as which view (in a multiple view application) is displayed along with things like the view stack – well you get the idea, it depends how far you want to go to recreate the state of your application.

Note: another useful way to deal with view model data etc. is to actually persist it automatically when it changes, I don’t mean for every change of an entry control, but for example if you get data from a service, then you might store this in a cache and persist at the same time – obviously it depends on your specific scenarios and design.

Resuming from sleep mode

When an application is resumed, the following is called

  1. OnResume

At this point we need to read any persisted data, hydrate our data/view models with this previously stored data and then get the application back into the state it was when it went into sleep mode. As mentioned for OnSleep, this includes any changes to the UI to put the correct view in place. Basically the user should not even realise that the application was, essentially, closed and restarted.

To test OnResume we simply click the power button on the emulator or unlock the device at which point OnResume will be called.

References

Xamarin.Forms App Lifecycle
Android Activity Lifecycle
UIApplicationDelegate Class

Material UI in Xamarin Forms

To get nice, material ui, visuals on your Android and/or iOS application you can use the Xamarin.Forms.Visual.Material nuget package, see Xamarin.Forms Material Visual for a full explanation of using this package. I’m just going to summarise this information in this post for my own information.

Add the nuget package Xamarin.Forms.Visual.Material you may need to upgrade your Xamarin Forms if it’s an older version.

Init the FormsMaterial in the AppDelegate of the iOS project

global::Xamarin.Forms.Forms.Init();
global::Xamarin.Forms.FormsMaterial.Init();

and the same in the MainActivity

global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
global::Xamarin.Forms.FormsMaterial.Init(this, savedInstanceState);

Finally set the Visual element of the ContentPage, i.e.

<ContentPage Visual="Material"
/>

That’s all there is to it.

Emailing (using default Email client) from mobile using Xamarin

A simply way to send email from Android and iOS using Xamarin is by using the Xamarin.Essentials.Email class. This allows us to use the default email client on the device to send our email, so we simply compose the email then pass the user to the default client to press the send button. What’s useful about this is our application can then leave the user to add any further information to the email without having to create the entry fields in our app.

You’ll need to add the NuGet package Xamarin.Essentials, then we can use the following code (don’t forget to add using Xamarin.Essentials)

try
{
   var message = new EmailMessage
   {
      Subject = subject,
      Body = body,
      To = recipients,
      Cc = ccRecipients,
      Bcc = bccRecipients,
      BodyFormat = EmailBodyFormat.PlainText
   };

   if (attachments != null && attachments.Count > 0)
   {
      attachments.ForEach(attachment =>
      {
         message.Attachments.Add(new EmailAttachment(attachment));
      });
   }

   await Email.ComposeAsync(message);
}
catch (Exception ex)
{
   // Log exception
}

On Android this will display the default email client, for example gmail, with all the fields filled in along with any attachments.

Xamarin UITest (on Android)

Having used the likes of TestStack.White in the past I was interested in trying out the Xamarin UITest library for executing tests against my mobile application’s UI.

For now I’m primarily discussing testing against an Android device or emulator, but I will amend the post as and when I run tests against iOS.

Some problems and solutions

It didn’t go smoothly, initially, getting a project running. Hence, this part of the post is going to cover some of the issues I had and some of the possible solutions.

  • If you have platform-tools.old followed by a number of digits within C:\Program Files (x86)\Android\android-sdk (for example platform-tools.old1970091580), either delete these folders or for safety’s sake, move them outside of the C:\Program Files (x86)\Android\android-sdk folder, otherwise running the UITests seems to get confused which adk it should use.
  • Add an environment variable (if not already existing) named ANDROID_HOME and set it’s value to your install of the android-sdk, i.e. C:\Program Files (x86)\Android\android-sdk
  • The version of the UITest NuGet package seems to be related to the version of the Android SDK, so after you’ve created a UITest project and added the Xamarin.UITest package, depending on the Android SDK you might need to get a previous version of this package – in my case I’m using Xamarin.UITest version 2.2.7.0 and Android SDK Tools 26.1.1
  • For an Android application, we need to set the project properties Android Manifest, Required permissions to include the INTERNET permission
  • For Android projects we need to run against a Release build
  • Again for Android projects, if we added a UITest project which include the ApplInitializer.cs file, we need to supply the application name or the path to the .apk file being used, for example
    if(platform == Platform.Android)
    {
       return ConfigureApp
          .Android
          .InstalledApp("com.putridparrot.MyApp")
          .PreferIdeSettings()
          .EnableLocalScreenshots()
          .StartApp();
    }
    

    Note: In place of InstalledApp we could use ApkFile with the path of our apk file, i.e.

       .ApkFile(@"C:\Development\MyApp\com.putridparrot.MyApp.apk")
    
  • If you’ve previously installed your application on the emulator or device, I found it best to manually uninstall it first
  • Before running your tests, make sure the emulator is running or the device is connected (I know, probably obvious)

Creating our UI test project

  • Add a Xamarin.UITest Cross-Platform Test Project to your solution
  • Build the project so it restores any missing NuGet packages, I needed to update the following packages to Xamarin.UITest version 2.2.7.0 and NUnit 3.11.0.0
  • Deploy your application to your device before running the tests
  • When running your tests, they may take a little time before you see anything happening on the emulator or device – so don’t be too impatient.

Before we can actually run our tests (which we’ll discuss next) we need to build our application and generate an APK for Android (if running against Android).

Writing our UI tests

To allow our UITests to locate controls in our user interface we supply each control (that we need to interact with) with an AutomationId, this should be unique (so it’s easy for our tests to locate).

For Android application I found this configuration works (obviously replace the ApkFile location/name with your apk).

if(platform == Platform.Android)
{
   return ConfigureApp
      .Android
      .ApkFile(@"C:\Development\MyApp\com.putridparrot.MyApp.apk")
      .PreferIdeSettings()
      .EnableLocalScreenshots()
      .StartApp();
}

Note: we should be able to replace the ApkFile line with .InstalledApp(“com.putridparrot.MyApp”) if you prefer.

The UITest project will require an AppInitializer.cs file which, if you created via the project template, will be included. Here’s an example of one

public class AppInitializer
{
   public static IApp StartApp(Platform platform)
   {
      if(platform == Platform.Android)
      {
         return ConfigureApp
            .Android
            .InstalledApp("com.putridparrot.MyApp")
            .PreferIdeSettings()
            .EnableLocalScreenshots()
            .StartApp();
     }
     return ConfigureApp
        .iOS
        .StartApp();
}

Test files (again the project template will include a Tests.cs file) might look like this

[TestFixture(Platform.Android)]
[TestFixture(Platform.iOS)]
public class Tests
{
   private IApp _app;
   private readonly Platform _platform;

   private static readonly 
      Func<AppQuery, AppQuery> LoginButton = 
         c => c.Marked("Login");

   public Tests(Platform platform)
   {
      _platform = platform;
   }

   [SetUp]
   public void BeforeEachTest()
   {
      _app = AppInitializer.StartApp(_platform);
   }

   [Test]
   public void DoesNothing()
   {
      // Arrange
      // Act
      // Assert
   }
}

Writing UI tests is much the same as writing standard unit tests, we mark our test methods with the NUnit TestAttribute, then Arrange, Act and Assert our UI. For example let’s assume we have a button with an AutomationId Login then we can create a static field within our Test class like this

private static readonly 
   Func<AppQuery, AppQuery> LoginButton = 
      c => c.Marked("Login");

This function can be used within various _app methods, such as _app.Tap(LoginButton).

As you’ve guessed I’m testing a login UI, so assuming we have a login screen with username, password and a login button we might setup our tests like this…

First Arrange our UI, for example check that we’re on the correct screen and we’ve entered a username and password. Then we’d Act by tapping the Login button then finally Assert by checking we’ve moved on from the Login screen.

REPL

When we run our tests we might want to run the _app.Repl() method which will display a REPL command line, this allows us to view the tree representing our UI.

References

Cannot run XAMARIN UI TEST on xamarin.forms, error System.Exception

Platform specific code with Xamarin and Prism

When writing platform specific code within our iOS, Android and UWP projects we can use the built-in lightweight dependency injection code and attributes that comes out of the box with Xamarin, but when using Prism we’re probably using Unity or DryIoc as our preferred IoC library.

Let’s look at a simple example, whereby I have an interface in my shared code, which looks like this

public interface IFileService
{
   void Save(string data);
}

although there is file handling code etc. in .NET standard and we can implement something like this in the shared code, maybe we want some other more specific platform code. Here’s an Android file (i.e. within the Android project)

[assembly: Dependency(typeof(FileService))]
namespace Droid.Services
{
    public class FileService : IFileService
    {
        public void Save(string data)
        {
            // some Android specific code
        }
    }
}

The use of the DependencyAttribute makes this class available via Xamarin Forms built-in DependencyService, but not available to DryIoc, for example – hence what we want to do is use the built-in DI container and map this to our preferred IoC library.

All we need to do in our shared project’s App.xaml.cs file within the RegisterTypes method, we just do something like this

containerRegistry.RegisterInstance(DependencyService.Get<IFileService>());

Simple.

Adding SQLite to my Xamarin forms application

To be totally honest, this post Xamarin.Forms Local Databases covers everything you need to know.

Simply add Frank Krueger’s NuGet package to your shared code project. This library is both a database access library and ORM.

We’ll need to create the database file, hence we can create our file location using the following

private static readonly string DatabaseLocation =
   Path.Combine(
      Environment.GetFolderPath
        (Environment.SpecialFolder.LocalApplicationData), 
        "Capture.db3");

Create the database

var database = new SQLiteAsyncConnection(DatabaseLocation);
await database.CreateTableAsync<DataItem>();

Depending on the use case it may be best to create the database connection when the application starts and keep available whilst the application is running. In this instance my calls to the DB are going to be dictated by the user, i.e. pressing a button, so we can create the connection, then create a table for our data objects.

Note: The data object stored into the database must have a default constructor and not be abstract etc. for it to work with the ORM part of this library.

Closing the database

The database connection does not support the IDisposable interface, so we need to explicitly call

await database.CloseAsync();

Note: I’ve not checked the source for the library and had no issues with not closing the connection.

Inserting items into the database

We can insert new items into the database using

await database.InsertAsync(dataItem);

// or a batch insert using 

await database.InsertAllAsync(dataItems)

// or an insert OR replace using

await database.InsertOrReplaceAsync(dataItem)

Updating rows

We saw that we can InsertOrReplace rows but this is based upon whether the object is unique. In other words the data object is first inserted and then a key returned, if another object matches this newly inserted one, then it’s deleted.

We can call UpdateAsync if we know a data object has already been saved to the database and we just want to update it, i.e.

await database.UpdateAsync(dataItem);

and thus if we’re tracking, within our data object whether it’s been saved and decide whether to update or insert using

if(dataItem.Id != 0)
{
   await database.UpdateAsync(dataItem);
}
else
{
   dataItem.Id = await database.InsertAsync(dataItem);
}

Querying the database

It wouldn’t be much of a database if we couldn’t run queries on it. We can use

var list = 
   await database.QueryAsync<DataItem>(
      "SELECT * FROM [DataItem] WHERE [Success] = 0"
   );

We can also use Linq like this

var dataItem = 
   database.Table<DataItem>()
      .Where(i => i.Name == "Samsung").ToListAsync();

Hence here we’ll get a list of all DataItems with the name “Samsung”.

Deleting data

We can use

await database.DeleteAsync(dataItem);

Deleting the database

As the database is stored as a file we can simply delete the file from the file system using

if (File.Exists(DatabaseLocation))
{
   File.Delete(DatabaseLocation);
}

More on our data objects

The only thing we’ve specified in any of the above code, for our data objects, is that they must have a default constructor on a concrete class, but as this SQLite NuGet package is acting like an ORM (as opposed to us creating our tables etc. in SQL), we’ll probably need some of the following properties added to our data object…

In the above we’ve showed that we can get a key back from an insert etc. but we can also add a key to the data objects themselves and have SQLite supply the keys. So for example we can add the following to our data item class

[PrimaryKey, AutoIncrement]
public int Id { get; set; }

Now the id is our primary key and is automatically supplied during an insert using an AutoIncrement algorithm.

We can also add indexed properties, for example

[Indexed]
public string Name { get; set; }

We can ignore properties by marking them with the IgnoreAttribute, i.e.

[Ignore]
public int AverageDb { get; set; }

Other attributes, include the following UniqueAttribute, MaxLengthAttribute , NotNullAttribute, StoreAsTextAttribute (for enums) and CollationAttribute (BINARY, NOCASE, RTRIM are supported with BINARY being the default) for comparisons.

Added a clicking command to Labels (and more)

I wanted to have a clickable label in my Xamarin Forms application. A button was just a little too large for my requirements, but a standard Label does not have a click command. However, it’s easy to create such an command handler, this also works for other UI elements.

In your XAML just use the GestureRecognizers collection and add a TapGestureRecongizer, like this

<Label Text="More...">
   <Label.GestureRecognizers>
      <TapGestureRecognizer Command="{Binding MoreCommand}" />
   </Label.GestureRecognizers>
</Label>

Simple.

Creating a Prism.DryIoc.Forms application from scratch

I must have created my last Prism.DryIoc.Forms application using a project template but this time created a standard Xamarin.Forms application and then realised I wanted/meant to use DryIoc.

So here’s the steps to turn my “standard” Xamarin.Forms application into a Prism.DryIoc.Forms application.

  • Add the Prism.DryIoc.Forms nuget package to your application
  • Delete the MainPage.xaml files generated by Xamarin.Forms
  • Change the App.xaml to use PrismApplication i.e.
    <?xml version="1.0" encoding="utf-8" ?>
    <prism:PrismApplication 
       xmlns="http://xamarin.com/schemas/2014/forms"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       xmlns:prism="clr-namespace:Prism.DryIoc;assembly=Prism.DryIoc.Forms"
       x:Class="MyDemo.App">
        <Application.Resources>
    
        </Application.Resources>
    </prism:PrismApplication>
    
  • Change the App.xaml.cs to derive from PrismApplication, for example
    public partial class App : PrismApplication
    
  • Remove/replace the App constructor with the following
    public App() :
       this(null) { }
    
    public App(IPlatformInitializer initializer) :
       base(initializer) { }
    
  • Now override the OnInitialized method and put the IntitializeComponent call within this, i.e.
    protected override async void OnInitialized()
    {
       InitializeComponent();
    }
    
  • Add folders to the solution named ViewModels and Views
  • Within the Views folder add a MainPage.xaml Xamarin.Forms ContentPage (or page type as required)
  • To register our MainPage and the NavigationPage go back to the App.xaml.cs and add the following method
    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {
       containerRegistry.RegisterForNavigation<NavigationPage>();
       containerRegistry.RegisterForNavigation<MainPage>();
    }
    
  • Finally, in the App.xaml.cs within the OnIntialized method we’ll navigate to the new page. As the NavigateAsync returns a Task, we can await it so we’ll add async to the OnInitialized method – here’s what that will look like
    protected override async void OnInitialized()
    {
       InitializeComponent();
    
       await NavigationService.NavigateAsync("NavigationPage/MainPage");
    }
    

Now place any further page’s within the Views folder and add to the RegisterTypes method (if required) and add any view models to the ViewModels folder deriving from BindableBase (if you want to use the Prism MVVM base class).