简体   繁体   English

Xamarin形成ZXing QR码错误

[英]Xamarin Forms ZXing QR Code Error

I am using Xamarin forms to make a QR code reader app. 我正在使用Xamarin表单制作QR码阅读器应用程序。 I have found an implementation by ZXing but I am getting an error when running my code due to using the await keyword outside of an async function. 我已经找到了ZXing的实现,但是由于在async函数之外使用await关键字,因此在运行代码时出现错误。 The tutorial does it this way however, but I don't know what I am doing wrong to throw the error. 本教程以这种方式执行此操作,但是我不知道自己在做错什么以抛出错误。

using Xamarin.Forms;
using ZXing.Net.Mobile.Forms;

namespace App3
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();

            var scanPage = new ZXingScannerPage();
            scanPage.OnScanResult += (result) => {
                // Stop scanning
                scanPage.IsScanning = false;

                // Pop the page and show the result
                Device.BeginInvokeOnMainThread(() => {
                    Navigation.PopAsync();
                    DisplayAlert("Scanned Barcode", result.Text, "OK");
                });
            };

            // Navigate to our scanner page
             await Navigation.PushAsync(scanPage); // Here is the error
        }
    }  
}

The error is: 错误是:

The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'

It is because constructor cant be asynchronous. 这是因为构造函数不能异步。 Just move your code to void method like: 只需将代码移动到void方法,如:

private async void InitializeScanner()
{
   var scanPage = new ZXingScannerPage();
        scanPage.OnScanResult += (result) => {
            // Stop scanning
            scanPage.IsScanning = false;

            // Pop the page and show the result
            Device.BeginInvokeOnMainThread(() => {
                Navigation.PopAsync();
                DisplayAlert("Scanned Barcode", result.Text, "OK");
            });
        };

        // Navigate to our scanner page
         await pushAsyncPage(scanPage); 
}

public MainPage()
{
   InitializeComponent();
   InitializeScanner();
}

Another option maybe better (with some adjustments eg opening scanner page on button cllick) is create scan page in OnAppearing method, but be careful when scan is completed Navigation.PopAsync() is called and OnAppearing on your MainPage is called. 另一个更好的选择(进行一些调整,例如,在按钮cllick上打开扫描仪页面)可能是OnAppearing方法中的创建扫描页面,但是在扫描完成时要小心, Navigation.PopAsync()被调用,并且MainPage上的OnAppearing被调用。 So in that case new scan page will be pushed up. 因此,在这种情况下,将向上推新的扫描页面。

This message is because you need to include the async keyword to the outer method that is running your method. 该消息是因为您需要在运行您的方法的外部方法中包括async关键字。 The problem you have is that you are trying to run it at the Page constructor and these cannot be async. 您遇到的问题是您试图在Page构造函数上运行它,并且它们不能是异步的。

You can get rid of the error messages moving either the pushAsyncPage method call out of the constructor to another method in the Page like the OnAppearing and change the signature of this adding async, something like: 您可以摆脱错误消息,将pushAsyncPage方法调用从构造函数中移出到页面中的另一个方法(例如OnAppearing并更改此添加异步的签名,例如:

    protected override async void OnAppearing ()
    {
        base.OnAppearing ();

        if(isPageLoaded)
            return;

        isPageLoaded = true;
        await pushAsyncPage(scanPage);
    }

Or moving the whole block of code to the same method: 或将整个代码块移至相同的方法:

    protected override async void OnAppearing ()
    {
        base.OnAppearing ();

        if(isPageLoaded)
            return;

        isPageLoaded = true;

        var scanPage = new ZXingScannerPage();
        scanPage.OnScanResult += (result) => {
            // Stop scanning
            scanPage.IsScanning = false;

            // Pop the page and show the result
            Device.BeginInvokeOnMainThread(() => {
                Navigation.PopAsync();
                DisplayAlert("Scanned Barcode", result.Text, "OK");
            });
        };

        // Navigate to our scanner page
         await pushAsyncPage(scanPage); // Here is the error            
    }

This should be enough. 这应该足够了。

UPDATE UPDATE

As commented below, using this code will require having a variable to know if the page is already loaded to prevent the ZXing page showing again when returning from the scanner. 如下所述,使用此代码将需要有一个变量来知道页面是否已加载,以防止ZXing页面从扫描仪返回时再次显示。

This is the reason I do prefer opening the scanning page on an user iteration (tap of a button, swipe or any other gesture) to prevent loops like this. 这就是为什么我更喜欢在用户迭代(轻按按钮,滑动或任何其他手势)上打开扫描页面以防止此类循环的原因。

Good luck. 祝好运。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM