Search code examples
c#mauizxing

Opening new page after barcode detection with zxing:CameraBarcodeReaderView throws COMException


I have a plain barcode reader app that tries to navigate to a new page with the search result, but I'm getting this weird COMException that I simply don't understand.

MainPage.xaml:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MyApp.App.MainPage"
             xmlns:local="clr-namespace:MyApp.App"
             xmlns:zxing="clr-namespace:ZXing.Net.Maui.Controls;assembly=ZXing.Net.MAUI.Controls">
    <ContentPage.BindingContext>
        <local:BarcodeScannerBindingContext />
    </ContentPage.BindingContext>
    <VerticalStackLayout
        Padding="30,0"
        Spacing="25">
        <zxing:CameraBarcodeReaderView
            x:Name="cameraBarcodeReaderView"
            BarcodesDetected="OnBarcodesDetected"
            IsDetecting="{Binding IsDetectingInternal}"
            IsEnabled="{Binding IsDetectingInternal}" />
    </VerticalStackLayout>

</ContentPage>

MainPage.xaml.cs:

private async void OnBarcodesDetected(object sender, BarcodeDetectionEventArgs e)
{
    if (e.Results.Count() > 0)
    {
        BindingContext.IsDetectingInternal = false;
        string barcode = e.Results[0].Value;

        await Navigation.PushAsync(new ResultsPage(barcode)); //Throws COMException
    }
}

Stack trace:

   at WinRT.ExceptionHelpers.g__Throw|39_0(Int32 hr)
   at ABI.Microsoft.UI.Xaml.Controls.ICommandBarMethods.get_PrimaryCommands(IObjectReference _obj)
   at Microsoft.UI.Xaml.Controls.CommandBar.get_PrimaryCommands()
   at Microsoft.Maui.Controls.Toolbar.UpdateMenu()
   at Microsoft.Maui.Controls.Toolbar.MapToolbarItems(IToolbarHandler arg1, Toolbar arg2)
   at Microsoft.Maui.PropertyMapperExtensions.c__DisplayClass2_0`2.b__0(TViewHandler h, TVirtualView v, Action`2 p)
   at Microsoft.Maui.PropertyMapperExtensions.c__DisplayClass1_0`2.g__newMethod|0(IElementHandler handler, IElement view)
   at Microsoft.Maui.PropertyMapper`2.c__DisplayClass5_0.b__0(IElementHandler h, IElement v)
   at Microsoft.Maui.PropertyMapper.UpdatePropertyCore(String key, IElementHandler viewHandler, IElement virtualView)
   at Microsoft.Maui.PropertyMapper.UpdateProperty(IElementHandler viewHandler, IElement virtualView, String property)
   at Microsoft.Maui.Handlers.ElementHandler.UpdateValue(String property)
   at Microsoft.Maui.Controls.Toolbar.SetProperty[T](T& backingStore, T value, String propertyName)
   at Microsoft.Maui.Controls.Toolbar.set_ToolbarItems(IEnumerable`1 value)
   at Microsoft.Maui.Controls.NavigationPageToolbar.ApplyChanges(NavigationPage navigationPage)
   at Microsoft.Maui.Controls.NavigationPageToolbar.NavigationPageChildrenChanged(Object s, ElementEventArgs a)
   at Microsoft.Maui.Controls.Element.OnChildAdded(Element child)
   at Microsoft.Maui.Controls.VisualElement.OnChildAdded(Element child)
   at Microsoft.Maui.Controls.Element.InsertLogicalChild(Int32 index, Element element)
   at Microsoft.Maui.Controls.Page.InternalChildrenOnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
   at System.Collections.ObjectModel.ObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
   at Microsoft.Maui.Controls.NavigationPage.PushPage(Page page)
   at Microsoft.Maui.Controls.NavigationPage.MauiNavigationImpl.c__DisplayClass9_0.b__0()
   at Microsoft.Maui.Controls.NavigationPage.d__100.MoveNext()
   at MyApp.App.MainPage.d__3.MoveNext() in MyApp\\MyApp.App\\MainPage.xaml.cs:line 45

P.S.: Code for BarcodeScannerBindingContext taken from here

The question: Do I need to turn off the scanner and if so, how?


Solution

  • So, it was a threading issue. What resolved it (Thanks to @IV.'s input):

    private void OnBarcodesDetected(object sender, BarcodeDetectionEventArgs e)
    {
        if (e.Results.Count() > 0)
        {
            BindingContext.IsDetectingInternal = false;
            string barcode = e.Results[0].Value;
     
            Action action = () => {
                Navigation.PushAsync(new ResultsPage(barcode));
            };
    
            App.Current.Mainpage.Dispatcher?.DispatchAsync(action);
        }
    }