Open Manish-Pradhan-FP opened 9 months ago
I came up with this one. This has one big issue, the camera remains active after completing the scan. If you try to use DisconnectHandler, an InvalidOperationException will be thrown. But I think this can give you a starting point.
Create a MAUI Class Library project and reference ZXing.Net.Maui.Controls. Add a new MAUI ContentPage (XAML) to the project.
XAML:
<?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="SimpleScan.Maui.ScanPage"
xmlns:zxing="clr-namespace:ZXing.Net.Maui.Controls;assembly=ZXing.Net.MAUI.Controls"
Title="ScanPage"
Unloaded="OnUnloaded">
<zxing:CameraBarcodeReaderView x:Name="barcodeView" />
</ContentPage>
XAML.cs:
namespace SimpleScan.Maui;
public partial class ScanPage : ContentPage {
public event EventHandler<string>? BarcodeDetected;
public ScanPage() : this(
new global::ZXing.Net.Maui.BarcodeReaderOptions {
Formats = global::ZXing.Net.Maui.BarcodeFormats.All,
AutoRotate = true,
Multiple = false,
TryHarder = true
}
) {
}
public ScanPage(global::ZXing.Net.Maui.BarcodeReaderOptions options) {
InitializeComponent();
barcodeView.Options = options;
}
protected override void OnAppearing() {
barcodeView.BarcodesDetected += BarcodeView_BarcodesDetected;
base.OnAppearing();
}
protected override void OnDisappearing() {
barcodeView.BarcodesDetected -= BarcodeView_BarcodesDetected;
base.OnDisappearing();
}
private void BarcodeView_BarcodesDetected(object? sender, global::ZXing.Net.Maui.BarcodeDetectionEventArgs e) {
if (BarcodeDetected == null || e.Results.Length == 0)
return;
Dispatcher.Dispatch(() => BarcodeDetected?.Invoke(this, e.Results[0].Value));
}
private void OnUnloaded(object sender, EventArgs e) {
//This will throw InvalidOperationException. I assume this is a bug in CameraBarcodeReaderView.
barcodeView.Handler?.DisconnectHandler();
}
}
Add a new C# class to the project:
using ZXing.Net.Maui;
namespace SimpleScan.Maui {
public class SimpleZXingScanner {
public async Task<string> ScanAsync(string title, Page parentPage, BarcodeReaderOptions options) {
ScanPage page = new(options) {
Title = title ?? "Scan barcode"
};
await parentPage.Navigation.PushAsync(page);
TaskCompletionSource<string> tcs = new TaskCompletionSource<string>();
page.BarcodeDetected += (o, e) => tcs.TrySetResult(e);
string result = await tcs.Task;
await parentPage.Navigation.PopAsync();
return result;
}
}
}
In Xamarin Forms, we could easily trigger a Scanner simply by using Scan() and did not have to rely on creating our own view to embed this control. Is there a way I can achieve it currently or do I have to basically create my own XAML view and then embed the ScannerView ?
Previously this would work. I see no way of this now or am I missing something? ZXing.Result scanResult = await MobileBarcodeScanner.Scan();
if (scanResult != null) { xxamTableSearchEntry.Text = scanResult.Text; }