Xamarin Best Practices

In a recent blog post, I showed the C# best practices we use at my current placement. Today, the Xamarin best practices:

Xamarin 🐒 Best Practices

The Do’s 🙌

👍 Catch XAML Errors Early

Add the following attribute to code behind in order to improve performance and catch xaml errors early.

[assembly: XamlCompilation (XamlCompilationOptions.Compile)]

Why: https://stackoverflow.com/questions/46338575/bad-xaml-still-compiles-with-no-error-then-runtime-error-occurs-in-xamarin-form/46338664 

👍 By convention the identifier for the ViewModel is vm (not Vm or vM)

👍 The only code in code-behind (e.g., foo.xaml.cs) should be

  • initialize in the constructor
  • create the view model
  • assign the datacontext to the view model
  • call the viewmodel’s Initialize method
  • Lifecycle methods such as OnAppearing and OnDisappearing

Why: we want to keep the code behind as sparse as possible. Unit testing requires reaching into code and that is infinitely easier with a viewmodel.

👍 Every viewmodel should have an initialize method called from the code behind.

Why: Having an initialize method keeps most of the code for the vm out of the constructor. This is recommended practice by Microsoft, and allows for async methods.

👍 Create viewmodel name by appending “viewmodel” to the xaml name

LigthController.xaml
  LightController.xaml.cs
     LightControllerViewModel.cs

Why: It is far easier to find the file you want if we follow a convention.

👍 Use commands rather than event handlers

// wrong - handled in code behind
<button Text="Divide by 2" Clicked="onClick" />  

//correct - handled in viewmodel
<button Text="Divide by 2" ClickedCommand="{Binding DivideBy2Command"

Why: It is much easier to write unit tests when the event handler is in the viewmodel. Update: Use the Xamarin Community Toolkit to create commands out of events.

👍 ListView ItemSource should bind to Observable Collections instead of Lists

Why: Observable Collections provide notifications when items get added, removed, or when the whole list is refreshed. Lists do not provide these notifications. Warning, there is no automatic push notification if a member of the list is changed.

👍 Set BindingContext in ctor of the View CodeBehind

Why: This will prevent timing issues that may prevent the Content Page Title from displaying

👍 Place async method calls in OnAppearing in the View CodeBehind rather than in the constructor

  //wrong
  public PointsListView()
  {
     viewModel =
               new PointListViewModel(pointService, Device, SelectedModule, ObjectType);
     Task.Run(async()=> await viewModel.PopulateMenuOptions());
     
  }
  //correct
  public PointsListView()
  {

  }

  protected override async void OnAppearing()
  {
     viewModel =
               new PointListViewModel(pointService, Device, SelectedModule, ObjectType);
     await viewModel.PopulateMenuOptions();
  }

Why: The ctor should only be initializing the view and should not make calls to controller.
And Microsoft support said so 😄

The Don’ts 🙅

😦 Do not assign more than one view to a view model. Generally speaking, it should be one view to one view model.

Why: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/enterprise-application-patterns/mvvm#connecting-view-models-to-views 

😦 Do not put Xaml in templates in App.xaml. Put the Xaml in the Xaml file.

Why: App.xaml quickly becomes bloated and hard to work with. Having the Xaml in the Xaml file is natural and helps create the troika we want: foo.xaml, foo.xaml.cs and fooViewModel.cs.

😦 Do not pass view modes to methods of other pages

😦 Avoid Xaml file names ending in “view”

LightControllerView.xaml
   LightControllerView.xaml.cs
      LightControllerViewViewModel.cs

Why: Adding view to a view file is redundant and it makes reading the name of the ViewModel more difficult.

😦 Do not end async method names with ‘Async’

Why: It is easy to forget.

About Jesse Liberty

Jesse Liberty has three decades of experience writing and delivering software projects and is the author of 2 dozen books and a couple dozen Pluralsight & LinkedIn Learning courses. He was a Senior Technical Evangelist for Microsoft, a Distinguished Software Engineer for AT&T, a VP for Information Services for Citibank and a Software Architect for PBS. He is a Xamarin Certified Mobile Developer and a Xamarin MVP and a Microsoft MVP.
This entry was posted in Essentials. Bookmark the permalink.