Xamarin

How to price Xamarin.Forms components

This post is primarily documenting my thought process when trying to come up with pricing for two premium components that we’re about to release at XAM Consulting. We’re very excited about releasing these components. We’re looking forward to contributing to the Xamarin ecosystem and helping developers build great things. Many companies I’ve worked for have clearly stated that their whole company has been built on the back of great component vendors like DevExpress and Telerik. It’s pretty amazing to know that something you’ve built has also helped build an amazing company or change the world.

The first component we are releasing is called SlideOverKit. This is a powerful component that allows you to slide over from anywhere on the screen, with nice smooth animations. It can be used to create slide menus such as a Right Side Master Detail, Mini Context Menu’s or the display of Contextual Information. The key advantage of this menu is that internally we’ve built the code using Native APIs and therefore it is has the advantages of not only being incredibly quick but it also supports swipe/touch gestures. (Note* that when I refer to Native APIs, that’s only from our internal perspective, from a developer’s perspective the component is built completely from Xamarin.Forms). To illustrate its performance and ease of use, I’ve included some samples below with the SlideOverKit component.

The second component, called TEditor, is a rich/html text editing component designed for Xamarin.Forms. It is intended to be used for the editing, importing and exporting of HTML documents. As such, it supports the majority of rich text editing functions such as Bold, Italic to text color. Like the first component, it takes only a few lines of code to include this component in a project.

So what price do I sell it for?

This is a very hard question; if you price it too high then people won’t see it’s value and if you price it too low then you won’t have enough money to continue it’s development. It’s important to me that we have continued development on the components that we sell. Nobody wants a component vendor that’s not committed.

To investigate further, I researched the components supplied within the ecosystem. There’s the many big vendors like DevExpress and Telerik, who sell their components at over $1000 per year. I’ve also know about the MR.Gestures component developed by Michael Rumpler, who sells it at a very affordable $10. That’s a huge difference in pricing, so I wanted to reach out to Michael and see if he could provide any insights based on his experiences. Michael mentioned that the amount of demand was much less than was suggested on the uservoice website for his component. He also mentioned that at the price of $10, combined with the amount of sales, it wasn’t anywhere near the amount of effort he had to put in to develop it. Michael confirmed a few suspicions that I had:

1) there’s likely to be a much lower demand than you think for a component and

2) there’s a reason companies like telerik must charge so much for their components. eg. component development is hard and it’s very time consuming.

I’ve been in software long enough to know there’s a lot of hidden time and costs in software. At a minimum you need to calculate:

  • Initial development costs
  • Costs in writing documentation
  • Costs in handling support requests (per sale)
  • Maintenance development costs

Xamarin.Forms is a fast moving target, not only because of the speed of development from the Xamarin team, but also because of the rapidly changing underlying platforms (iOS, Android and Windows). The other issues we also encounter is that most components need to use the Native APIs on the platforms.

So far we’ve spent ~150 hours on each of the components, and on top of this there is a yearly maintenance of ~50 hours. Adding these up, based on an estimate of $75 per hour development cost, leads to a cost of $11,250 in the first year and $3,750 each year after that.

It would be nice if the components were to break even in the 24 months. In order to calculate this, we need to guesstimate the amount of sales each component will generate each year. Given that each component is a niche component inside Xamarin.Forms, which is a niche in Xamarin, which is a niche in Native Apps, which is a niche in the software world. I’m really not expecting a huge amount of sales each year, for SlideOverKit. I don’t think that I would expect more than 50-100 sales per year. Assuming 75 sales in 12 months, the costs are $15,000 in the first 2 years, then $15,000 / 150 = $100 per component. Now the RichTextEditor is an even more Niche component, which I’m only expecting a few sales each per year. Assuming 10 sales per year, then $15,000 / 20 = $750.

Shouldn’t it be free and open source like in XLabs and other components?

Open source software is great, I get a lot from the open source community and love contributing to the open source community, I spent a lot of time developing the FreshMvvm Framework. The problem with projects like XLabs, is that many of the components are not feature complete or are half finished (or are implemented on only a single platform). The reason for this is that most of us contributors to XLabs, also have full-time jobs and can only work on the project in our spare time.

XLabs works great if you’re an expert in Forms, Android, or iOS and don’t mind getting your hands dirty delving deep into code. Many developers and business don’t have all day and night to be working on building components.

So I wanted to put in the effort up front so that I can help time-poor developers and businesses, so we invest in developing production ready components that are easy to use, feature rich, well documented and production ready and developers can just build awesome stuff.

If you would like early access to any of the components please feel free to contact me anytime.

Thanks

Michael

 

 

FreshMvvm 1.0 Preview Release

Since the first release of FreshMvvm it’s been a wild ride, the up take of FreshMvvm has been very impressive it’s really good to see others having success using FreshMvvm. While I’ve been using and loving FreshMvvm for a long long time, even since before it was called FreshMvvm, it’s great to see others also enjoying the Framework.

Since this release has a few large features and breaking changes I’ve decided bump the version up to 1.0 preview. Please see below of a description of the features.

Multiple Navigation Services

It’s always been possible to do any type of navigation in FreshMvvm, with custom or advanced scenarios were done by implementing a custom navigation service. Even with this ability people found it a little hard to do advanced navigation scenarios in FreshMvvm. After I reviewed all the support questions that came in for FreshMvvm I found that the basic issue people had was they wanted to be able to use our built in navigation containers multiple times, two primary examples are 1) within a master detail having a navigation stack in a master and another in the detail 2) The ability to push modally with a new navigation container. In order to support both these scenarios I concluded that the FreshMvvm required the ability to have named NavigationServices so that we could support multiple NavigationService’s.

Using multiple navigation containers

Below we’re running two navigation stacks, in a single MasterDetail.

var masterDetailsMultiple = new MasterDetailPage (); //generic master detail page

//we setup the first navigation container with ContactList
var contactListPage = FreshPageModelResolver.ResolvePageModel<ContactListPageModel> ();
contactListPage.Title = "Contact List";
//we setup the first navigation container with name MasterPageArea
var masterPageArea = new FreshNavigationContainer (contactListPage, "MasterPageArea");
masterPageArea.Title = "Menu";

masterDetailsMultiple.Master = masterPageArea; //set the first navigation container to the Master

//we setup the second navigation container with the QuoteList 
var quoteListPage = FreshPageModelResolver.ResolvePageModel<QuoteListPageModel> ();
quoteListPage.Title = "Quote List";
//we setup the second navigation container with name DetailPageArea
var detailPageArea = new FreshNavigationContainer (quoteListPage, "DetailPageArea");

masterDetailsMultiple.Detail = detailPageArea; //set the second navigation container to the Detail

MainPage = masterDetailsMultiple;

PushModally with new navigation stack

//push a basic page Modally
var page = FreshPageModelResolver.ResolvePageModel<MainMenuPageModel> ();
var basicNavContainer = new FreshNavigationContainer (page, "secondNavPage");
await CoreMethods.PushNewNavigationServiceModal(basicNavContainer, new FreshBasePageModel[] { page.GetModel() }); 

//push a tabbed page Modally
var tabbedNavigation = new FreshTabbedNavigationContainer ("secondNavPage");
tabbedNavigation.AddTab<ContactListPageModel> ("Contacts", "contacts.png", null);
tabbedNavigation.AddTab<QuoteListPageModel> ("Quotes", "document.png", null);
await CoreMethods.PushNewNavigationServiceModal(tabbedNavigation);

//push a master detail page Modally
var masterDetailNav = new FreshMasterDetailNavigationContainer ("secondNavPage");
masterDetailNav.Init ("Menu", "Menu.png");
masterDetailNav.AddPage<ContactListPageModel> ("Contacts", null);
masterDetailNav.AddPage<QuoteListPageModel> ("Quotes", null);
await CoreMethods.PushNewNavigationServiceModal(masterDetailNav);

Custom IOC Container

The second major request for FreshMvvm 1.0 was to allow custom IOC containers. In the case that your application already has a container that you want to leverage.

Using a custom IOC container is very simple in that you only need to implement a single interface.

public interface IFreshIOC
{
    object Resolve(Type resolveType);
    void Register<RegisterType>(RegisterType instance) where RegisterType : class;
    void Register<RegisterType>(RegisterType instance, string name) where RegisterType : class;
    ResolveType Resolve<ResolveType>() where ResolveType : class;
    ResolveType Resolve<ResolveType>(string name) where ResolveType : class;
    void Register<RegisterType, RegisterImplementation> ()
        where RegisterType : class
        where RegisterImplementation : class, RegisterType;
}

And then set the IOC container in the System.

FreshIOC.OverrideContainer(myContainer);

Breaking Changes

Please remember whenever you register a IFreshNavigationService it now has to have a name.

FreshIOC.Container.Register<IFreshNavigationService> (this, Constants.DefaultNavigationServiceName);

Please find this pre-release in nuget. – https://www.nuget.org/packages/FreshMvvm/1.0.0-pre1

FYI – This nuget is a pre-release nuget and you’ll need to have the ‘pre-release’ option selected on nuget.

The main repo for FreshMvvm can be found on github – https://github.com/rid00z/FreshMvvm.

Please post any issues on the github repository.

Thanks

Michael

 

MVVM / MVC is dead? Is Unidirectional a MVVM / MVC Killer?

Ah so now when you’ve learnt MVC/MVVM, everyone’s decided that we shouldn’t do it anymore? Huh?

MVVM is a great pattern which allows for a clean separation between views and logic, it also lends itself well to unit testing, but is it the only way? If you didn’t already know there’s some new kids on the block, Unidirectional User Interface Architectures which is basically applying the CRQS/Event Sourcing pattern on the client side. The idea of these patterns is to have a single DataStore which is the source of truth and data is updated via events, all Views read from the single source of Data and can only update via events/actions. From what I can gather at the moment, the specific problems they solve are 1) Avoid data being duplicated across viewmodels and stale data 2) Avoid the situation of Fat ViewModels. At the moment this concept is being driven from the web clientside world, but eventually it might make it’s way into the Xamarin world and become popular, maybe? 

There’s new unidirectional frameworks appearing all the time, the ones I’ve looked into recently are Flux and Redux.

Flux Diagram 

flux-diagram

Redux Diagram

Redux Diagram

So can we have these in Xamarin? Yes, these are simply design patterns and can easily be implemented in C#. Infact someone has already created a project based on Redux named Redux.net. In some R&D we’ve been doing on a project we’ve also implemented a Xamarin.Forms sample for the Redux.net project.

Here’s some code from the redux project:

Let’s start with our Application state.

public class ApplicationState
{
    public ImmutableArray<Todo> Todos { get; set; }

    public TodosFilter Filter { get; set; }
}

The Actions are basically any changes in your apps state.

public class AddTodoAction : IAction
{
    public string Text { get; set; }
}

public class DeleteTodoAction : IAction
{
    public Guid TodoId { get; set; }
}

public class CompleteTodoAction : IAction
{
    public Guid TodoId { get; set; }
}

public class CompleteAllTodosAction : IAction
{
    public bool IsCompleted { get; set; }
}

public class ClearCompletedTodosAction : IAction
{

}

public class FilterTodosAction : IAction
{
    public TodosFilter Filter { get; set; }
}

The application reducer will then take an Action and modify the state.

public static class ApplicationReducer
{
    public static ImmutableArray<Todo> AddTodoReducer(ImmutableArray<Todo> previousState, AddTodoAction action)
    {
        return previousState
            .Insert(0, new Todo
                {
                    Id = Guid.NewGuid(),
                    Text = action.Text
                });
    }

    public static ImmutableArray<Todo> ClearCompletedTodosReducer(ImmutableArray<Todo> previousState, ClearCompletedTodosAction action)
    {
        return previousState.RemoveAll(todo => todo.IsCompleted);
    }

    public static ImmutableArray<Todo> CompleteAllTodosReducer(ImmutableArray<Todo> previousState, CompleteAllTodosAction action)
    {
        return previousState
            .Select(x => new Todo
                {
                    Id = x.Id,
                    Text = x.Text,
                    IsCompleted = action.IsCompleted
                })
            .ToImmutableArray();
    }

    public static ImmutableArray<Todo> CompleteTodoReducer(ImmutableArray<Todo> previousState, CompleteTodoAction action)
    {
        var todoToEdit = previousState.First(todo => todo.Id == action.TodoId);

        return previousState
            .Replace(todoToEdit, new Todo
                {
                    Id = todoToEdit.Id,
                    Text = todoToEdit.Text,
                    IsCompleted = !todoToEdit.IsCompleted
                });
    }

    public static ImmutableArray<Todo> DeleteTodoReducer(ImmutableArray<Todo> previousState, DeleteTodoAction action)
    {
        var todoToDelete = previousState.First(todo => todo.Id == action.TodoId);

        return previousState.Remove(todoToDelete);
    }

    public static ImmutableArray<Todo> TodosReducer(ImmutableArray<Todo> previousState, IAction action)
    {
        if (action is AddTodoAction)
        {
            return AddTodoReducer(previousState, (AddTodoAction)action);
        }

        if (action is ClearCompletedTodosAction)
        {
            return ClearCompletedTodosReducer(previousState, (ClearCompletedTodosAction)action);
        }

        if (action is CompleteAllTodosAction)
        {
            return CompleteAllTodosReducer(previousState, (CompleteAllTodosAction)action);
        }

        if (action is CompleteTodoAction)
        {
            return CompleteTodoReducer(previousState, (CompleteTodoAction)action);
        }

        if (action is DeleteTodoAction)
        {
            return DeleteTodoReducer(previousState, (DeleteTodoAction)action);
        }

        return previousState;
    }

    public static ApplicationState Execute(ApplicationState previousState, IAction action)
    {
        return new ApplicationState
        {
            Filter = action is FilterTodosAction ? ((FilterTodosAction)action).Filter : previousState.Filter,
            Todos = TodosReducer(previousState.Todos, action)
        };
    }
}

Then the UI will be updated, below we see  a UI element binding directly to the state and updating on changes.

public partial class MainSection : ContentView
{
    public MainSection()
    {
        this.InitializeComponent();

        App.Store.Subscribe((ApplicationState state) =>
            {
                TodosItemsControl.ItemsSource = FilterTodos(state.Todos,state.Filter);
            });
    }

    private IEnumerable<Todo> FilterTodos(IEnumerable<Todo> todos, TodosFilter filter)
    {
        if(filter == TodosFilter.Completed)
        {
            return todos.Where(x => x.IsCompleted);
        }

        if(filter == TodosFilter.InProgress)
        {
            return todos.Where(x => !x.IsCompleted);
        }

        return todos;
    }
}

Should I use this over Mvvm? Will this kill Mvvm? 

In all truthfulness I (like most people) don’t know if Unidirectional User Interface Architectures are the answer but I feel like they’re going to be around for a while.

I feel like I’ve hardly done these architectures justice in my explanations but I encourage you to look further into these patterns (maybe even try them or built a Unidirectional Framework for Xamarin). Anyways here’s some links for further reading.

https://facebook.github.io/flux/

https://github.com/rackt/redux

https://github.com/GuillaumeSalles/redux.NET

http://staltz.com/unidirectional-user-interface-architectures.html

 

Dont forget to subscribe to michaelridland.com.


FreshMvvm n=3: Navigation in FreshMvvm

Here’s the next video in the  FreshMvvm n+1 series. The idea of this series is to get the video’s out to the eager listeners (you) as quickly as possible, therefore these videos are done live with almost no editing.

Episode Title: n=3: Navigation in FreshMvvm

In this episode we discuss:

  • Review FreshMvvm’s built in Navigation Abilities
  • Understand how navigation works in FreshMvvm

I hope you enjoy.

FreshMvvm n=2 – IOC and Constructor Injection

Here’s the next video in the  FreshMvvm n+1 series. The idea of this series is to get the video’s out to the eager listeners (you) as quickly as possible, therefore these videos are done live with almost no editing.

Episode Title: n=2 – IOC and Constructor Injection

In this episode we discuss:

  • Review FreshMvvm’s built in IOC container
  • Setup a decoupled Data Service with interface
  • Use the PageModel Constructor Injection
  • Use a 3rd Party Library in the IOC Container

I hope you enjoy.

 

 

FreshMvvm n=1 : Your first FreshMvvm Application

Here’s the next video in the  FreshMvvm n+1 series. The idea of this series is to get the video’s out to the eager listeners (you) as quickly as possible, therefore these videos are done live with almost no editing.

Episode Title: n=1 Your first FreshMvvm Application

In this episode we discuss:

  • Creating a New Project adding FreshMvvm
  • Automatic wiring of BindingContext
  • PageModel to PageModel Navigation
  • Automatic wiring of Page events (eg. appearing)
  • Basic methods (with values) on PageModel (init, reverseinit)

I hope you enjoy.

 

Also, if you want to know more awesome things about Xamarin.Forms then my eCourse is a must do! ‘Secrets of a Xamarin.Forms Ninja

Thanks

Michael

 

Mixing MvvmCross Native Views and Xamarin.Forms Pages

If you’ve read my blog before you probably already know that I’m a avid Mvvm supporter. You’ll also know that I use FreshMvvm alot in my Xamarin.Forms solutions. While I love FreshMvvm it’s always important to pick the right tool for the job.

In a recent project at XAM Consulting we had a project to enhance a large pre-existing application that was built in MvvmCross and ‘Xamarin Traditional’. There was a few things to consider on this project a) it was a pre-existing app with a large amount of business logic b) there was a large amount of changes required c) there was also a large amount of existing Native Views.

If you’ve been in software long enough you know rewriting is the wrong thing to do in the majority of cases. The original application had nice clean code and good architecture, we wanted to keep this but when building new screens it’s very hard to look past the advantages of Xamarin.Forms.

So essentially we wanted to both keep the Native Views and add in a few pages of Xamarin.Forms. Currently all the solutions for MvvmCross and Xamarin.Forms are related to having a Forms app with MvvmCross backend, not mixing the two.

I’ve included a diagram below to help you understand what’s happening in the app.

MvvmCrossAndXamarinForms

So what’s the secret sauce? 

It’s important to understand this is really a MvvmCross application but with support Xamarin.Forms pages instead of Native View.

Here’s some of the major components done to implement this, not a step by step guide.

1) Implementing custom MvvmCross presenters

This need to be done in both the iOS project and the Android project. In iOS the class we need to inherit is MvxTouchViewPresenter and we need to override the Show method. In Android the class we need to inherit is MvxAndroidViewPresenter. 

In Android

1
public class MvxFormsDroidPagePresenter : MvxAndroidViewPresenter, IMvxAndroidViewPresenter

In iOS

1
public class MvxFormsTouchPagePresenter : MvxTouchViewPresenter

2) Setup MvvmCross to use the new presenters

To do this we need to override the CreatePresenter method on the Setup.

In Android

1
2
3
4
protected override IMvxAndroidViewPresenter CreateViewPresenter ()
{
    return new MvxFormsDroidPagePresenter ();
}

In iOS 

1
2
3
4
5
protected override IMvxTouchViewPresenter CreatePresenter ()
{
    Forms.Init ();
    return new MvxFormsTouchPagePresenter (ApplicationDelegate ,Window);
}

3) The Secret Sauce

Generally the concepts are the same on both platforms, when we come across a ViewModel ending with XFViewModel then we assume it’s Xamarin.Forms View Model. When it’s Xamarin.Forms ViewModel we 1) Find the Xamarin.Forms Views 2) Convert it into a Native View 3) Setup the BindingContext 4) Display/Native the Native view as if it’s a MvvmCross view.

In iOS 

iOS is was much easier, primarily because Xamarin.Forms allows you to easily create a ViewController.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public override void Show (MvxViewModelRequest request)
{
    // XFViewModel means we need a Forms View
    if (request.ViewModelType.FullName.Contains ("XFViewModel")) 
    {
        //get the xamarin.forms page from the ViewModel
        var contentPage = MvxPresenterHelpers.CreatePage (request); 
 
        //MvvmCross call to create the view model with DI etc
        var viewModel = MvxPresenterHelpers.LoadViewModel (request); 
 
        //Assign it to the Forms Binding Content
        contentPage.BindingContext = viewModel;             
 
        //Creating the view controller from the content page
        var viewController = contentPage.CreateViewController ();
 
        if (this.MasterNavigationController == null) 
        {
            // If it's the first view 
            this.ShowFirstView (viewController);
        } 
        else 
        {
            // If it's already in the stack
            this.MasterNavigationController.PushViewController (viewController, true);
        }
 
    } 
    else 
    {
        //Using a normal MvvmCross View
        base.Show (request);
    }
}

In Android

It turns out this is a bit harder in Android. This is because Xamarin.Forms Navigation and MvvmCross navigation is very different, Xamarin.Forms has a single Activity for a application while MvvmCross has an activity per page, we need to trick the Xamarin.Forms pages into using a single activity.

 

Below is the Xamarin.Forms container activity, normally there would only be a single Activity but in this case we want to create a Activity for every page. You’ll also notice we resolve the MvcAndroidLifetimeMonitor and we pass the Forms activity events, this hooks the Xamarin.Forms page into the MvvmCross Navigation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
[Activity (Label = "XamarinForm", Theme = "@android:style/Theme.Holo.Light", NoHistory = false)]
public class MvxFormsApplicationActivity : FormsApplicationActivity
{
    public static Page CurrentPage;
 
    protected override void OnCreate (Bundle bundle)
    {
        base.OnCreate (bundle);
 
        Forms.Init (this, bundle);
 
        SetPage (CurrentPage);
 
        var lifetimeMonitor = Mvx.Resolve<IMvxAndroidCurrentTopActivity> () as MvxAndroidLifetimeMonitor;
        lifetimeMonitor.OnCreate (this);
    }
 
    protected override void OnStart ()
    {
        base.OnStart ();
        var lifetimeMonitor = Mvx.Resolve<IMvxAndroidCurrentTopActivity> () as MvxAndroidLifetimeMonitor;
        lifetimeMonitor.OnStart (this);
    }
 
    protected override void OnRestart ()
    {
        base.OnRestart ();
        var lifetimeMonitor = Mvx.Resolve<IMvxAndroidCurrentTopActivity> () as MvxAndroidLifetimeMonitor;
        lifetimeMonitor.OnRestart (this);
    }
 
    protected override void OnResume ()
    {
        base.OnResume ();
        var lifetimeMonitor = Mvx.Resolve<IMvxAndroidCurrentTopActivity> () as MvxAndroidLifetimeMonitor;
        lifetimeMonitor.OnResume (this);
    }
 
    protected override void OnDestroy ()
    {
        base.OnDestroy ();
        var lifetimeMonitor = Mvx.Resolve<IMvxAndroidCurrentTopActivity> () as MvxAndroidLifetimeMonitor;
        lifetimeMonitor.OnDestroy (this);
    }
}

 

Now that we have the container for the Xamarin.Forms Page we can override the show method and handle the Xamarin.Forms ViewModel requests.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public override void Show (MvxViewModelRequest request)
{
    //detect if we want a Forms View 
    if (request.ViewModelType.FullName.Contains ("XFViewModel")) {
 
        //get the Forms page from the request 
        var contentPage = MvxPresenterHelpers.CreatePage (request);
 
        //set DataContext of page to LoadViewModel
        var viewModel = MvxPresenterHelpers.LoadViewModel (request);
 
        //set the binding context of the content page
        contentPage.BindingContext = viewModel;
 
        //set the current page of the activity 
        MvxFormsApplicationActivity.CurrentPage = contentPage;
 
        //Start the Xamarin.Forms Activity
        Activity.StartActivity (typeof(MvxFormsApplicationActivity));
 
    } else {
        base.Show (request);
    }
}

 

Android also requires some extra work when Pages/Views are closed, this is because MvvmCross ignores close events if it’s not a MvvmCross view, which in this case it isn’t. So we need to handle the close ourselves and skip the ignore clauses.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public override void ChangePresentation (MvxPresentationHint hint)
{
    if (hint is MvxClosePresentationHint) {
        var viewModel = (hint as MvxClosePresentationHint).ViewModelToClose;
 
        Activity activity = this.Activity;
 
        IMvxView mvxView = activity as IMvxView;
 
        activity.Finish ();
 
        return;
    }                
}

4) The helper methods

You might have noticed both the iOS project and the Android project referenced some helper function, here’s the code from the helper classes. The functions are used to help create the View Models and Pages.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public static class MvxPresenterHelpers
{
    /// <summary>
    /// Creates a view model from a view model request
    /// </summary>
    public static IMvxViewModel LoadViewModel (MvxViewModelRequest request)
    {
        var viewModelLoader = Mvx.Resolve<IMvxViewModelLoader> ();
        var viewModel = viewModelLoader.LoadViewModel (request, null);
        return viewModel;
    }
 
    /// <summary>
    /// Create a Xamarin.Forms page from a View Model request
    /// </summary>
    public static Page CreatePage (MvxViewModelRequest request)
    {
        var viewModelName = request.ViewModelType.Name;
        var pageName = viewModelName.Replace ("XFViewModel", "Page");
        var pageType = request.ViewModelType.GetTypeInfo ().Assembly.CreatableTypes ()
            .FirstOrDefault (t => t.Name == pageName);
        if (pageType == null) {
            Mvx.Trace ("Page not found for {0}", pageName);
            return null;
        }
 
        var page = Activator.CreateInstance (pageType) as Page;
        if (page == null) {
            Mvx.Error ("Failed to create ContentPage {0}", pageName);
        }
        return page;
    }
}

The End

So that’s the core pieces of the puzzles, this blog is not a step by step guide so if you want a easy way to see this code work I recommend looking at it on github.

Github Sample Repository

Need an App built or Xamarin.Forms training? – You can hire me!

Want to be a Awesome Xamarin.Forms developer? I’m building a eCourse that’ll teach you all that you everything you need to know.

SecretsOfAXamarinFormsNinja

Creating a Native View from a Xamarin.Forms View

WARNING: this is a expert level technique and isn’t officially supported by Xamarin.

Personally I feel like this is the holy grail of Xamarin.Forms development, having the ability to jump between both Xamarin.Forms Views and Native Views. I’ve used this technique multiple times in Xamarin.Forms apps.

It’s primarily used when you’ve created a custom renderer and you’re working against Native UI APIs, this could be in the native maps API or a 3rd party native component. Now once you’re in the Native area of the application there’s cases where you need to show a view for the user but you still want to have the View shared between the platforms.

To give you an idea the structure might be as follows.

Xamarin.Forms -> Native View

In the diagram above the secret sauce is in orange, taking a Xamarin.Form View and converting that into a native view. This converts to a UIView in iOS and ViewGroup in Android.

Below I’ve written two helper classes that take a Xamarin.Forms view and convert it into the NativeViews. In my experience this code works the best when the Xamarin.Forms view is a Layout.

iOS Converter Class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class FormsViewToNativeiOS
{
    public static UIView ConvertFormsToNative(Xamarin.Forms.View view, CGRect size)
    {
        var renderer = RendererFactory.GetRenderer (view);
 
        renderer.NativeView.Frame = size;
 
        renderer.NativeView.AutoresizingMask = UIViewAutoresizing.All;
        renderer.NativeView.ContentMode = UIViewContentMode.ScaleToFill;
 
        renderer.Element.Layout (size.ToRectangle());
 
        var nativeView = renderer.NativeView;
 
        nativeView.SetNeedsLayout ();
 
        return nativeView;
    }
}

Android converter class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class FormsToNativeDroid
{
    public static ViewGroup ConvertFormsToNative(Xamarin.Forms.View view, Rectangle size)
    {
        var vRenderer = RendererFactory.GetRenderer (view);
        var viewGroup = vRenderer.ViewGroup;
        vRenderer.Tracker.UpdateLayout ();
        var layoutParams = new ViewGroup.LayoutParams ((int)size.Width, (int)size.Height);
        viewGroup.LayoutParameters = layoutParams;
        view.Layout (size);
        viewGroup.Layout (0, 0, (int)view.WidthRequest, (int)view.HeightRequest);
        return viewGroup; 
    }
}

I’ve created a github sample application, please find it https://github.com/rid00z/LoadingFormsViewFromNative. *** Please note this iOS project uses UIPopover which is only available on iPad so you must use the iPad for this demo.

If you want to know more awesome Xamarin.Forms techniques then my eCourse is a must do! ‘Secrets of a Xamarin.Forms Ninja

Thanks

Michael