Categories
.NET .NET 8 .NET 9 .NET MAUI Android Blazor C# Code Deep Dive Desktop Developer Embedding Hybrid iOS macOS Mobile Quick Fix Web Windows WinUI 3 Xamarin Xamarin.Forms

.NET MAUI – Native Embedding

Harness the capabilities of .NET MAUI directly from the platform project.

The Native Embedding feature in .NET MAUI is a charming capability inherited from the legacy of Xamarin.Forms.

The platform project can make use of abstracted .NET MAUI pages and controls directly, showcasing its enhanced capabilities in this aspect.

To gain further insights, please consult my previous article outlining how to implement Blazor Hybrid in the WinUI 3 project.

When compared with the time of Xamarin.Forms, significant progress has been made in the implementation of this feature, such as the definition of a platform-independent extension method called ToPlatform().

But one issue that still stands out is trouble in making use of Application-level resources on the embedded pages. One of the primary reasons for this is not referencing the user-defined Application type in the UseMauiEmbedding() method call. Before the release of .NET 8, the embedding functionality operated directly on the MAUI Application type itself. However, this issue has since been resolved.

// User-defined Application type
public class MyApp : Application {}

// MAUI pipeline
var builder = MauiApp.CreateBuilder();
builder.UseMauiEmbedding<MyApp>();
var mauiApp = builder.Build();

Yet, the connection between the application and the page has not been established. This is because when using it as a regular .NET MAUI project, the (abstracted) application instance is resolved in the platform application lifecycle. But in the embedding scenario, this is not the case.

So to resolve this, define the specified workaround in the MAUI pipeline. The sample code is for the WinUI 3 project. The same applies to the other supported platforms such as Android, iOS, and macOS.

// User-defined Application type
// Defines an implicit style for Label
public class MyApp : Application
{
    public MyApp()
    {
        Resources.Add(new Style(typeof(Label))
        {
            Setters =
            {
                new() { Property = Label.TextColorProperty, Value = Color.FromArgb("#512BD4") }
            }
        });
    }
}
// A sample Page with a Label
public partial class MauiPage : ContentPage
{
    public MauiPage()
    {
        Content = new Grid()
        {
            Children =
            {
                new Label()
                {
                    HorizontalOptions = LayoutOptions.Center,
                    Text = ".NET MAUI Embedding is cool!!!",
                    VerticalOptions = LayoutOptions.Center
                }
            }
        };
    }
}
// Platform Application Window
public partial class MainWindow : Window
{
    public MainWindow()
    {
        this.InitializeComponent();
        // MAUI pipeline
        var builder = MauiApp.CreateBuilder();
        builder.UseMauiEmbedding<MyApp>();
        var mauiApp = builder.Build();
        // With .NET MAUI Embedding, this call is required so that the Application object instance gets resolved.
        var _ = mauiApp.Services.GetRequiredService<IApplication>();
        Content = new MauiPage().ToPlatform(new MauiContext(mauiApp.Services));
    }
}

The output will be a Label presenting the specified Text in a Color that is from an implicitly defined Style at the Application level.

Behind the Scene:

The application type specified in the UseMauiApp() or UseMauiEmbedding() method call, as a generic type parameter TApp, is registered in the MAUI pipeline for the IApplication interface.

builder.Services.TryAddSingleton<IApplication, TApp>();

Once resolved, this instance becomes accessible via the Application.Current property and IPlatformApplication.Current.Application property (of type IApplication).

Hence including this workaround establishes the relationship between the application and the page, ensuring that global resources are accessible in the embedded pages as well.

Using XAML files of WinUI and .NET MAUI in the same project is unsupported due to potential compilation errors. To address this issue, a viable approach is to abstract .NET MAUI components into a separate class library, define the XAML files within it, and subsequently add the library as a reference to the platform project.

A WinUI 3 sample solution is now made available in the .NET MAUI Samples GitHub repository. Kindly refer to the src\NET_8\ or src\NET_9\ folder.

Happy coding. Stay connected as we continue to learn and share the experiences from this exciting journey of being a .NET developer.

By Vijay Anand E G

A software professional with over a decade long industry experience in developing products that spans across desktop, mobile, and web.