Implementing a .NET MAUI Blazor Hybrid App with ZXing QR/Barcode Scanner

Explore QR/Barcode scanning in MAUI(Blazor) by building a simple app.

Mobile application development has witnessed significant changes and advancements in recent years. One of the notable shifts is the rise of cross-platform development frameworks that allow developers to build apps for multiple platforms with a single codebase. .NET MAUI, or Multi-platform App UI, is a robust framework developed by Microsoft that empowers developers to create native applications for iOS, Android, and Windows using C# and .NET.

Blazor, another technology from the .NET ecosystem, is a framework for building interactive web applications using C# and .NET. Blazor WebAssembly enables you to run C# code directly in the browser, allowing for feature-rich web applications with the convenience of C#. .NET MAUI Blazor Hybrid, the combination of .NET MAUI and Blazor, offers an exceptional platform for creating cross-platform mobile applications with web-like user interfaces. In this article, we'll explore how to implement a .NET MAUI Blazor Hybrid app with a QR/Barcode scanner using the ZXing.Net.Maui library.

Getting Started with .NET MAUI Blazor Hybrid Before we delve into incorporating a QR/Barcode scanner, let's briefly outline the necessary setup steps for a .NET MAUI Blazor Hybrid project:

Prerequisite

  1. Create a New Project: .NET MAUI Blazor App.

    I assume you know how to create a basic MAUI Blazor app. If not, use the provided link.

  2. Install the ZXing.Net.MAUI NuGet package on your .NET MAUI application.

  3. Follow all required steps to enable the ZXing.Net.MAUI component.

    1. UseBarcodeReader

    2. Android and iOS permissions

Let's start to write some code

We will reversely begin our journey, create an XAML page for our custom camera UI, and then connect it to our Razor page.

We have to create a new XAML page and incorporate the scanner functionality.

The following code is dedicated to scanning QR codes and barcodes. The zxing:CameraBarcodeReaderView control from the ZXing library is utilized for this purpose. When the control detects barcodes, a BarcodesDetected method will be triggered.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MauiApp3.CameraPage"
             xmlns:zxing="clr-namespace:ZXing.Net.Maui.Controls;assembly=ZXing.Net.MAUI"
             Title="Scan">
    <VerticalStackLayout>
        <Label 
            Text="Scanner"
            VerticalOptions="Center" 
            HorizontalOptions="Center" />

        <zxing:CameraBarcodeReaderView
              x:Name="cameraBarcodeReaderView"
              BarcodesDetected="BarcodesDetected" />

    </VerticalStackLayout>
</ContentPage>

The code provided below defines the behavior of the CameraPage class. It initializes and configures the barcode scanner, provides a method to await barcode scanning results, handles the event when barcodes are detected, closes the page, and returns the results to the caller.

using ZXing.Net.Maui;

namespace MauiApp3;

public partial class CameraPage : ContentPage
{
    public CameraPage()
    {
        InitializeComponent();

        cameraBarcodeReaderView.Options = new BarcodeReaderOptions
        {
            Formats = BarcodeFormats.OneDimensional,
            AutoRotate = true,
            Multiple = true
        };
    }

    private TaskCompletionSource<BarcodeResult[]> scanTask = new TaskCompletionSource<BarcodeResult[]>();
    public Task<BarcodeResult[]> WaitForResultAsync()
    {
        return scanTask.Task;
    }

    protected void BarcodesDetected(object sender, BarcodeDetectionEventArgs e)
    {
        Application.Current.MainPage.Navigation.PopModalAsync();

        scanTask.TrySetResult(e.Results);
    }
}

Let's create and connect a new Razor page with our XAML page.

The next code sets up a simple web page in our application. It provides a "Scan" button that, when clicked, opens a barcode scanning page. After scanning, the result is displayed on the main page.

@page "/"
@using ZXing.Net.Maui;

<h1>Scan Test</h1>

<button @onclick="DoScanAsync">Scan</button>

<br />

Scan Result: @scanResultLabel

@code
{
    private string scanResultLabel;

    public async Task DoScanAsync()
    {
        var scanResults = await GetScanResultsAsync();
        var barcode = scanResults.FirstOrDefault();
        if (barcode != null)
            scanResultLabel = $"Barcodes: {barcode.Format} -> {barcode.Value}";
    }

    public async Task<BarcodeResult[]> GetScanResultsAsync()
    {
        var cameraPage = new CameraPage();
        await Application.Current.MainPage.Navigation.PushModalAsync(cameraPage);

        return await cameraPage.WaitForResultAsync();
    }
}

Quick Remark #1: You cannot use MAUI components (XAML) within Blazor pages. However, if required, you can have an XAML view that mixes BlazorWebview with other MAUI elements.

Quick Remark #2: I want to mention my implementation of page navigation quickly. I created it in a simple way to minimize the complexity of the code. However, in a real-life scenario, navigation should be done using NavigationService, .NET MAUI Shell navigation, or whatever the default way of navigation is in your application.

Let's review the result.

This is how the app looks like on Android.

Conclusion

Creating a .NET MAUI Blazor Hybrid app with a QR/Barcode scanner is a powerful way to combine the strengths of .NET MAUI and Blazor for cross-platform mobile development. The ZXing library simplifies the process of adding scanning capabilities, making it easier for developers to create feature-rich applications that meet various business needs. Whether building a new app or enhancing an existing one, this combination provides a robust framework for delivering efficient and versatile mobile solutions.

Did you find this article valuable?

Support Pavlo Datsiuk by becoming a sponsor. Any amount is appreciated!