The first project with .NET MAUI

The first project with .NET MAUI

14 March 2021




Today we will migrate an existing Xamarin.Forms Application to .NET MAUI! As a victim I chose my KanbanBoard app.


First of all, we need to verify if we have prepared the development environment. The best tool for that is MAUI Check. Run the next commands in PowerShell:

dotnet tool install -g Redth.Net.Maui.Check

It will automatically attempt to fix any issues.

Solution Configuration

  1. Because .NET MAUI is not published to Nuget yet, we need to set up additional package sources.

Create NuGet.config file new the solution file

<?xml version="1.0" encoding="utf-8"?>
    <clear />
    <add key="" value="" protocolVersion="3" />
    <add key="dotnet6" value="" />
    <add key="maui" value="" />
    <add key="public" value="" />
    <add key="globalPackagesFolder" value="packages" />
  1. Edit solution file
  • Remove Platform-specific projects;
  • Remove unused Solution Configuration Platforms

The base solution configuration is done.

It's project time

.NET MAUI introduces the Single project concept, SDK-project style, and much more. Let's first migrate our platforms to the “Shared” project.

  1. For each platform create a folder in the “Shared” project:
  • Android
  • iOS
  • MacCatalyst

1.1. Android

  • Copy AndroidManifest.xml, MainActivity.cs, MainApplication.cs, all your services, Resources folder to the Android folder.

1.2. iOS, macOS

  • Copy Main.cs, Info.plist, Entitlements.plist, AppDelegate.cs, LaunchScreen.storyboard, and all your services to the iOS/MacCatalyst folder
  1. Delete Old platforms projects folders.

  2. Now we need to modify and change these files

  • From AndroidManifest.xml remove package name, version code, version name. We will set these settings later in csproj file.
  • Replace MainActivity.cs content with:
namespace YourNamespace
	using Android.App;
	using Microsoft.Maui;

	[Activity(Theme = "@style/MainTheme", MainLauncher = true)]
	public class MainActivity : MauiAppCompatActivity
  • Replace MainApplication.cs content with:
namespace YourNamespace
	using System;
	using Android.App;
	using Android.Runtime;
	using Microsoft.Maui;

	public class MainApplication : MauiApplication<Startup>
		public MainApplication(IntPtr handle, JniHandleOwnership ownership)
			: base(handle, ownership)
  • Replace AppDelegate.cs content with:
using Foundation;
using Microsoft.Maui;

namespace YourNamespace
	public class AppDelegate : MauiUIApplicationDelegate<Application>
  1. Replace all Xamarin.Forms with Microsoft.Maui
  2. Replace App.xaml.cs file content with the next code:
namespace KanbanBoard
    public partial class App : Application
        public App(IServiceProvider serviceProvider) // You can inject and resolve any service

        protected override IWindow CreateWindow(IActivationState activationState)
        	return new Microsoft.Maui.Controls.Window(new MainPage());

Here we enabled back compatibility with the Xamarin.Forms and created a new Window with the ContentPage. 6. Create Startup.cs with content:

namespace YourNamespace
	using System.Linq;
	using Microsoft.Extensions.DependencyInjection;
	using Microsoft.Maui;
	using Microsoft.Maui.Hosting;

	public class Startup : IStartup
		public void Configure(IAppHostBuilder appBuilder)
				.UseMauiServiceProviderFactory(constructorInjection: true)
                                .ConfigureServices(services =>
                                    services.AddTransient<IPath, DbPath>();
				.ConfigureFonts(fonts =>
					fonts.AddFont("fasolid.otf", "FASolid");
  1. Inherit all content pages from IPage:
public partial class MainPage : ContentPage, IPage

7.1. Replace xmlns="" with xmlns="" 8. Finally update csproj file with:

<Project Sdk="Microsoft.NET.Sdk">

		<!-- iOS, Android, MacCatalyst -->

		<!-- Display name -->

		<!-- App Identifier -->

		<!-- Versions -->

		<UseInterpreter Condition="'$(TargetFramework)' == 'net6.0-android'">True</UseInterpreter>

		<PackageReference Include="Microsoft.Maui" Version="6.0.100-preview.4.*" />

		<InvariantGlobalization Condition="'$(TargetFramework)' == 'net6.0-maccatalyst'">true</InvariantGlobalization>
		<RuntimeIdentifier Condition="'$(TargetFramework)' == 'net6.0-ios'">iossimulator-x64</RuntimeIdentifier>
		<RuntimeIdentifier Condition="'$(TargetFramework)' == 'net6.0-maccatalyst'">maccatalyst-x64</RuntimeIdentifier>
	<ItemGroup Condition="'$(TargetFramework)' == 'net6.0-android'">
		<AndroidEnvironment Include="Android\AndroidEnvironment.txt" />
		<!-- App Icon -->
			IsAppIcon="true" />

		<!-- Splash Screen -->
		<MauiSplashScreen Include="Resources\appiconfg.svg" Color="#512BD4" />

		<!-- Images -->
		<MauiImage Include="Resources\Images\*" />

		<!-- Custom Fonts -->
		<MauiFont Include="Resources\Fonts\*" />


Pay attention to the last ItemGroup. .NET MAUI is integrated with Resizetizer NT, so MauiImage and MauiFont will automatically prepare resources for all your applications.

Build and Run

# For Android
dotnet build KanbanBoard -t:Run -f net6.0-android
# For iOS
dotnet build KanbanBoard -t:Run -f net6.0-ios
# For macOS
dotnet build KanbanBoard -t:Run -f net6.0-maccatalyst


1. Android deployment (Solved)

I was not able to deploy the application to the device until specified the RuntimeIdentifiers for Android. Add this line to your csproj file:

<RuntimeIdentifiers Condition="'$(TargetFramework)' == 'net6.0-android'">android-arm;android-arm64;android-x86;android-x64</RuntimeIdentifiers>

After some unsuccessful attempts I made it running: Kanban MAUI

You can find the code changes here:


Creating Kanban Board using Xamarin Forms 5

Creating Kanban Board using Xamarin Forms 5

This article describes how to create Kanban Board using Xamarin Forms 5 only. Drag & Drop Cards, Set Column WIP, Store data in Local Db.

How to show SnackBar and Toast using Xamarin Community Toolkit

How to show SnackBar and Toast using Xamarin Community Toolkit

Demonstrate how to configure SnackBar and Toast using Xamarin Community Toolkit

An error has occurred. This application may no longer respond until reloaded. Reload 🗙