0

I'm making an app which has a a ZXing ScannerView in a ContentPage. I've managed to make it read a QR code just fine in a function in my ScanningViewModel. However, when I try to navigate away from the page with the ScannerView, it crashes. In the 'Application Output' in Visual Studio, I'm seeing a load of the 'Too soon between frames' error, which is I believe is causing the crashing. I've read that setting delays to 5 might help, but I'm not sure how to do this. This is where I read this: https://github.com/Redth/ZXing.Net.Mobile/issues/721 I've also seen some other StackOverflow articles, but they didn't really answer my question. Is there a way to fix this?

Edit: This is the other post I read on StackOverflow:

Zxing Mobile doesn't stop analysing on iOS

XAML Page:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:zxing="clr-namespace:ZXing.Net.Mobile.Forms;assembly=ZXing.Net.Mobile.Forms"
              xmlns:viewmodel1="clr-namespace:DoorRelease.ViewModel" 
             xmlns:viewmodel="clr-namespace:GardisMobileApp.ViewModel" 
             x:Class="GardisMobileApp.QRScanningPage">
    <ContentPage.BindingContext>
        <viewmodel:ScanningViewModel/>
    </ContentPage.BindingContext>
    <ContentPage.Content>
        
        <StackLayout>
            <StackLayout>
                <Label Text="Welcome to Xamarin.Forms!"
                VerticalOptions="CenterAndExpand" 
                HorizontalOptions="CenterAndExpand" />
            </StackLayout>
            <zxing:ZXingScannerView x:Name="scanner" IsScanning="{Binding isScanning}"  ScanResultCommand="{Binding GetResultCommand}" />
        </StackLayout>

    </ContentPage.Content>
</ContentPage>

My Code Behind:

namespace MobileApp
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class QRScanningPage : ContentPage
    {
        public QRScanningPage()
        {
            InitializeComponent();
            
            
        }
    }
}

My ScanningViewModel:

namespace MobileApp.ViewModel
{
    public class ScanningViewModel : BaseViewModel
    {
        private static ScanningViewModel _instance = new ScanningViewModel();
        public static ScanningViewModel Instance { get { return _instance; } }
        public string stsAddress { get; set; }
        public string apiAddress { get; set; }
        public bool isScanning { get; set; } = true;    
        public Command GetResultCommand { get; set; }
        public ScanningViewModel() : base()
        {
            Title = "QR Code Scanner";
            GetResultCommand = new Command(async(r) => await GetScannedAsync(r));
        }
        async Task GetScannedAsync(object result)
        {
            isScanning = false;
            try
            {
                var resultArray = result.ToString().Split(',');
                stsAddress = resultArray[0];
                apiAddress = resultArray[1];

                MainThread.BeginInvokeOnMainThread(async () =>
                {
                   
                    await Application.Current.MainPage.Navigation.PopAsync();
                    //await Application.Current.MainPage.DisplayAlert("Code scanned", "You've scanned a QR code!", "OK"); 

                });

            }
            catch(Exception e)
            {
                await Application.Current.MainPage.DisplayAlert("Error!", e.Message, "OK");
            }

        }
    }
}
vlad radoi
  • 13
  • 1
  • Is your problem only on iOS? – Jessie Zhang -MSFT Feb 18 '22 at 08:55
  • iOS is the only thing I've tested this on as I don't have an Android device to work with. Although from what I've read online, I believe the issue is related to the app being on iOS. – vlad radoi Feb 18 '22 at 11:00
  • 1
    How does isScanning implement INotifyPropertyChanged? If it doesn't, that's why scanning doesn't stop, the UI is never notified of the change. – Andrew Feb 18 '22 at 16:56
  • isScanning is just a bool that I've bound to to the isScanning property of the the ScannerView in XAML. I didn't think it'd need to implement the INotifyProperty stuff. My ScanningViewModel inherits from the BaseViewModel which inherits from INotifyPropertyChanged. – vlad radoi Feb 21 '22 at 08:35
  • `My ScanningViewModel inherits from the BaseViewModel which inherits from INotifyPropertyChanged` But property `public bool isScanning { get; set; } = true; ` is not in the right way .You can refer to my code in my answer. – Jessie Zhang -MSFT Feb 22 '22 at 02:43

1 Answers1

0

From document INotifyPropertyChanged Interface,we know that

The INotifyPropertyChanged interface is used to notify clients, typically binding clients, that a property value has changed.

For change notification to occur in a binding between a bound client and a data source, your bound type should either:

  • Implement the INotifyPropertyChanged interface (preferred).
  • Provide a change event for each property of the bound type.

Do not do both.

In your code, if you want to update the UI while changing the value of isScanning , you have to inplement interface INotifyPropertyChanged .

public bool isScanning { get; set; } = true;   

Please refer to the following code:

    private bool _isScanning;
    public bool isScanning
    {
        get
        {
            return _isScanning;
        }
        set
        {
            SetProperty(ref _isScanning, value);
        }
    }

And assign an initial value (true) for it in the constructor of class ScanningViewModel:

    public ScanningViewModel() 
    {  
       //assign an initial value (`true`)
        isScanning = true;

        // other code
    }
Jessie Zhang -MSFT
  • 9,830
  • 1
  • 7
  • 19