M102 - NET MAUI - How It Works

M102 - NET MAUI - How It Works

How It Works for Multiple Platforms

In a previous article, I gave an introduction to .NET MAUI and showed how it can be used to create an application that runs natively on multiple platforms using a single shared project and code base.? In this article, I am going to go into more details about how this is accomplished and show you how you can then further customize the application for each platform if desired for consistency or to take advantage of underlying platform features.?

I am not going to rehash the documentation from Microsoft but each platform you target has their own way of defining the user interface, accessing the hardware, defining permissions, and define how the various components in the application communicate.? The .NET MAUI framework provides an abstraction layer over controls and APIs used to target each platform and then the base class library implementation for each platform utilizes the appropriate .NET Runtime (Mono for Android, iOS, and macOS, and then .NET Core CLR for Windows).

.NET MAUI abstraction layers

Handlers Overview

The concept of handlers is typically a more advanced topic, and I will go into more details in a future article, but a "Handler" is used to "map" an abstracted virtual view for a control into the underlying native view, instantiating the underlying native view, and mapping their cross-platform API abstractions to the native API.

Handlers and control differences

The above image shows the flow from placing a control in XAML to the outputs for each platform using the default handlers and styling for light and dark themes.? Notice how the spacing, alignment, borders, and focus indicator are slightly different when rendered on each platform and also how Android has a circular animation on the button when pressed.?

Platform Customizations

When you create a .NET MAUI project you will see a Platforms and a Resources folder at the project root.? Expanding the Platforms folder will reveal the structure shown below where there is a sub-folder and files for each platform.? Each platform has its own requirements and details for configuring, permissions, packaging, and launching an application and the framework will use the appropriate platform when compiling for a specific target.?

Platform specific project folders

Once the platform specific code has been launched, the common MauiProgram.CreateMauiApp method will be called to configure and initialize a MauiApp. The application builder uses the fluent syntax to define what class to instantiate, the fonts to use, allows you to configure a dependency injection container, define any custom mappings and handlers, and initialize any third-party libraries, etc.?

Handling Platform Differences

There are several ways you can adapt the code for different platforms (Android, iOS, Mac, Windows, Simulators) and idioms (phone, tablet, desktop) depending on how complex the difference is.? If you are writing custom controls, extending or modifying behaviors of built in controls, or accessing platform APIs then your work may be more involved and would likely be creating custom mappers, handlers or services.? At some point you need to tell the compiler which blocks of code to include for each platform and there are several ways this can be accomplished.

Conditional Compilation Constants

MAUI includes several built-in targeting constants as shown here.? Sometimes a simple conditional compilation constant #if block is all that is needed or the only way to accomplish a certain task but be cautious in its use as it can lead to code that is difficult to maintain.

Conditional compilation constants

In the image above Windows is selected but if you switch to Android, then you will see the Android code becomes active so you can "enable" blocks of code during development and get IntelliSense, colorization, etc.

?

Targeting a platform for code file

On Platform and On Idiom XAML Extensions

You can also customize platform specific behavior in XAML by using On Platform and On Idiom markup extensions.? Her you can see a couple different ways to use the extension as an inline property setter for simple changes or via XML "dot" syntax with child elements.? The extension has a default value and then allows you to customize for different platforms, here the default was green, but the WinUI platform specified to use blue and when I targeted an iPhone, the color was red, and the margin was zero.

XAML extensions and windows
XAML extensions and iOS

Partial Classes and Platform Folder Implementations

If you have to handle the same code for multiple platforms, such as the case when you are writing something around the platform specific APIs or controls (services, mappers, handlers), then it would probably best to create a partial class inside each platform folder and let the compiler include the appropriate class based on the platform.? For example, if you were to create a common service interface:

Service interface

And then create an implementation class of that interface in each platform folder:

Service partial class implementations

When SaySomething.SayHello() method is called, the appropriate platform specific message is displayed.?

Say Hello

?If you need to expose platform specific components in an interface, then you would also utilize conditional compilation constants such as how Microsoft implements their built-in handlers.? By utilizing a PlatformView alias with conditional compilation, the actual code in the interface is straight forward.

Handler code using alias

Configure Multi-Targeting Using the Project File

The above scenarios will cover most scenarios but there is another way in which you can include or exclude entire files based on the file and folder naming conventions.? By including the platform name in the file and modifying the project file the compiler will include or exclude files specific to the platform?

Filename conventions


Project file changes for filename inclusions

For additional information on this topic, see the documentation here

Putting It All Together

The .NET MAUI framework is very flexible and allows for platform specific customizations but if you are wondering why or when you would need to do this, here are a few examples of platform specific customizations I have had to make.

From the images shown in this article you can see that on Windows when an entry control has the focus, the border gets a highlight indicating that the control has the focus.? This focuses visual cue was not present on an iPad, so I created a focused highlight:

  • Created a new EntryWithBorder that inherited from Entry and added some properties: BorderWidth, FocusedBorderWidth, CornerRadius, BorderColor, and FocusedBorderColor
  • Created a style based on the default Entry style and added values for my new properties
  • Created a handler that changed the border and color when the control gains or loses focus and uses the properties added in step 1
  • Used a conditional compilation constant in the build of the mauiprogram.cs to register the handler if it's on the iOS platform
  • Changed any instance of <Entry> control on the forms and pages to <EntryWithBorder>

iOS focused higlight

Another request from a client on one of my past projects was to replace the picker behavior on the iPad with one that is consistent across platforms.? They did not like the "wheel" behavior so I had to make a picker appear at the bottom of the page where they keyboard would appear.? I was also able to utilize the previous custom entry handler to then automatically hide the picker when another control gained focus and vice-versa.

Custom picker on iOS

One more customization I did was for replacing the built-in keyboard for numeric entry with a custom keyboard on iOS to aid the users in their data.? By creating a custom handler for an EntryNumeric control I created, I was able to remove the default keyboard and totally replace it with a custom keyboard "drawn" in the C# code file.

Custom numeric keyboard on iOS

?Wrapping Up

As you can see, the .NET MAUI framework has many different ways you can customize the user interface or behaviors on a per platform basis from conditional compilation in the code behind files, partial classes and platform specific implementations, handlers, mappers, conditional XAML, depending on your needs.? Handlers and mappers are definitely a more advanced topic, and I will cover these in more detail in a future article.??

要查看或添加评论,请登录

Steve Cisco的更多文章

社区洞察

其他会员也浏览了