如何使用MVVM模式在Xamarin表单中为ZXingScannerView添加自定义叠加层?

时间:2019-05-17 15:03:17

标签: c# xaml xamarin xamarin.forms zxing

我花了一些时间在SO的其他地方获取示例,以使Zxing Scanner视图与ViewModel一起使用。我能够触发扫描事件,但是视觉效果都消失了。我现在正在尝试在扫描仪视图周围添加自定义叠加层,以再次添加视觉效果,但是它们看上去有些疯狂。

我要寻找的外观是使整个屏幕显示摄像机视图,并在顶部显示覆盖的视觉效果。

以下课程:

ScanningView.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"
             x:Class="RMAGo.Features.Scanning.ScanningView"             
             xmlns:viewModelBase="clr-namespace:RMAGo.Framework;assembly=RMAGo" 
             viewModelBase:ViewModelLocator.AutoWireViewModel="true"
             xmlns:zxing="clr-namespace:ZXing.Net.Mobile.Forms;assembly=ZXing.Net.Mobile.Forms"
             Title="Scanning">   


            <zxing:ZXingDefaultOverlay                                
                x:Name="scannerOverlay"                                                       
                BottomText="Place the red line over the barcode you'd like to scan.">

                <zxing:ZXingScannerView
                    VerticalOptions="FillAndExpand"
                    HorizontalOptions="FillAndExpand"                     
                    IsScanning="{Binding IsScanning}" 
                    IsAnalyzing="{Binding IsAnalyzing}"
                    Result="{Binding Result, Mode=TwoWay}" 
                    ScanResultCommand="{Binding ScanCommand}" />                       

            </zxing:ZXingDefaultOverlay> 
</ContentPage>

ScanningViewModel.cs

using RMAGo.Features.Common;
using RMAGo.Features.Navigation;
using RMAGo.Features.Settings;
using RMAGo.Framework;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using ZXing;
using ZXing.Mobile;
using ZXing.Net.Mobile.Forms;

namespace RMAGo.Features.Scanning
{
    public class ScanningViewModel : ViewModelBase
    {
        private readonly IRMAApiService _rmaApiService;
        private readonly ISettingsService _settingsService;
        private readonly IDialogService _dialogService;
        private readonly INavigationService _navigationService;

        private string barcode = string.Empty;
        public string Barcode
        {
            get
            {
                return barcode;
            }
            set
            {
                barcode = value;
            }
        }       

        private bool _isAnalyzing = true;
        public bool IsAnalyzing
        {
            get { return _isAnalyzing; }
            set
            {
                if (!Equals(_isAnalyzing, value))
                {
                    _isAnalyzing = value;
                }
            }
        }        

        private bool _isScanning = true;
        public bool IsScanning
        {
            get { return _isScanning; }
            set
            {
                if (!Equals(_isScanning, value))
                {
                    _isScanning = value;
                }
            }
        }       

        public Command ScanCommand
        {
            get
            {
                return new Command(() =>

                {
                    IsAnalyzing = false;
                    IsScanning = false;

                    Device.BeginInvokeOnMainThread(async () =>
                    {
                        Barcode = Result.Text;
                        await _dialogService.ShowAlertAsync("Scanned Item", Result.Text, "Ok");
                    });

                    IsAnalyzing = true;
                    IsScanning = true;
                });               
            }
        }
        public Result Result { get; set; }        
        public ScanningViewModel(IRMAApiService rmaApiService, ISettingsService settingsService, IDialogService dialogService, INavigationService navigationService)
        {
            _rmaApiService = rmaApiService;
            _settingsService = settingsService;
            _dialogService = dialogService;
            _navigationService = navigationService;


            PropertyChanged += ScanningViewModel_PropertyChanged;
        }

        private void ScanningViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {           
        }
    }
}

结果截图

1 个答案:

答案 0 :(得分:0)

更新:我找到了解决方案。我在github上看到了这个示例文件,该文件直接将叠加层和扫描视图作为子级添加到网格中:https://github.com/Redth/ZXing.Net.Mobile/blob/master/Samples/Forms/Core/CustomScanPage.cs

一旦我看到我几乎只是遵循相同的方法,只是使用xaml。 (注意:我被卡住了一会儿是因为我列出了Overlay,然后列出了扫描仪视图。顺序很重要,因为我猜每个人都被放在另一个人的上面,所以overlay必须排在最后,才是最后一个在顶部)

ScanningView.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"
             x:Class="RMAGo.Features.Scanning.ScanningView"             
             xmlns:viewModelBase="clr-namespace:RMAGo.Framework;assembly=RMAGo" 
             viewModelBase:ViewModelLocator.AutoWireViewModel="true"
             xmlns:zxing="clr-namespace:ZXing.Net.Mobile.Forms;assembly=ZXing.Net.Mobile.Forms"
             Title="Scanning">   



    <Grid VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
        <zxing:ZXingScannerView                                      
                    IsScanning="{Binding IsScanning}" 
                    IsAnalyzing="{Binding IsAnalyzing}"
                    Result="{Binding Result, Mode=TwoWay}" 
                    ScanResultCommand="{Binding ScanCommand}" />    
         <zxing:ZXingDefaultOverlay               
                x:Name="scannerOverlay"                                                       
                BottomText="Place the red line over the barcode you'd like to scan." />            

    </Grid>   

</ContentPage>