Let's start by getting a basic overview of .NET MAUI and how projects are structured.
This module is also available in Chinese (Simplified) & Chinese (Traditional).
- Open Part 1 - Displaying Data/MonkeyFinder.sln
This MonkeyFinder contains 1 project:
- MonkeyFinder - The main .NET MAUI project that targets Android, iOS, macOS, and Windows. It includes all scaffolding for the app including Models, Views, ViewModels, and Services.
The MonkeyFinder project also has blank code files and XAML pages that we will use during the workshop. All of the code that we modify will be in this project for the workshop.
.NET Multi-platform App UI (.NET MAUI) single project takes the platform-specific development experiences you typically encounter while developing apps and abstracts them into a single shared project that can target Android, iOS, macOS, and Windows.
.NET MAUI single project provides a simplified and consistent cross-platform development experience, regardless of the platforms being targeted. .NET MAUI single project provides the following features:
- A single shared project that can target Android, iOS, macOS, and Windows.
- A simplified debug target selection for running your .NET MAUI apps.
- Shared resource files within the single project.
- Access to platform-specific APIs and tools when required.
- A single cross-platform app entry point.
.NET MAUI single project is enabled using multi-targeting and the use of SDK-style projects in .NET 6.
Resource management for cross-platform app development has traditionally been problematic. Each platform has its own approach to managing resources, that must be implemented on each platform. For example, each platform has differing image requirements that typically involves creating multiple versions of each image at different resolutions. Therefore, a single image typically has to be duplicated multiple times per platform, at different resolutions, with the resulting images having to use different filename and folder conventions on each platform.
.NET MAUI single project enables resource files to be stored in a single location while being consumed on each platform. This includes fonts, images, the app icon, the splash screen, and raw assets.
IMPORTANT: Each image resource file is used as a source image, from which images of the required resolutions are generated for each platform at build time.
Resource files should be placed in the Resources folder of your .NET MAUI app project, or child folders of the Resources folder, and must have their build action set correctly. The following table shows the build actions for each resource file type:
Resource | Build action |
---|---|
App icon | MauiIcon |
Fonts | MauiFont |
Images | MauiImage |
Splash screen | MauiSplashScreen |
Raw assets | MauiAsset |
NOTE: XAML files are also stored in your .NET MAUI app project, and are automatically assigned the MauiXaml build action when created by project and item templates. However, XAML files will not typically be located in the Resources folder of the app project.
When a resource file is added to a .NET MAUI app project, a corresponding entry for the resource is created in the project (.csproj) file. After adding a resource file, its build action can be set in the Properties window. The following screenshot shows a Resources folder containing image and font resources in child folders:
Child folders of the Resources folder can be designated for each resource type by editing the project file for your app:
<ItemGroup>
<!-- Images -->
<MauiImage Include="Resources\Images\*" />
<!-- Fonts -->
<MauiFont Include="Resources\Fonts\*" />
<!-- Raw Assets (also remove the "Resources\Raw" prefix) -->
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>
The wildcard character (*
) indicates that all the files within the folder will be treated as being of the specified resource type. In addition, it's possible to include all files from child folders:
<ItemGroup>
<!-- Images -->
<MauiImage Include="Resources\Images\**\*" />
</ItemGroup>
In this example, the double wildcard character ('**') specifies that the Images folder can contain child folders. Therefore, <MauiImage Include="Resources\Images\**\*" />
specifies that any files in the Resources\Images folder, or any child folders of the Images folder, will be used as source images from which images of the required resolution are generated for each platform.
Platform-specific resources will override their shared resource counterparts. For example, if you have an Android-specific image located at Platforms\Android\Resources\drawable-xhdpi\logo.png, and you also provide a shared Resources\Images\logo.svg image, the Scalable Vector Graphics (SVG) file will be used to generate the required Android images, except for the XHDPI image that already exists as a platform-specific image.
An app icon can be added to your app project by dragging an image into the Resources\Images folder of the project, and setting the build action of the icon to MauiIcon in the Properties window. This creates a corresponding entry in your project file:
<MauiIcon Include="Resources\Images\appicon.png" />
At build time, the app icon is resized to the correct sizes for the target platform and device. The resized app icons are then added to your app package. App icons are resized to multiple resolutions because they have multiple uses, including being used to represent the app on the device, and in the app store.
Images can be added to your app project by dragging them to the Resources\Images folder of your project, and setting their build action to MauiImage in the Properties window. This creates a corresponding entry per image in your project file:
<MauiImage Include="Resources\Images\logo.jpg" />
At build time, images are resized to the correct resolutions for the target platform and device. The resized images are then added to your app package.
True type format (TTF) and open type font (OTF) fonts can be added to your app project by dragging them into the Resources\Fonts folder of your project, and setting their build action to MauiFont in the Properties window. This creates a corresponding entry per font in your project file:
<MauiFont Include="Resources\Fonts\OpenSans-Regular.ttf" />
At build time, the fonts are copied to your app package.
A slash screen can be added to your app project by dragging an image into the Resources\Images folder of your project, and setting the build action of the image to MauiSplashScreen in the Properties window. This creates a corresponding entry in your project file:
<MauiSplashScreen Include="Resources\Images\splashscreen.svg" />
At build time, the splash screen image is resized to the correct size for the target platform and device. The resized splash screen is then added to your app package.
Raw asset files, such as HTML, JSON, and videos, can be added to your app project by dragging them into the Resources folder of your project (or a sub-folder, such as Resources\Assets), and setting their build action to MauiAsset
in the Properties window. This creates a corresponding entry per asset in your project file:
<MauiAsset Include="Resources\Assets\index.html" />
Raw assets can then be consumed by controls, as required:
<WebView Source="index.html" />
At build time, raw assets are copied to your app package.
.NET Multi-platform App UI (.NET MAUI) apps are bootstrapped using the .NET Generic Host model. This enables apps to be initialized from a single location, and provides the ability to configure fonts, services, and third-party libraries.
Each platform entry point calls a CreateMauiApp
method on the static MauiProgram
class that creates and returns a MauiApp
, the entry point for your app.
The MauiProgram
class must at a minimum provide an app to run:
namespace MyMauiApp;
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>();
return builder.Build();
}
}
The App
class derives from the Application
class:
namespace MyMauiApp;
public class App : Application
{
public App()
{
InitializeComponent();
MainPage = new AppShell();
}
}
Fonts can be added to your app and referenced by filename or alias. This is accomplished by invoking the ConfigureFonts
method on the MauiAppBuilder
object. Then, on the IFontCollection
object, call the AddFont
method to add the required font:
namespace MyMauiApp;
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
});
return builder.Build();
}
}
In the example above, the first argument to the AddFont
method is the font filename, while the second argument represents an optional alias by which the font can be referenced when consuming it.
Any custom fonts consumed by an app must be included in your .csproj file. This can be accomplished by referencing their filenames, or by using a wildcard:
<ItemGroup>
<MauiFont Include="Resources\Fonts\*" />
</ItemGroup>
NOTE: Fonts added to the project through the Solution Explorer in Visual Studio will automatically be included in the .csproj file.
The font can then be consumed by referencing its name, without the file extension:
<!-- Use font name -->
<Label Text="Hello .NET MAUI"
FontFamily="OpenSans-Regular" />
Alternatively, it can be consumed by referencing its alias:
<!-- Use font alias -->
<Label Text="Hello .NET MAUI"
FontFamily="OpenSansRegular" />
Now that you have a basic understanding of the .NET MAUI project, let's start building an app! Head over to Part 1.