ViewModel to ViewModel Navigation in a Xamarin.Forms Application with Prism and MvvmCross

ViewModel to ViewModel Navigation in a Xamarin.Forms Application with Prism and MvvmCross

I’m a big fan of the separation that the Mvvm pattern gives developers in that the user interface is encapsulated in the view (Page, UserControl etc) and that the business logic resides in the ViewModel/Model. When structuring the solution for an application I will go so far as to separate out my ViewModels into a separate project from the views, even with Xamarin.Forms where the views can be defined in a .NET Standard library.

One of the abstractions that this lends itself to is what is referred to as ViewModel to ViewModel navigation – rather than the ViewModel explicitly navigation to a page, or bubbling an event up to the corresponding view to get the view to navigate to the next page, ViewModel to ViewModel navigation allows the ViewModel to call a method such as Navigation(newViewModel) where the newViewModel parameter is either the type of the ViewModel to navigate to, or in some frameworks it may be an actual instance of the new ViewModel.

MvvmCross

Let’s see this in action with MvvmCross first – I’m going to start here because ViewModel to ViewModel navigation is the default navigation pattern in MvvmCross. I’ll start with a new project, created using the MvxScaffolding I covered in my previous post, using MvvmCross in a Xamarin.Forms application. The single view template already comes with a page, HomePage, with corresponding ViewModel, HomeViewModel. To demonstrate navigation I’m going to add a second page and a second ViewModel. Firstly, I’ll add a new class, SecondViewModel, which will inherit from BaseViewModel (a class generated by MvxScaffolding which inherits from MvxViewModel that’s part of MvvmCross).

public class SecondViewModel : BaseViewModel
{
}

Next, I’ll add a new ContentPage called SecondPage (note the convention here that there is a pairing between the page and the ViewModel ie [PageName]Page maps to [PageName]ViewModel)

image

MvvmCross supports automatic registration of pages and ViewModels but it does require that the page inherits from the Mvx base class, MvxContentPage. I just need to adjust the root XAML element from

<ContentPage …

to

<views:MvxContentPage x_TypeArguments=”viewModels:SecondViewModel” …

The inclusion of the TypeArguments means that the generic overload of MvxContentPage is used, providing a helpful ViewModel property by which to access the strongly typed ViewModel that is databound to the page.

Now that we have the second page, we just need to be able to navigate from the HomePage. I’ll add a Button to the HomePage so that the user can drive the navigation:

<Button Text=”Next” Clicked=”NextClicked” />

With method NextClicked as the event handler (here I’m just using a regular event handler but in most cases this would be data bound to a command within the HomeViewModel):

private async void NextClicked(object sender, EventArgs e)
{
     await ViewModel.NextStep();
}

And of course we need to add the NextStep method to the HomeViewModel that will do the navigation. The HomeViewModel also needs access to the IMvxNavigationService in order to invoke the Navigate method – this is done by adding the dependency to the HomeViewModel constructor.

public class HomeViewModel : BaseViewModel
{
     private readonly IMvxNavigationService navigationService;


    public HomeViewModel(IMvxNavigationService navService)
     {
         navigationService = navService;
     }
     public async Task NextStep()
     {
         await navigationService.Navigate<SecondViewModel>();
    }
}

As you can see from this example the HomeViewModel only needs to know about the SecondViewModel, rather than the explicit SecondPage view. This makes it much easier to test the ViewModel as you can provide a mock IMvxNavigationService and verify that the Navigate method is invoked.

Prism

Now let’s switch over to Prism and I’ve used the Prism Template Pack to create a new project. To add a second page I’ll add a SecondPageViewModel, which in the case of Prism inherits from ViewModelBase and requires the appropriate constructor that provides access to the INavigationService. Note that the naming convention with Prism is slightly different from MvvmCross where the ViewModel name is [PageName]PageViewModel (ie both the page and the viewmodel have the Page suffix after the PageName eg SecondPage and SecondPageViewModel)

public class SecondPageViewModel : ViewModelBase
{
     public SecondPageViewModel(INavigationService navigationService) : base(navigationService)
     {
     }
}

I’ll add a new ContentPage called SecondPage but unlike MvvmCross I don’t need to alter the inheritance of this page. Instead what I do need to do is register the page so that it can be navigated to. This is done in the App.xaml.cs where there is already a RegisterTypes method – note the additional line to register SecondPage.

protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
     containerRegistry.RegisterForNavigation<NavigationPage>();
     containerRegistry.RegisterForNavigation<MainPage, MainPageViewModel>();
     containerRegistry.RegisterForNavigation<SecondPage, SecondPageViewModel>();
}

Similar to the MvvmCross example, I’ll add a button to the MainPage (the first page of the Prism application created by the template) with code behind to call the NextStep method on the MainViewModel

private async void NextClicked(object sender, EventArgs e)
{
     await (BindingContext as MainPageViewModel).NextStep();
}

Note that because the MainPage just inherits from the Xamarin.Forms ContentPage there’s no property to expose the data bound viewmodel. Hence the casting of the BindingContext, which you’d of course do null checking and error handling around in a real world application.

public async Task NextStep()
{
     await NavigationService.NavigateAsync(“SecondPage”);
}

The NextStep method invokes the NavigateAsync method using a string literal for the SecondPage – I’m really not a big fan of this since it a) uses a string literal and b) requires the the ViewModel knows about the view that’s being navigated to. So let’s adjust this slightly by changing the way that pages and ViewModels are registered. The RegisterForNavigation method accepts a parameter that allows you to override the navigation path, meaning we can set it to be the name of the ViewModel instead of the name of the page.

protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
     containerRegistry.RegisterForNavigation<NavigationPage>();
     containerRegistry.RegisterForNavigation<MainPage, MainPageViewModel>(nameof(MainPageViewModel));
     containerRegistry.RegisterForNavigation<SecondPage, SecondPageViewModel>(nameof(SecondPageViewModel));
}

The navigation methods would then look like:

public async Task NextStep()
{
     await NavigationService.NavigateAsync(nameof(SecondPageViewModel));
}

But I think we an improve this further still by defining a couple of extension methods

public static class PrismHelpers
{
     public static void RegisterForViewModelNavigation<TView, TViewModel>(this IContainerRegistry containerRegistry)
         where TView : Page
         where TViewModel : class
     {
         containerRegistry.RegisterForNavigation<TView, TViewModel>(typeof(TViewModel).Name);
     }


    public static async Task<INavigationResult> NavigateAsync<TViewModel>(this INavigationService navigationService)
         where TViewModel : class
     {
         return await navigationService.NavigateAsync(typeof(TViewModel).Name);
     }
}

Using these extension methods we can update the registration code:

protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
     containerRegistry.RegisterForNavigation<NavigationPage>();
     containerRegistry.RegisterForViewModelNavigation<MainPage, MainPageViewModel>();
     containerRegistry.RegisterForViewModelNavigation<SecondPage, SecondPageViewModel>();
}

And then the navigation code:

public async Task NextStep()
{
     await NavigationService.NavigateAsync<SecondPageViewModel>();
}

The upshot of these changes is that there’s almost no difference between the MvvmCross method of navigation and what can be done with a little tweaking with Prism.

Scaffolding Your Next MvvmCross Xamarin.Forms Project

Scaffolding Your Next MvvmCross Xamarin.Forms Project

One of the things I liked about the getting started experience with Prism was that there was a Visual Studio extension that made creating a new project super simple. Whilst I know that MvvmCross doesn’t provide something like that out of the box, I decided to take a look at some of the project/solution templates that the community have created. The Getting Started page on the MvvmCross website does maintain a list of MvvmCross templates but I must confess that some of these are a little dated. I just went through and opened each of the links, and there were only two that seemed to be recent, Mvx Toolkit and MvxScaffolding. I downloaded both extensions and just happened to try out MvxScaffolding first. Here’s a quick summary of creating a new Xamarin.Forms application using MvxScaffolding

Search for Mvx to find the scaffolding templates

image

Basic project details

image

Now we’re into the MvxScaffolding custom dialog – wow, look at how nice this is.

image

I went with the Single Item template – it’s a tad confusing that you have to click on the grey circle to pick each option, rather than clicking the whole card. Next up, pick the platform and which test projects you want generated.

image

I added UWP support, and asked for all the test projects

image

A quick summary before the projects are created

image

The final solution

image

And of course, the running application.

image

This was a bit mind blowing to be honest – the level of detail in this extension was awesome and I was able to generate the runnable application in under a minute. I like the way the projects are separated and that it can generate all the test projects.

Resolving Dependencies In Platform Pages, Renderers, Effects and Elements with Xamarin.Forms and Prism

Resolving Dependencies In Platform Pages, Renderers, Effects and Elements with Xamarin.Forms and Prism

We’ve been using Prism for a number of our Xamarin.Forms projects and for the most part we rely on the services being injected into our view models but a scenario came up recently where we wanted to access one of our services from within the platform implementation of a renderer. We were using DryIoC and needed to come up with a mechanism to resolve dependencies that had been registered with DryIoC via Prism. I recalled seeing in Brian’s What’s New in Prism 7.1 post that support had been added for the Xamarin.Forms Dependency Resolver and was wondering whether we could use that to allow us to resolve dependencies by calling Resolve on the static DependencyService that Xamarin.Forms exposes. In this post I’m going to walk through creating a simple Prism application, register a service and then retrieve it from the code behind of a UWP page (but the same process applies for any renderer, effect, page or element).

To get started with a new Prism application I’m going to make use of the Prism Template Pack that installs as a Visual Studio Extension and includes a variety of project and item templates. In Visual Studio 2019 when you launch the application you can select Create a New Project and be given the option to search for project templates.

image 

Once you’ve selected the Prism Bank App (Xamarin.Forms) you’ll then be prompted to specify the name and location of the project

image

The final step is a Prism specific dialog that allows you to specify which platforms and what IoC container you want to use

image

In this case we’re going with DryIoC but I think the technique will work equally well if you select AutoFac or Unity. After hitting Create Project our solution is setup with four projects: one for each target platform and a project that contains both our view and view models. 

image

My preference is to separate views and viewmodels further but for the timebeing we’ll leave the project structure as it is. The next step is to create and register the service that we want to retrieve from our platform specific code.

public interface IFancyService
{
     string WelcomeText { get; }
}


public class MyFancyService : IFancyService
{
     public string WelcomeText => “Hello Dependency World!”;
}

The MyFancyService needs to be registered with the DI container, which we can do by adding a line to the RegisterTypes method in the App.xaml.cs

protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
     containerRegistry.RegisterForNavigation<NavigationPage>();
     containerRegistry.RegisterForNavigation<MainPage, MainPageViewModel>();


    containerRegistry.Register<IFancyService, MyFancyService>();
}

Let’s switch across to the code behind of the MainPage in the UWP application – note that this page is different from the MainPage that’s in the Xamarin.Forms project which is the page that’s displayed on all platforms. The MainPage in the UWP project is used to host the Xamarin.Forms application when it’s run on Windows. I’m going to add the OnNavigatedTo override method and in it I’m going to attempt to resolve the IFancyService interface using the Xamarin.Forms DependencyService.

protected override void OnNavigatedTo(NavigationEventArgs e)
{
     base.OnNavigatedTo(e);


    var fancy = DependencyService.Resolve<IFancyService>();
}

Running this code we’ll see that the variable fancy is null, meaning that the Resolve method wasn’t able to find any registered implementation of the IFancyService.

image

To fix this, we need to tell Prism to register as a Dependency Resolver, which will mean that the Xamarin.Forms DepedencyService will use the same DI container when resolving instances. This is done by using the overloaded constructor of the PrismApplication class. In the App.xaml.cs of our application, change the call to base to include a second parameter which is set to true.

public App(IPlatformInitializer initializer) : base(initializer, setFormsDependencyResolver: true)
{
}

Running the application now and the fancy variable is set to an instance of the MyFancyService.

image

And there you have it – an easy way to use the Xamarin.Forms DependencyService in conjunction with Prism and DryIoC.

Deploying Uno Wasm using Blob Storage

Deploying Uno Wasm using Blob Storage

Earlier today I posted about deploying Uno on Wasm to an Azure App Service (to which the Uno team replied on Twitter with an updated web.config). I was thinking a bit more about how I would deploy a real Uno Wasm app and I realised that of course, there’s no server side logic, so I could just go host it off Blob Storage.

I ran up the Azure Storage Explorer and created a new container within an existing Blob Storage account

image

As I’m going to be serving up content directly from Blob Storage I need to make sure that I enable public read access on the individual blobs (the default is that there’s no public read access on the container or blobs). Right-click on the container and select Set Public Access Level

image

Set access to Public read access for blobs only

image

Now you can simply copy the Uno Wasm application into the container by dragging the files from File Explorer into the right pane of the Azure Storage Explorer. I found that the best folder to copy is the folder that Visual Studio uses to deploy files when you do a Publish. For my project this is found at FirstUnoProject.WasmobjReleasenetstandard2.0PubTmpOutFirstUnoProject.WasmdistbinReleasenetstandard2.0dist.

And that’s it – now I can run my Uno Wasm application by clicking the Copy URL from the tool bar and then switching to my browser and launching the corresponding URL.

image

The Uno Wasm application runs without any further configuration required.

image

Publishing Uno WebAssembly (Wasm) to Azure App Service

Publishing Uno WebAssembly (Wasm) to Azure App Service

I figured that since I had Uno working in WebAssembly locally on my machine that I’d try publishing it out to an Azure App Service. I mean, how hard could it be since Visual Studio recognises that the Wasm project is a web project (nice job there team Uno!) and even gives me the option to Publish.

image

Stepping through the publish wizard I decided to create a new Azure App Service

image

I made use of an existing Resource Group and App Service Plan that I had lying around.

image

After hitting Create and publish Visual Studio went off thinking for what seemed like a long time with nothing happening. I knew it was probably busy packaging and deploying but I didn’t see anything appear in the Output window…… not surprisingly because Visual Studio pushes all the logging for the publish operation to the Web Publish Activity window.

image

Once it was done Visual Studio launches a browser window displaying the root of the newly created App Service. Unfortunately, this is not my Uno project.

image

After investigating a little I realised that the publish operation was uploading the Wasm project to a sub folder of the wwwroot folder within the App Service (eg  wwwrootFirstUnoProject.WasmbinReleasenetstandard2.0distindex.html). I validated this by using the Advanced Tools from the Azure portal.

image

From the Advanced Tools, select Files

image

Browsing the files you can locate the index.html that gets published with the Wasm project. This is the file that hosts the wasm

image

Unfortunately just adding the appropriate path to the index.html to the site url doesn’t seem to work (ie this doesn’t work: https://firstunoproject.azurewebsites.net/FirstUnoProject.Wasm/dist/bin/Release/netstandard2.0/dist/index.html). However, you can easily set up a new application to point to the dist folder. Go to Application Settings and under the section Virtual  applications and directories, create a new mapping. In this case I’ve mapped /uno to the sitewwwrootFirstUnoProject.WasmdistbinReleasenetstandard2.0dist folder (you can get the folder from the “path” shown in the Kudo – Files explorer) and I’ve made it an Application.

image

If you now attempt to go to the index.html page in your new mapped folder (eg https://firstunoproject.azurewebsites.net/uno/index.html) you’ll find that you’ll see the “Loading…” text that comes with the Uno project template but your application won’t load. If you spin up the Chrome debugging tool you’ll see that it’s not able to find the mono.wasm file with a 404 being raised. Don’t bother trying to work out whether the file exists or not because the issue is that whilst the file exists, the Azure App Service isn’t going to serve it because it’s not a known file type. Luckily there’s a simple solution. Add the following Web.config to your Wasm project and publish your application again.

<?xml version=”1.0″ encoding=”UTF-8″?>
<configuration>
   <system.webServer>
     <staticContent>
       <remove fileExtension=”.clr” />
       <remove fileExtension=”.dll” />
       <remove fileExtension=”.json” />
       <remove fileExtension=”.wasm” />
       <remove fileExtension=”.woff” />
       <remove fileExtension=”.woff2″ />
       <mimeMap fileExtension=”.dll” mimeType=”application/octet-stream” />
       <mimeMap fileExtension=”.clr” mimeType=”application/octet-stream” />
       <mimeMap fileExtension=”.json” mimeType=”application/json” />
       <mimeMap fileExtension=”.wasm” mimeType=”application/wasm” />
       <mimeMap fileExtension=”.woff” mimeType=”application/font-woff” />
       <mimeMap fileExtension=”.woff2″ mimeType=”application/font-woff” />
     </staticContent>
     <httpCompression>
       <dynamicTypes>
         <add mimeType=”application/octet-stream” enabled=”true” />
         <add mimeType=”application/wasm” enabled=”true” />
       </dynamicTypes>
     </httpCompression>
   </system.webServer>
</configuration>

Now you should be able to launch your Uno wasm-based application hosted in Azure App Service

image

Design Time Data for Xamarin.Forms

Design Time Data for Xamarin.Forms

In my previous post I showed how to switch between Visual States using the tooling that comes with the BuildIt.Forms library. One of the other features of the tooling is the ability to load mock data that can assist with visualising how a page might look like with certain data. Rather than try to guess at what data your page might require, the tooling simply allows you to define a series of design actions. Each design action will appear within the BuildIt.Forms flyout, allowing you to invoke the action.

Let’s demonstrate this with an example. I’m going to change the layout of my page slightly so that in the DataLoaded state a ListView is displayed that takes up the entire screen. The XAML for the ListView is as follows:

<ListView x_Name=”DataList” IsVisible=”false”>
     <ListView.ItemTemplate>
         <DataTemplate>
             <ViewCell>
                 <Label Text=”{Binding Name}” />
             </ViewCell>
         </DataTemplate>
     </ListView.ItemTemplate>
</ListView>

As I don’t have any actual data at the moment, when I run up the application and click the Load Data button I see the following for the DataLoaded state:

image

This isn’t great as I’ve got no idea what my ListView is going to look like. So let’s fix this by adding a design action. I do this by calling the AddDesignAction method (it’s an extension method which is why I can access it on the MainPage) and providing a name, “Mock Data”, and the action to perform when the design action is run.

public MainPage()
{
     InitializeComponent();


    var groups = VisualStateManager.GetVisualStateGroups(this);

#if DEBUG
     this.AddDesignAction(“Mock Data”,
         () =>
         {
             var data = from i in new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
                        select new { Name = $”Item {i}” };
             DataList.ItemsSource = data;
         });
#endif
}

In this case I’m creating an IEnumerable of an anonymous type that has a property Name, which aligns with the data binding in the ListView XAML shown earlier. I’m assigning this directly to the ItemsSource of the ListView – at this stage I’m just creating the layout of the pages of my application so I might not even have View Models, which is why I’m assigning directly to the ItemSource property in place of data binding it.

Now when I run the application I see:

imageimage

imageimage

The final image shows the list of items being displayed in the ListView – clearly this layout could do with some work!

Visual State Manager Tooling in Xamarin.Forms With BuildIt.States

Visual State Manager Tooling in Xamarin.Forms With BuildIt.States

Back in the days of Silverlight/Windows Phone Microsoft launched a tool called Expression Blend that allowed developers and designer to work in harmony with developers doing their thing (ie write code) in Visual Studio and designers creating the user experience in XAML using Expression Blend. Fast forward a few years and Expression Blend has been rebadged to Blend for Visual Studio and most of the features of Blend have now been migrated to Visual Studio. With the demise of Windows Phone and the lack of developer interest in building for just Windows, Blend is now a tool that most developers have all but forgotten. So, why am I bringing this up now? Well, one of the features I missed from Blend is the ability to have design time data that allows you to build out the entire user interface, with the design time data being replace by real data when the application is run. Whilst there have been some attempts at providing a design time experience for Xamain/Xamarin.Forms, the reality is that it comes no where close to what Blend was able to do in its heyday.

If we look at other platforms, such as React Native, there has been a shift away from design time experience, across to an interactive runtime experience. By this I mean the ability to adjust layout and logic of the application whilst it’s running, which relies on the platform being able to hot-reload both layout and logic of the application. There are some third party tools for Xamarin.Forms that partially enable this functionality.

One of the challenges I found when working with Visual States is that you often need to get the application to a certain point, or follow a particular sequence of steps in order to get a specific Visual State to appear. Take the example I provided in my previous post on page states where I provided DataLoaded and DataFailedToLoad states – in the example the appearance of these states was completely random, so you might have to click the button a couple of times in order to get the state to appear. Luckily, the BuildIt.Forms library has a slightly-hidden feature that allows you to manually switch between states. I say it’s slightly-hidden because if you connect your Visual States to a StateManager in your ViewModels (shown in either this post or this post) you’ll see this feature automatically. In the example I covered in my previous post I needed to add the following line to the end of the MainPage constructor:

public MainPage()
{
     InitializeComponent();
    var groups = VisualStateManager.GetVisualStateGroups(this);
}

Now, when I run the application I see a small dot appear in the bottom left of the screen.

image

Clicking on the dot reveals a flyout that allows you to switch states:

App14UWP20190317125937

Note that this is only shown when the Visual Studio debugger is attached so will not impact the way your application works in release mode.

Page State with the Visual States Manager for Xamarin.Forms

Page State with the Visual States Manager for Xamarin.Forms

One of the current limitations of the Xamarin.Forms implementation of the Visual State Manager (VSM) is that it only works for setting properties on an individual control. Whilst this is great for control state management (think button states like disabled, pressed etc), its incredibly limiting and makes it unsuitable for some typical visual state scenarios. The one that often comes up in a mobile application is for pages that load data. In this scenario you typically have a least three states: Loading, DataLoaded, DataFailedToLoad. In some cases you might even extend this to have states such as Refreshing or LoadingMoreData. For these states you probably want to show/hide different elements on the screen, which is why the current Xamarin.Forms implementation of the VSM isn’t a great option.

Luckily there’s an alternative, which is the Visual State Manager that’s part of the BuildIt.Forms library. Here’s a quick example of it in action:

<?xml version=”1.0″ encoding=”utf-8″ ?>
<ContentPage
             
             
              x_Class=”App14.MainPage”>
     <vsm:VisualStateManager.VisualStateGroups>
         <vsm:VisualStateGroups>
             <vsm:VisualStateGroup Name=”LoadingStates”>
                 <vsm:VisualState Name=”Loading”>
                     <vsm:VisualState.Setters>
                         <vsm:Setter Value=”True” Element=”{x:Reference LoadingLabel}” Property=”IsVisible” />
                     </vsm:VisualState.Setters>
                 </vsm:VisualState>
                 <vsm:VisualState Name=”DataLoaded”>
                     <vsm:VisualState.Setters>
                         <vsm:Setter Value=”True” Element=”{x:Reference LoadedLabel}” Property=”IsVisible” />
                     </vsm:VisualState.Setters>
                 </vsm:VisualState>
                 <vsm:VisualState Name=”DataFailedToLoad”>
                     <vsm:VisualState.Setters>
                         <vsm:Setter Value=”True” Element=”{x:Reference FailedLabel}” Property=”IsVisible” />
                     </vsm:VisualState.Setters>
                 </vsm:VisualState>
             </vsm:VisualStateGroup>
         </vsm:VisualStateGroups>
     </vsm:VisualStateManager.VisualStateGroups>

     <StackLayout VerticalOptions=”Center”>
         <Label Text=”Loading…” x_Name=”LoadingLabel” HorizontalOptions=”Center”  IsVisible=”False” />
         <Label Text=”Success: Data Loaded!!” x_Name=”LoadedLabel” HorizontalOptions=”Center” IsVisible=”False” />
         <Label Text=”Failure :-(” x_Name=”FailedLabel” HorizontalOptions=”Center” IsVisible=”False” />
         <Button Text=”Load Data” Clicked=”LoadClicked” />
     </StackLayout>
</ContentPage>

In this case we’ve defined three Visual States that correspond to showing the LoadingLabel, LoadedLabel and FailedLabel respectively. The code behind for the LoadClicked method illustrates how easily you can switch between the states:

private readonly Random rnd = new Random();


private async void LoadClicked(object sender, EventArgs e)
{
     var success = rnd.Next(0, 1000) % 2 == 0;
     await VisualStateManager.GoToState(this, “Loading”);
     await Task.Delay(2000);
     await VisualStateManager.GoToState(this, success ? “DataLoaded” : “DataFailedToLoad”);
}

Ok, so one last thing we can add in is a bit of animation to make the transition between states a little smoother. Let’s fade our labels in and out:

<vsm:VisualState Name=”Loading”>
     <vsm:VisualState.ArrivingAnimations>
         <animations:AnimationGroup>
             <animations:AnimationGroup.PostAnimations>
                 <animations:FadeAnimation Opacity=”1″
                                           Duration=”500″
                                           Element=”{x:Reference LoadingLabel}” />
             </animations:AnimationGroup.PostAnimations>
         </animations:AnimationGroup>
     </vsm:VisualState.ArrivingAnimations>
     <vsm:VisualState.LeavingAnimations>
         <animations:AnimationGroup>
             <animations:AnimationGroup.PreAnimations>
                 <animations:FadeAnimation Opacity=”0″
                                           Duration=”500″
                                           Element=”{x:Reference LoadingLabel}” />
             </animations:AnimationGroup.PreAnimations>
         </animations:AnimationGroup>
     </vsm:VisualState.LeavingAnimations>

     <vsm:VisualState.Setters>
         <vsm:Setter Value=”True” Element=”{x:Reference LoadingLabel}” Property=”IsVisible” />
     </vsm:VisualState.Setters>
</vsm:VisualState>

The XAML adds a fade in after the state transition has occurred (Post animation) when transitioning to (Arriving at) the the Loading state, and a fade out before the state transition has occurred (Pre animation) when transitioning from (Leaving) the Loading state. As you can see the XAML gets fairly verbose but it’s structured this way to allow for complex combinations and sequences of animations:

<animations:AnimationGroup.PostAnimations>
     <animations:SequenceAnimation>
         <animations:ParallelAnimation>
             <animations:FadeAnimation Opacity=”1″ Duration=”500″ Element=”{x:Reference LoadingLabel}” />
             <animations:ScaleAnimation Scale=”5″ Duration=”500″ Element=”{x:Reference LoadingLabel}” />
             <animations:SequenceAnimation>
                 <animations:RotateAnimation Rotation=”10″ Duration=”250″ Target=”LoadingLabel” />
                 <animations:RotateAnimation Rotation=”0″ Duration=”250″ Target=”LoadingLabel” />
                 <animations:RotateAnimation Rotation=”-10″ Duration=”250″ Target=”LoadingLabel” />
                 <animations:RotateAnimation Rotation=”0″ Duration=”250″ Target=”LoadingLabel” />
             </animations:SequenceAnimation>
         </animations:ParallelAnimation>
         <animations:ScaleAnimation Scale=”1″ Duration=”500″ Element=”{x:Reference LoadingLabel}” />
     </animations:SequenceAnimation>
</animations:AnimationGroup.PostAnimations>

And let’s see this in action:

App14UWP20190317022241

Hopefully you can see from this short post how you can leverage the BuildIt.Forms Visual State Manager to do complex page state management as well as animations. We’ve just released a new beta package compatible with the latest Xamarin.Forms v3.6 and would love feedback (https://www.nuget.org/packages/BuildIt.Forms/2.0.0.27-beta).

Updated Uno Visual Studio Extension

Updated Uno Visual Studio Extension

I just noticed that the Uno Visual Studio Extension has been updated, so I figured I’d give it a go in Visual Studio 2019. After installing the extension I used the new startup dialog on Visual Studio to “Create a new project”. I searched Uno but Cross-Platform or any of the target platforms would show you the templates.

image

After selecting the Cross-Platform App (Uno Platform) template I had to enter a few details before hitting Create

image

Seconds later I had a brand new solution with five projects giving me the ability to target iOS, Android and Wasm all from the code I write in a UWP app.

image

Selecting the Wasm project I set it as the startup project and hit F5 to run. After a few minutes of building (the first build is slow as it downloads packages etc) it launched Chrome with my fancy Hello World project running.

image

Note: Small confession that I had to run the project twice because the first time failed without error. On second attempt it ran successfully. However, it’s been a bit hit and miss in terms of getting it to run. I added “<MonoRuntimeDebuggerEnabled>true</MonoRuntimeDebuggerEnabled>” to the csproj file and that seems to have got it to run more reliably.

Adding Content

I wanted to add some content to my page but figured I’d start off slow – how about a couple of labels and a button:

<Page
     x_Class=”FirstUnoProject.MainPage”
    

    
    
    

    
     mc_Ignorable=”d”>
   <Grid Background=”{ThemeResource ApplicationPageBackgroundThemeBrush}”>
     <StackPanel>
       <TextBlock Text=”Hello, world !” Margin=”20″ FontSize=”30″ />
       <TextBlock Text=”Hello, world !” Margin=”20″ FontSize=”30″ />
       <TextBlock Text=”Hello, world !” Margin=”20″ FontSize=”30″ />
       <Button Content=”Press Me!” Click=”IveBeenPressed” />
     </StackPanel>
   </Grid>
</Page>

and a bit of code behind:

public async void IveBeenPressed(object sender, RoutedEventArgs e)
{
     await new MessageDialog(“I’ve been Pressed!”, “Pressed”).ShowAsync();
}

Now tell me you don’t expect this to work on the web, right? Sure enough works a treat.

image

It’d be great if the message box had “Pressed” as the title instead of “localhost:5210 says” but I’m still mind blown that this still works?

One thing to be aware of is that I’ve had some mixed experiences with Wasm as the resoluts seem to vary depending on which combination of Uno packages are referenced. This is definitely a work in progress but I feel that this is probably in line with where WebAssembly support is at across the board.

Blend Still Lives

Blend Still Lives

I was surprised when editing the XAML of a UWP project that I saw a prompt to open the page in Blend – I’d all but forgotten that Blend exists.

image

On launching Blend I noticed the fancy new splash screen but is the only thing that’s been worked on? Well I currently don’t use Blend, even for UWP development, so I’m not sure why this product even exists, considering most of its features are covered by the new tool windows in Visual Studio.

I did notice that when editing the UWP page, there was at least support for Visual States. Back in its prime, Blend led the way with developer-designer engagement. Now with hot reload support in most major frameworks, the reliance on a design time experience as all but gone away. I think it’s time to say RIP to Blend and move forward with a different approach to XAML developers.

Web Development with NO JavaScript; Is Uno the Future Web Platform?

Web Development with NO JavaScript; Is Uno the Future Web Platform?

This is probably stating the obvious but I’m a big advocate for rich client applications. With the recent advances in PWAs I’m looking down the barrel of having to concede to all those fellow developers that have jacked themselves up on as many JavaScript frameworks they can find and now charge through the roof because they’re one of only a handful who actually understand the difference between == and ===. I’m sure the time will come but for now, it may be that the Uno Platform can help me leverage my UWP skills in building apps for iOS, Android and the Web (via WebAssembly).

In my previous post I covered Getting Started with Platform Uno where I simply used the extension to create a new project and discussed running it on various platforms. One of the features of UWP that I really like is that ability to gracefully handle different screen sizes through the use of Visual States. So I figured I’d give states a go in my basic Uno app. Here’s the XAML (note there’s no code behind) for my MainPage:

<Page x_Class=”UnoGettingStarted.MainPage”
      

      
      
      

      
       mc_Ignorable=”d”>
     <Grid>
         <VisualStateManager.VisualStateGroups>
             <VisualStateGroup x_Name=”SizeGroup”>
                 <VisualState x_Name=”Small”>
                    <VisualState.StateTriggers>
                         <AdaptiveTrigger MinWindowWidth=”0″ />
                     </VisualState.StateTriggers>

                     <VisualState.Setters>
                         <Setter Target=”MainContent.Visibility”
                                 Value=”Collapsed” />
                     </VisualState.Setters>
                 </VisualState>
                 <VisualState x_Name=”Large”>
                    <VisualState.StateTriggers>
                         <AdaptiveTrigger MinWindowWidth=”1000″ />
                     </VisualState.StateTriggers>

                 </VisualState>
             </VisualStateGroup>
         </VisualStateManager.VisualStateGroups>
         <StackPanel VerticalAlignment=”Stretch”
                     x_Name=”MainContent”
                     HorizontalAlignment=”Stretch”>
             <TextBlock Text=”Hello, world !”
                        Margin=”20″
                        FontSize=”30″ />
             <Button Content=”Test”
                     Click=”TestClick” />
         </StackPanel>
     </Grid>
</Page>

This XAML shows two Visual States, “Small,” hides the MainContent StackPanel, and “Large” which has no setters, so is the default states of the page. I’ve added an AdaptiveTrigger to both states for clarity. The “Small” Visual State for window sizes from 0; The “Large” Visual State for window sizes over 1000.

Whilst this is a relatively simple example, when I build and run this, it not only works on UWP (expected) but also on Wasm. The image below shows the output – the red text has been added afterwards to indicate which Visual State the page is in.

image

Serious props to the Platform Uno team, this is awesome.

Getting Started with Platform Uno

Getting Started with Platform Uno

A while ago I posted on Building a TipCalc using Platform Uno and at the time there was quite a few steps to jump through to get a basic application running from scratch. In this post I’m going to cover off how incredibly easy it now is to get started with the Uno Platform. Before I get into the steps, I want to give some background on why after almost a year am I coming back to looking at Uno. For those who have been reading my blog or have worked with Built to Roam you’ll know that we specialise in building cross-platform applications, whether it be a mobile app spanning iOS and Android, a Windows app targeting desktop and Xbox, or an enterprise solution that’s available across web, mobile and desktop. With a deep heritage in the Microsoft ecosystem we have seen the emergence of technologies such as Xamarin.Forms – historically this was rudimentary framework for rapidly developing forms based applications, primarily for line of business solutions. We’ve also seen other frameworks emerge such as React Native, Flutter and of course PWAs. Each framework has its advantaged and disadvantages; each framework uses a unique set of tools, workflow and languages. The question we continually ask ourselves is which framework is going to provide the best value for our customers and that will allow us to build user interfaces that include high fidelity controls and rich animation.

We also evaluate frameworks based on the target platforms that they support, which is what has led me to this post. One of the amazing things about Xamarin.Forms is that it has provided support for the three main platforms, iOS, Android and Windows, as part of the core platform. In fact the tag line is currently “Native UIs for iOS, Android and Windows from a single, shared codebase”.

image

What’s mind blowing is if you look at the Other Platforms page you’ll see that there is also support for GTK, Mac, Tizen and WPF. Unfortunately, these other platforms do not get the same love as the core platforms, so don’t expect them to be kept up to date with the latest releases.

At this point you might be thinking, why stray from Xamarin.Forms? Well in recent times there has been a shift away from supporting UWP as a core component of Xamarin.Forms. When asked on Twitter about UWP support for Shell, David Ortinau’s response was just another nail in the coffin for UWP app developers who are already struggling an up hill battle to convince customers of the value proposition of building for Windows.

image

So this leads me to again revisit other frameworks but we find the situation isn’t much better:

  • React Native – iOS and Android only – There is a React Native for Windows but again, it’s not part of the core offering, so it will trail (perhaps not by much but the commit history indicates a difference between 1 day ago for the main Reach Native repo and 26 days ago on the Windows repo, for the most recent commit).
  • Flutter – iOS and Android only – There is work on desktop embedding and having Flutter work on the web, so perhaps we’ll see more support beyond Google I/O
  • PWAs – varying level of support on different platforms – Clearly Microsoft sees this as the path forward for some of their Office suite of apps but the lack of native UI I think is still a limitation of PWAs.

At this point I remembered that Uno provided an interesting take on cross platform development. I also remembered that they’ve been doing a lot of work to support WebAssembly, so perhaps this could be the perfect solution. In the simplest form, the Uno Platform is #uwpeverywhere (an initiative that I’ve long believed Microsoft should have championed, after all it’s called Universal for a reason, right?) but beyond that Uno is about being able to “Build native apps for Mobile and Web using XAML and C#”.

image

Let’s get cracking with building a Uno application and see how it pans out. If you’re on the Uno Platform homepage and wondering how to get started, don’t worry, you’re not alone – I was looking for a big “Get Started” button but instead I see links to sample apps and to the source code. If you find yourself across at the source code, you’re about to embark down the wrong path – you don’t need to grab their source code as everything is distributed via nuget! So where do you go? Well you need to find the Uno Documentation and then click the link to Getting Started – now we’re cooking with gas! Unfortunately most of this page is pretty useless until you come to want to debug your application on WebAssembly. Instead what you really want to do i install the Uno Visual Studio Extension and use that to create your application.

Getting Started

  • Install the Uno Visual Studio Extension
  • Open Visual Studio and select File, New, Project
  • Search for “cross platform” and select the Cross-Platform App (Uno Platform) template

image

  • Important: Update nuget package references – if you don’t do this, it’s unlikely that your application will run as a WebAssembly (check the “Include prerelease” to get the latest update for Wasm support)

image

  • For WebAssembly in the csproj file:
    • Add <DotNetCliToolReference Include=”Uno.Wasm.Bootstrap.Cli” Version=”1.0.0-dev.214″ /> into the same ItemGroup as the PackageReference for Uno.Wasm.Bootstrap
    • Add <MonoRuntimeDebuggerEnabled>true</MonoRuntimeDebuggerEnabled> to the initial PropertyGroup
    • Change the Project element to <Project Sdk=”Microsoft.NET.Sdk.Web”>
  • Build and run each platform – I’m showing UWP, Android and WebAssembly here but iOS works straight from the template too

image

So, now that we have a UWP application that runs on iOS, Android, Windows and Web, are we satisfied with this as a cross platform solution? I think I’m enjoying working in UWP again but it’ll take a bit more investigation to see if this is a viable solution or not.

———-

Contact Built to Roam for more information on building cross-platform applications

———-