Modernize WinForms and WPF apps with BlazorWebView

You may have heard about Blazor Desktop, Blazor Hybrid, or maybe Blazor Native. All of them are the same, just different names. What it really is, is the BlazorWebView. A control for .NET MAUI (and Xamarin.Forms), WinForms and WPF.

BlazorWebView can be seen as the third option about how you will host your Blazor app. If you are a Blazor web developer you probably already know about Blazor Server and Blazor WebAssembly. With BlazorWebView you will host Blazor inside of your native app, in the same process as the rest of the app.

So why is this an interesting thing for WPF or WinForms developers?

  • You can reuse your Blazor components from your web projects.
  • You can use Blazor components from the community or third-party vendors, like Progress Telerik and Syncfusion.
  • You can develop your app with web technology and have full native access (to what the platform offers).
  • You can take your website and add it to a native shell and improve the experience with some native features.

Modernize your app

Because you can use BlazorWebView as all other controls, you can use it wherever you want in your app. This means that you can use BlazorWebView to modernize your apps. For example, if you have an old WinForms app that you maybe want to replace with a website or you want to add new features to it that you already have on your website you can easily take your Blazor component and add them inside of your app. Instead of developing that feature again for the app, you are reusing what you already have developed. In the long run, you maybe will replace the whole app with a website but with this strategy you can do it step by step instead. Or you will keep the app, but with just web UI, but you have specified the website up with some native stuff.

Combine native and web UI

A common strategy with BlazorWebView will be to keep some parts of the app native, navigation for example. In a WinForms or a WPF app, you probably want to have the menu native, but the actual content can be in a BlazorWebView and you can share it with your websites or with a .NET MAUI app for, iOS, Android, and/or MacOS. If you spcify a control that are a Router, you can also navigate inside of your BlazorWebView.

How to use BlazorWebView

To use BlazorWebView you need to install the platform-specific Nuget package to your app project. In this repository on GitHub you can see how I am using Blazor WebView in a project I am working on, https://github.com/dhindrik/CodeBlogger.

You have to create a wwwroot folder in your project and that need to contain an HTML file and you need to include the following script:

<script src="_framework/blazor.webview.js"></script>

Note, the script tag should not include autostart="true". That is only for .NET MAUI apps.

The HTML file needs to contain a container where the component should be inserted. For example, you can insert a div with an id set to “app”. You will point to that selector from your code.

<div id="app"></div>

CSS file or other content should be placed inside of the wwwroot folder.

In the project file you should change the top line from:

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

to

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

If you not are changing that, it will not work to have razor components inside of that project.

In the project file, you also have to add this rows to handle the web content.

<ItemGroup>
    <Content Update="wwwroot\**">
        <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
</ItemGroup>

WinForms

The NuGet package you need to install is Microsoft.AspNetCore.Components.WebView.WindowsForms

Open the code view for the form where you want to add the BlazorWebView to. You need to create a ServiceCollection because WinForms will not have that in the startup as a .NET MAUI app. If you are using BlazorWebView in multiple places in your app you can of course reuse the same ServiceCollection between them. You need to add the following using:

using Microsoft.AspNetCore.Components.WebView.WindowsForms;

When you have done that you can call AddBlazorWebView() to add it to the ServiceCollection.

After that, you can create the BlazorWebView and add the component you want to show to it. For the HostPage property you should specify the path to the HTML file.

The last step is to add the BlazorWebView to the view, in this case to the root control of the view. But you can add it to which control supports subcontrols that you want.

var services = new ServiceCollection();
services.AddBlazorWebView();

var blazorWebView = new BlazorWebView()
{
    Dock = DockStyle.Fill,
    HostPage = @"wwwroot\index.html",
    Services = services.BuildServiceProvider(),
};

blazorWebView.RootComponents.Add<Editor>("#app");

Controls.Add(blazorWebView);

WPF

The NuGet package you need to install is Microsoft.AspNetCore.Components.WebView.Wpf

To add a BlazorWebView to a WPF is very similar to how it works for WinForms, but you will do it from "the code behind" and you need to create an instance of the RootComponent object and set the ComponentType property to the type of component you want to use.

The reason I don't do this in the XAML is that we need to pass the ServiceCollection. It is doable in XAML too, if you prefer it, but I think this way is more simple.

var services = new ServiceCollection();
        services.AddBlazorWebView();

        services.AddSingleton<IPostService, PostService>();
        var blazorWebView = new BlazorWebView()
        {
            HostPage = @"wwwroot\index.html",
            Services = services.BuildServiceProvider(),

        };

        blazorWebView.RootComponents.Add(new RootComponent()
        { 
            ComponentType = typeof(Editor),
            Selector = "#app"
        });

        Content = blazorWebView;

  12/2/2021 - 11:51 AM