【问题标题】:ZXing ScannerView doesn't stop scanning even when isScanning is set to false即使 isScanning 设置为 false,ZXing ScannerView 也不会停止扫描
【发布时间】:2022-02-21 15:57:51
【问题描述】:

我正在制作一个在 ContentPage 中有一个 ZXing ScannerView 的应用程序。 我已经设法让它在我的 ScanningViewModel 中的一个函数中读取 QR 码。 但是,当我尝试使用 ScannerView 离开页面时,它会崩溃。 在 Visual Studio 的“应用程序输出”中,我看到了“帧之间过早”错误的负载,我认为这是导致崩溃的原因。我读过将延迟设置为 5 可能会有所帮助,但我不确定如何执行此操作。这是我读到这个的地方:https://github.com/Redth/ZXing.Net.Mobile/issues/721 我还看过其他一些 * 文章,但它们并没有真正回答我的问题。 有没有办法解决这个问题?

编辑:这是我在 * 上阅读的另一篇文章:

Zxing Mobile doesn't stop analysing on iOS

XAML 页面:

<?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>

我的代码背后:

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

我的 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");
            }

        }
    }
}

【问题讨论】:

  • 你的问题只在 iOS 上吗?
  • iOS 是我唯一测试过的,因为我没有可以使用的 Android 设备。虽然从我在网上阅读的内容来看,我认为这个问题与 iOS 上的应用程序有关。
  • isScanning如何实现INotifyPropertyChanged?如果没有,这就是扫描不会停止的原因,UI 永远不会收到更改通知。
  • isScanning 只是一个布尔值,我绑定到 XAML 中 ScannerView 的 isScanning 属性。我不认为它需要实现 INotifyProperty 的东西。我的 ScanningViewModel 继承自 BaseViewModel,后者继承自 INotifyPropertyChanged。
  • My ScanningViewModel inherits from the BaseViewModel which inherits from INotifyPropertyChanged 但是属性public bool isScanning { get; set; } = true; 的方式不对。您可以在我的回答中参考我的代码。

标签: c# xamarin.forms zxing


【解决方案1】:

从文档INotifyPropertyChanged Interface,我们知道

INotifyPropertyChanged 接口用于通知客户端(通常是绑定客户端)属性值已更改。

要在绑定客户端和数据源之间的绑定中发生更改通知,您的绑定类型应该:

  • 实现INotifyPropertyChanged 接口(首选)。
  • 为绑定类型的每个属性提供一个更改事件。

不要两者都做。

在你的代码中,如果你想在改变isScanning 的值的同时更新UI,你必须实现接口INotifyPropertyChanged

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

请参考以下代码:

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

并在ScanningViewModel类的构造函数中为其分配一个初始值(true):

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

        // other code
    }

【讨论】:

  • 嗨@vlad radoi,请问您的问题是否已解决?如果没有,请在这里分享。我们可以一起解决。