Is there a way to render the Zxing ScannerPage in Xaml?

I'm using the MVVM approach to make a small scanner app. I have a startPage.Xaml with one button binded to a command in the viewModel that opens my scannerPage.Xaml On the scannerPage I have just a simple footer, and want the scanner object to fill the rest of the page. However, when I add the scanner object to my stackPanel I get the following exception: "System.MissingMethodException: Default constructor not found for type ZXing.Net.Mobile.Forms.ZXingScannerPage". I'll list my xaml code below. Any help will be much appreciated. Thanks

<?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:forms="clr-namespace:ZXing.Net.Mobile.Forms;assembly=ZXing.Net.Mobile.Forms"
             xmlns:custom="using:MobiNative_Forms.Views"
             x:Class="MobiNative_Forms.Views.BarcodePage"
             BackgroundColor="Transparent">
  <ContentPage.Content>
    <Grid>
      <Grid.RowDefinitions>
        <RowDefinition Height="8.5*" />
        <RowDefinition Height="1.5*" />
      </Grid.RowDefinitions>
      <StackLayout x:Name="layout2" Grid.Row="0" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
        <forms:ZXingScannerPage></forms:ZXingScannerPage>
      </StackLayout>
      <Label Grid.Row="1" Text="MOBI" FontSize="Large" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" BackgroundColor="Blue"/>
    </Grid>
  </ContentPage.Content>
</ContentPage>

Answers

  • KellyHussKellyHuss USMember ✭✭

    The ZXingScannerPage is a page, not a view. Maybe try ZXingScannerView instead?

  • KrzysztofKazmierczakKrzysztofKazmierczak USMember ✭✭
    edited July 2017

    Hi! The thread is quite old, but just in case - this is the xaml which works:

    <?xml version="1.0" encoding="utf-8" ?>

        <Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
            <forms:ZXingScannerView IsScanning="{Binding IsScanning}" IsAnalyzing="{Binding IsAnalyzing}" Result="{Binding Result, Mode=TwoWay}" ScanResultCommand="{Binding QRScanResultCommand}"></forms:ZXingScannerView>
            <forms:ZXingDefaultOverlay TopText="Sample top text" BottomText="sample bottom text" ShowFlashButton="False" Opacity="0.9"></forms:ZXingDefaultOverlay>
        </Grid>
    

    Best regards!

  • DougMaurerDougMaurer USMember ✭✭

    @KrzysztofKazmierczak , I am using your suggestions but am confused on where to put the events for the actual scanning. I am using an mvvm model (prism) so I have a viewmodel set for this page. What would the events look like in that model to be able to receive the scan, etc.?

  • And viewmodel code just in case:

    public class QRCodeScannerViewModel
    {
        public ZXing.Result Result { get; set; }
    
        private bool isAnalyzing = true;
        public bool IsAnalyzing
        {
            get { return this.isAnalyzing; }
            set
            {
                if (!bool.Equals(this.isAnalyzing, value))
                {
                    this.isAnalyzing = value;
                    this.OnPropertyChanged(nameof(IsAnalyzing));
                }
            }
        }
    
        private bool isScanning = true;
        public bool IsScanning
        {
            get { return this.isScanning; }
            set
            {
                if (!bool.Equals(this.isScanning, value))
                {
                    this.isScanning = value;
                    this.OnPropertyChanged(nameof(IsScanning));
                }
            }
        }
    
        public Command QRScanResultCommand
        {
            get
            {
                return new Command(() =>
                {
                    IsAnalyzing = false;
                    IsScanning = false;
    
                    Device.BeginInvokeOnMainThread(async () =>
                    {
                        //do your job here - Result.Text contains QR CODE
                    });
                });
            }
        }
    }
    

    Best regards!
    Krzysztof

  • DougMaurerDougMaurer USMember ✭✭

    Awesome! I got my app working!

    But, alas, a follow-up situation. After 1 scan, the scanner window is stuck on the last image. How do I get the scanner to scan an item, update an entry on screen (for example), and then get right back to scanning?

  • LinnKristinLinnKristin NOUniversity ✭✭

    What version of ZXing are U using ?
    Some how I can get the full screen to work but not in the view- I don´t get a camera preview. It does not react to hitting flash either. Thinking maybe it is a version problem ?
    IsScanning is set to true

  • SimonFagerliSimonFagerli USMember

    @LinnKristin
    I seem to be experiencing the same issues - I get the pageView to function as I want, but the view doesn't function as I want.
    I'm using version 2.3.2 with .NET Standard 2.0.

    I'm switching view between the content with a button for showing the QR scanner and first time it "works" to an extend in the sense that I can see the QR scanner and it calls the ScanResultCommand, but does not fill in the Result even though Ive binded it to a variable in the viewmodel with mode set as twoway.
    The result does not get set at all and remains empty. Next time I "activate" the view, the camera view is simply black.
    Torch button doesnt function either.

  • hrithickhrithick Member ✭✭
    @KrzysztofKazmierczak how to bind scanner result to entry after scannin
  • KrzysztofKazmierczakKrzysztofKazmierczak USMember ✭✭

    @udaysaikumar - I cannot test it now, but did you try to bind your entry to viewmodel's Result property?

    private ZXing.Result result;
    public ZXing.Result Result
    {
    get { return this.result; }
    set
    {
    if (!string.Equals(this.result, value))
    {
    this.result = value;
    this.OnPropertyChanged(nameof(Result));
    }
    }
    }

    I will check this as soon as possible.

    Best
    Krzysztof

  • KrzysztofKazmierczakKrzysztofKazmierczak USMember ✭✭

    @udaysaikumar - simply bind your entry to Result.Text. Please check my sampe xaml:

    <?xml version="1.0" encoding="utf-8" ?>

    <ContentPage.Content>

        <Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0,0,1,1">
            <Grid.RowDefinitions>
                <RowDefinition Height="40" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <forms:ZXingScannerView Grid.Row="1" IsScanning="{Binding IsScanning}" IsAnalyzing="{Binding IsAnalyzing}" Result="{Binding Result, Mode=TwoWay}"></forms:ZXingScannerView>
            <forms:ZXingDefaultOverlay Grid.Row="1" TopText="Coma" BottomText="Dr" ShowFlashButton="False" Opacity="0.9"></forms:ZXingDefaultOverlay>
            <Entry Grid.Row="0" Text="{Binding Result.Text}"></Entry>
        </Grid>
    
    </ContentPage.Content>
    

    And sample viewmodel:

    using System.ComponentModel;

    namespace Forum
    {
    public class QRCodeScannerViewModel : INotifyPropertyChanged
    {
    private ZXing.Result result;
    public ZXing.Result Result
    {
    get { return this.result; }
    set
    {
    if (!string.Equals(this.result, value))
    {
    this.result = value;
    this.OnPropertyChanged(nameof(Result));
    }
    }
    }

        private bool isAnalyzing = true;
        public bool IsAnalyzing
        {
            get { return this.isAnalyzing; }
            set
            {
                if (!bool.Equals(this.isAnalyzing, value))
                {
                    this.isAnalyzing = value;
                    this.OnPropertyChanged(nameof(IsAnalyzing));
                }
            }
        }
    
        private bool isScanning = true;
        public bool IsScanning
        {
            get { return this.isScanning; }
            set
            {
                if (!bool.Equals(this.isScanning, value))
                {
                    this.isScanning = value;
                    this.OnPropertyChanged(nameof(IsScanning));
                }
            }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler changed = PropertyChanged;
            if (changed != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
    

    }

    Please let me know if I can be of any more help on this!

    best regards!
    Krzysztof

  • hrithickhrithick Member ✭✭
    edited May 24

    @KrzysztofKazmierczak this is working fine... how to do this in code behind??? i am binding value from anotherpage to same entry using messaging center getting object reference not set to an instance..

Sign In or Register to comment.