Categories
.NET .NET 8 .NET MAUI Blazor Code Desktop Developer Hybrid Windows WinUI 3 Xamarin

.NET MAUI – Blazor Hybrid – WinUI 3

Use a rich set of WinUI 3 controls with the power of Blazor Hybrid.

.NET MAUI and Blazor – Best of both modern technologies for Mobile, Desktop, and Web solutions from a single codebase.

But app development is of two categories: Existing ones and Greenfield development. New features can be part of the latter quite easily as they’re done from scratch but definitely not that easy on the former as existing investments needs to be protected. And changes can be quite expensive as it needs to be thoroughly validated before rolling out to production use.

And for now, support for Blazor Hybrid is available on Windows and macOS only. And people from Microsoft have made it clear that Linux is not on the radar for .NET 8, the current preview version :-(. And for targeting macOS, the only option would be through .NET MAUI. So this article focuses mainly on Windows desktop scenarios.

Blazor Hybrid offers a solution for both categories. For existing apps on the classic WinForms and WPF, there is a separate NuGet package for each of the AppModel with an identical API surface. This allows to slowly add new features without affecting the other areas of the app. Thus making the transition quite easy.

The API usage is covered in these two articles:

  1. .NET MAUI – BlazorWebView – Streamlined
  2. .NET MAUI – Blazor Hybrid – StartPathWhat’s new in .NET 8

When it comes to modernization, WinUI 3 (aka WindowsAppSDK) is the way forward for Windows client app development and will be the successor to classic WinForms, WPF, and UWP app models. And it offers a rich set of controls to provide that modern Windows look and feel.

And wait, we’re talking about Hybrid scenarios, with no word yet on the availability of native BlazorWebView on WinUI 3. How’re going to tackle this? Yes, there’s an option available and that’s what we’re going to see in this article.

The answer would be Native Embedding. Yup, making the .NET MAUI feature work on the native platform project. It’s the other way around. The advantage would be a rich set of WinUI 3 controls with Blazor Hybrid. Similar to the classic scenario where existing investments and Blazor Hybrid. This opens up immense opportunities in real-world apps.

using Microsoft.AspNetCore.Components.WebView.Maui;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Maui;
using Microsoft.Maui.Platform;
using TestApp.Data;
using VijayAnand.MauiBlazor.Markup;
using static Microsoft.Maui.Dispatching.Dispatcher;

namespace TestApp
{
  public sealed partial class MainWindow : Window
  {
    public MainWindow()
    {
      var services = new ServiceCollection();
      services.AddSingleton(GetForCurrentThread()!);
      services.AddMauiBlazorWebView();
      services.AddSingleton<WeatherForecastService>();
#if DEBUG
      services.AddBlazorWebViewDeveloperTools();
#endif

      Content = new Grid()
      {
        Children =
        {
          new BlazorWebView().Configure("wwwroot/index.html", "/counter", ("#app", typeof(Main), null))
                             .ToPlatform(new MauiContext(services.BuildServiceProvider()))
        }
      };
    }
  }
}

We need to look in detail at the highlighted lines, Dispatcher is necessary to work with .NET MAUI, so adding it to the DI container, then the BlazorWebView handler registration, and then a sample type to demonstrate the data-oriented Razor component. Developer tools for debug build.

Now time to add the BlazorWebView to the WinUI 3 Window content, instantiate the control and set its properties. Using my Configure() extension method, available here as a NuGet package, which simplifies the registration in just a single line.

And any .NET MAUI view/layout/page can’t be added directly to the platform window/page/layout, rather first they need to be translated into the platform control and then made use of. ToPlatform() is a common API defined on such supported controls, is invoked here to convert the View to a FrameworkElement on WinUI 3. Now it can be part of the WinUI 3 window. For demo purposes, have made it to occupy the whole Window, rather it can be used along with other controls to occupy partial window space.

And if intended to use in multiple places, managing the DI container with those services can be abstracted to a common location and accessed from there. Quite like MauiProgram.cs.

The sample application with all the code is made available in this GitHub repository.

Now the most important part, this has a downside at least for now. Since both .NET MAUI and WinUI 3 app models support XAML-based development, they both have source generators on their own. And the output generated conflict with each other while using XAML as the choice of development option. For POC purposes, have made it a complete C# project, but that won’t be the case for real-world apps. Hence logged an issue detailing the use case here, kindly leave your thoughts so that it gets the necessary attention. This limitation can be overcome with a workaround, have posted it as a comment in the same issue thread here.

Since it’s a collaboration of two app models, requires a slight change in the way resources are handled and they fall in the region of .NET MAUI. So, find them under the Resources folder.

And while working with the Unpackaged model, the below project property needs to be uncommented in the project file otherwise it’ll result in the mentioned error message. And for the Packaged model, this can stay as commented or update its value as MSIX (the default value).

<WindowsPackageType>None</WindowsPackageType>

Error message:

Unable to load DLL ‘Microsoft.ui.xaml.dll’ or one of its dependencies: The specified module could not be found. (0x8007007E)

Project Template:

A preview version of the WinUI 3 Blazor Hybrid App project template using this native embedding feature is now made available in NuGet here.

Install the CLI template using the below command.

dotnet new install VijayAnand.WinUITemplates::2.2.0-preview.2

The template is named as winui-blazor and by default, it targets net7.0, the current stable version of .NET.

dotnet new winui-blazor -n MyApp

And to create a project targeting .NET 8 preview version:

dotnet new winui-blazor -n MyApp -f net8.0

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

Advertisement

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.

2 replies on “.NET MAUI – Blazor Hybrid – WinUI 3”

[…] .NET MAUI – Blazor Hybrid – WinUI 3 [#.NET #.NET 8 #.NET MAUI #Blazor #Code #Desktop #Developer #Hybrid #Windows #WinUI 3 #Xamarin #Android #AspNetCore #Blazor Hybrid #BlazorWebView #Embedding #iOS #Mac Catalyst #macOS #Mobile #Modernization #Native Embedding #Razor #Razor Class Library #Web #WinAppSDK #Windows 10 #Windows 11 #Windows AppSDK #Windows Forms #WinForms #WinUI #WinUI3 #Xamarin.Forms] […]

Like

Comments are closed.