Why ZXing.Net.Maui scanner doesn't work if the app doesn't use Shell? - c#

I'm trying to use ZXing.Net.Maui scanner in an empty .Net Maui app.
I seems like it doesn't work if the app doesn't use shell.
Here is my app class code:
The scanner works if the app is initialized using this code:
namespace MauiApp1;
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new AppShell();
}
}
However if the app is initialized using this code, it doesn't work. The camera view is just black and doesn't shod the camera feed.
namespace MauiApp1;
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new MainPage());
}
}
In both cases I'm creating the scanner by following the different steps in the documentation:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:zxing="clr-namespace:ZXing.Net.Maui.Controls;assembly=ZXing.Net.MAUI"
x:Class="MauiApp1.MainPage">
<ScrollView>
<VerticalStackLayout
Spacing="25"
Padding="30,0"
VerticalOptions="Center">
<zxing:CameraBarcodeReaderView x:Name="cameraBarcodeReaderView" />
</VerticalStackLayout>
</ScrollView>
</ContentPage>
C#
using ZXing.Net.Maui;
namespace MauiApp1;
public partial class MainPage : ContentPage
{
int count = 0;
public MainPage()
{
InitializeComponent();
cameraBarcodeReaderView.Options = new BarcodeReaderOptions
{
Formats = BarcodeFormats.OneDimensional,
AutoRotate = true,
Multiple = true
};
}
}
Does anyone know what am I doing wrong please ? My app doesn't use Shell. So I'm unable to use the scanner.

I can replicate the issue you descripted above and I notice that there is an open issue you raised about this problem: https://github.com/Redth/ZXing.Net.Maui/issues/109.
As an alternative workaround, if you don't want the app use shell when initializing the app, you can use the code below:
namespace MauiApp1;
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new MainPage();
}
}

Related

Xamarin.Forms: App does not show elements on the page

I am currently learning to use Xamarin.Forms and C# (first week into it) and am trying to create a basic login app.
I started with a blank template. Now, when I run my app, only the basic screen pops up, but not the elements in the page. What is wrong?
App.xaml.cs
using Xamarin.Forms;
namespace XamarinApp
{
public partial class App : Application
{
public App()
{
InitializeComponent();
new LoginPage();
}
protected override void OnStart()
{
}
protected override void OnSleep()
{
}
protected override void OnResume()
{
}
}
}
LoginPage.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="XamarinApp.LoginPage">
<ContentPage.Content>
<StackLayout>
<Label
Text="Welcome"
/>
</StackLayout>
</ContentPage.Content>
</ContentPage>
LoginPage.xaml.cs
using Xamarin.Forms;
namespace XamarinApp
{
public partial class LoginPage : ContentPage
{
public LoginPage()
{
InitializeComponent();
}
}
}
TL-DR
I believe that to solve your problem you will need to change your line:
new LoginPage();
to:
MainPage = new LoginPage();
My reasoning
You need to specify what the MainPage is. This part can be seen as confusing when you first start out because the example page that is supplied is also called MainPage but one is a class/Page implementation and the other key part is a property provided by the Application class that your App class inherits from. So that the app when running knows it's starting Page.
Typically when you create a new Blank Xamarin.Forms app you will see the following code in App.xaml.cs
public App()
{
InitializeComponent();
MainPage = new MainPage();
}
I suspect that your changes to add in your LoginPage somehow ended up removing the key part: MainPage = from that line.

Implement Prism in existing Xamarin.Forms Shared Application

I would like to know of there is a valid way to implement Prism in a existing Xamarin.Forms Shared project. I'm sure others would also like to know if they can profit from what Prism has to offer without having to convert their existing project to a PCL project. All existing examples I've found show a PCL project(probably for a good reason).
To try implementing Prism in my project I installed the Prims.Unity.Forms nuget to each platform project.
I tried to inherit from PrismApplication:
public partial class App : PrismApplication
{ }
But, this does not work. The app class does not allow me to inherit from a different base class.
Adding the following lines to my android project did not help:
protected override void OnCreate(Bundle bundle)
{
LoadApplication(new App(new AndroidInitializer()));
}
public class AndroidInitializer : IPlatformInitializer
{
public void RegisterTypes(IUnityContainer container)
{ }
}
Perhaps I am missing something or trying something that structurally is not possible.
Yes, it's completely possible.
First, ensure nuget packages are installed.
For example, for Prism and Unity you need:
<package id="Prism.Core" version="6.3.0" ... />
<package id="Prism.Forms" version="6.3.0" .../>
<package id="Prism.Unity.Forms" version="6.3.0" ... />
<package id="Unity" version="4.0.1" ... />
Add missing folders(just for order)
And move your existing page to the Views folder, but remember to
adjust the namespaces or your binding just won't work.
Change application base type
Remember to change application base type in code and XAML.
using Prism.Unity;
using Xamarin.Forms;
namespace XamPrismShared
{
public partial class App : PrismApplication
{
public App (IPlatformInitializer platformInitializer):base(platformInitializer)
{
}
}
}
Set the first page and its ViewModel
Implement OnInitialized and RegisterTypes. Remember that you need to register each type you want to use with Prism as a page.
using Prism.Unity;
using Xamarin.Forms;
namespace XamPrismShared
{
public partial class App : PrismApplication
{
public App (IPlatformInitializer platformInitializer):base(platformInitializer)
{
}
protected override void OnInitialized()
{
InitializeComponent();
NavigationService.NavigateAsync("MainPage");
}
protected override void RegisterTypes()
{
Container.RegisterTypeForNavigation<NavigationPage>();
Container.RegisterTypeForNavigation<MainPage>();
}
}
}
If you have existing pages
Add ViewModelLocator.AutowireViewModel="True"to your existent views in order to allow Prism to automatically bind with their respective ViewModel.
<?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:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
prism:ViewModelLocator.AutowireViewModel="True" x:Class="x:Class="XamPrismShared.Views.MainPage"" Title="MainPage">
<Label Text="{Binding Title}"
VerticalOptions="Center"
HorizontalOptions="Center" />
</ContentPage>
Add the missing ViewModel
using Prism.Mvvm;
namespace XamPrismShared.ViewModels
{
public class MainPageViewModel : BindableBase
{
public MainPageViewModel()
{
Title = "Hi from Prism.";
}
public string Title { get; set; }
}
}
Add Platform initializers in each platform project
Add the missing platform initializers and fix Xamarin.Forms load.
For Android,
using Android.App;
using Android.Content.PM;
using Android.OS;
using Microsoft.Practices.Unity;
using Prism.Unity;
namespace XamPrismShared.Droid
{
[Activity (Label = "XamPrismShared", Icon = "#drawable/icon", Theme="#style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate (Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate (bundle);
global::Xamarin.Forms.Forms.Init (this, bundle);
LoadApplication (new XamPrismShared.App(new AndroidPlatformInitializer()));
}
}
public class AndroidPlatformInitializer : IPlatformInitializer
{
public void RegisterTypes(IUnityContainer container)
{
}
}
}
For iOS,
using Foundation;
using Microsoft.Practices.Unity;
using Prism.Unity;
using UIKit;
namespace XamPrismShared.iOS
{
[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init ();
LoadApplication (new XamPrismShared.App(new iOSPlatformInitializer()));
return base.FinishedLaunching (app, options);
}
}
public class iOSPlatformInitializer : IPlatformInitializer
{
public void RegisterTypes(IUnityContainer container)
{
}
}
}
And voilà
If you have any question or want to check, you can review the code in Github https://github.com/jesulink2514/Xamarin-Prism-shared-project

unhandled exception when using Navigation.PushAsync

Some of the pages in my application -like the FillForm page- requires registration at first. to ensure that the user can't open those pages without being registered I did the following
Made a form for registration in a page with class name Registration
Created a new class called ContentPageRequiresRegistration
public class ContentPageRequiresRegistration : ContentPage
{
private static enumUserType userType;
public ContentPageRequiresRegistration():base()
{
if(userType==enumUserType.unRegistered)
Task.Run(() => this.LoadRegitrationPage()).Wait();
}
private async void LoadRegitrationPage()
{
await Navigation.PushAsync(new Registration(false));
}
}
Extended pages that requires registration from ContentPageRequiresRegistration
public partial class FillForm:ContentPageRequiresRegistration { ... }
And in App.cs file
public App(){
MainPage = new NavigationPage(new FillForm(1));
}
FillForm xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPageRequiresRegistration xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="HuraApp.Pages.FillForm"
Title="Fill forms">
</ContentPageRequiresRegistration>
But when I run the application it gives me an unhandled exception, and after some debugging it seems to be caused by the navigation statement
await Navigation.PushAsync(new Registration(false));
Why is this problem happening, and how can I solve it?

Xamarin Cannot Implicityconvert type to xamarin.Forms.Page

I've just start new Xamarin.Forms project and I don't know what I'm doing wrong.
In my App.cs file I'm trying to set my TestPage(I've created TestPage by Add->New Item-> BlankPage) as Main Page but i'm geting this error "Severity Code Description Project File Line Suppression State
Error CS0029 Cannot implicitly convert type 'Paternity_Test.TestPage' to 'Xamarin.Forms.Page'"
My TesPage.xaml.cs
namespace Paternity_Test
{
public partial class TestPage : Xamarin.Forms.Page
{
public TestPage()
{
this.InitializeComponent();
}
}
}
And My App.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xamarin.Forms;
namespace Paternity_Test
{
public class App : Application
{
public App ()
{
MainPage = new TestPage(); //here Im geting this error
}
protected override void OnStart ()
{
// Handle when your app starts
}
protected override void OnSleep ()
{
// Handle when your app sleeps
}
protected override void OnResume ()
{
// Handle when your app resumes
}
}
}
What I'm doing wrong?
<Page x:Class="Paternity_Test.TestPage" xmlns="schemas.microsoft.com/winfx/2006/xaml/presentation"; xmlns:x="schemas.microsoft.com/winfx/2006/xaml"; xmlns:local="using:Paternity_Test" xmlns:d="schemas.microsoft.com/expression/blend/2008"; xmlns:mc="schemas.openxmlformats.org/markup-compatibility/2006"; mc:Ignorable="d">
You can not use those Microsoft XAML namespaces, they need to be Xamarin/ WinFx based:
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
FYI: You can not currently use Blend to create these XAML files
ContentView Example:
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="TableHeaderBug.MyView">
<ContentView.Content>
</ContentView.Content>
</ContentView>
ContentPage Example:
<?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="TableHeaderBug.MyPage99">
<ContentPage.Content>
</ContentPage.Content>
</ContentPage>
Xamarin.Forms XAML Basics
Part 1. Getting Started with XAML
The first XML namespace declaration means that tags defined within the XAML file with no prefix refer to classes in Xamarin.Forms, for example ContentPage. The second namespace declaration defines a prefix of x. This is used for several elements and attributes that are intrinsic to XAML itself and which (in theory) are supported by all implementations of XAML. However, these elements and attributes are slightly different depending on the year embedded in the URI. Xamarin.Forms supports the 2009 XAML specification, but not all of it.
Device.OnPlatform has been deprecated and the suggestion is to use switch(Device.RuntimePlatform)
Below is an example using the switch:
switch(Device.RuntimePlatform)
{
case Device.iOS:
Padding = new Thickness(0, 20, 0, 0);
break;
case Device.Android:
Padding = new Thickness(10, 20, 0, 0);
break;
case Device.WinPhone:
Padding = new Thickness(30, 20, 0, 0);
break;
}

MonoTouch.Foundation.MonoTouchException has been thrown Objective-C exception thrown. Name: NSInternalInconsistencyException

I seem to be getting this issue whenever I run my iOS app within Xamarin.
MonoTouch.Foundation.MonoTouchException has been thrown
Objective-C exception thrown. Name: NSInternalInconsistencyException Reason: Could not load NIB in bundle: ’NSBundle ... (loaded)' with name ‘RouteMeViewController'
I am trying to replace a GoogleMapsViewController with a RouteMeViewController using the Objective C library and Binder in an app that I was given to work on. My AppDelegate looks like this:
namespace ExampleApp.iOS
{
[Register ("AppDelegate")]
public partial class AppDelegate : UIApplicationDelegate
{
UIWindow window;
RouteMeViewController viewController;
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
window = new UIWindow (UIScreen.MainScreen.Bounds);
viewController = new RouteMeViewController ();
window.RootViewController = viewController;
window.MakeKeyAndVisible ();
return true;
}
}
RouteMeViewController
namespace ExampleApp.iOS
{
public partial class RouteMeViewController : UIViewController
{
RMMapView MapView { get; set; }
public RouteMeViewController () : base ("RouteMeViewController", null)
{
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
MapView = new RMMapView(View.Frame, new RMOpenStreetMapSource().Handle);
MapView.AutoresizingMask = UIViewAutoresizing.FlexibleDimensions;
if (UIScreen.MainScreen.Scale > 1.0)
MapView.AdjustTilesForRetinaDisplay = true;
Add (MapView);
}
}
}
Any help or direction is much appreciated, thank you!
It seems you're missing a designer file in the resources of your solution. Even if you programmatically create controls and views, you need a designer file where they need to be drawn in, even if it's just an empty designer file. For IOS, you can use XCode for that. You can create files with the .xib extension. They will be compiled on your device, and the resulting file has the extension .nib. Make sure the target of the .xib file is the correct viewController of your project, else you'll still get the error.
I hope this helps. Good luck!
It is 2023 and this problem still appease for xamarion.IOS
and working fine for xamarion.Android
I'm using the last xamarin forms version 5.0.0.2545
this answer solves my problem
I put a lot of codes after InitializeComponent();
to solve the problem just put MainPage = new MainPage(); directly after InitializeComponent(); in your App.xaml.cs
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new MainPage());
}
The problem now it will directly go to the page without reading the other codes
so to solve this move your code to another page,empty page or splash screen page and put your code in it like
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new MySplashScreenPage());
}

Categories

Resources