i'm new with Xamarin, i tried to open the simulator iOS but i found this error:
Position 9:14. Type infra:IstanceLocator not found in xmlns
clr-namespace:Convert.Infrastructure;assembly=Convert
MY PROJECT
https://snag.gy/98ygVu.jpg
App.xaml
<?xml version="1.0" encoding="utf-8"?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:infra="clr-namespace:Convert.Infrastructure;assembly=Convert"
x:Class="Convert.App">
<Application.Resources>
<!-- Application resource dictionary -->
<ResourceDictionary>
<infra:IstanceLocator x:Key="Locator"></infra:IstanceLocator>
</ResourceDictionary>
</Application.Resources>
</Application>
App.xaml.cs
using Xamarin.Forms;
using Convert.Pages;
namespace Convert
{
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new MainPage());
}
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
}
}
}
IstanceLocator.cs
using System;
using Convert.ViewModels;
namespace Convert.Infrastructure
{
public class InstanceLocator
{
public MainViewModel Main { get; set; }
public InstanceLocator()
{
}
}
}
you have a typo
<infra:IstanceLocator x:Key="Locator"></infra:IstanceLocator>
You're missing the "n" in InstanceLocator
Related
I'm making an app which has a a ZXing ScannerView in a ContentPage.
I've managed to make it read a QR code just fine in a function in my ScanningViewModel.
However, when I try to navigate away from the page with the ScannerView, it crashes.
In the 'Application Output' in Visual Studio, I'm seeing a load of the 'Too soon between frames' error, which is I believe is causing the crashing. I've read that setting delays to 5 might help, but I'm not sure how to do this. This is where I read this: https://github.com/Redth/ZXing.Net.Mobile/issues/721
I've also seen some other StackOverflow articles, but they didn't really answer my question.
Is there a way to fix this?
Edit: This is the other post I read on StackOverflow:
Zxing Mobile doesn't stop analysing on iOS
XAML Page:
<?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>
My Code Behind:
namespace MobileApp
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class QRScanningPage : ContentPage
{
public QRScanningPage()
{
InitializeComponent();
}
}
}
My 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");
}
}
}
}
From document INotifyPropertyChanged Interface,we know that
The INotifyPropertyChanged interface is used to notify clients, typically binding clients, that a property value has changed.
For change notification to occur in a binding between a bound client and a data source, your bound type should either:
Implement the INotifyPropertyChanged interface (preferred).
Provide a change event for each property of the bound type.
Do not do both.
In your code, if you want to update the UI while changing the value of isScanning , you have to inplement interface INotifyPropertyChanged .
public bool isScanning { get; set; } = true;
Please refer to the following code:
private bool _isScanning;
public bool isScanning
{
get
{
return _isScanning;
}
set
{
SetProperty(ref _isScanning, value);
}
}
And assign an initial value (true) for it in the constructor of class ScanningViewModel:
public ScanningViewModel()
{
//assign an initial value (`true`)
isScanning = true;
// other code
}
So I tried implementing AdMob to my project but my ad is not showing up and I have no idea why.
I was following a guide online which I can't seem to find at this point but when they did it, it worked just fine, and I followed all the steps, I am starting to consider that it might be Xamarin but I am not sure.
I have a AdMobRenderer.cs that looks like this
using Google.MobileAds;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
namespace AdMobTestProject.iOS
{
public class AdMobRenderer : ViewRenderer
{
//hiding the key for this question
private const string adMobId = "ca-app-pub-xxxxxx/xxxxxxx";
private BannerView adView;
private bool viewOnScreen;
protected override void OnElementChanged(ElementChangedEventArgs<View> e)
{
base.OnElementChanged(e);
if (e.NewElement == null)
return;
if (e.OldElement == null)
{
adView = new BannerView(AdSizeCons.SmartBannerPortrait)
{
AdUnitID = adMobId,
RootViewController = UIApplication.SharedApplication.Windows[0].RootViewController
};
adView.AdReceived += (sender, args) =>
{
if (!viewOnScreen)
{
this.AddSubview(adView);
}
viewOnScreen = true;
};
Request request = Request.GetDefaultRequest();
adView.LoadRequest(request);
base.SetNativeControl(adView);
}
}
public AdMobRenderer()
{
}
}
}
And then the XAML aswell
<?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:local="clr-namespace:AdMobTestProject"
x:Class="AdMobTestProject.MainPage">
<StackLayout>
<!-- Place new controls here -->
<Label Text="Welcome to Xamarin.Forms!"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
<local:AdMobView WidthRequest="320" HeightRequest="50"></local:AdMobView>
</StackLayout>
</ContentPage>
And ofcourse the MainPage.xaml.cs
namespace AdMobTestProject
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
}
public class AdMobView : ContentView
{
public AdMobView()
{
}
}
}
Am I missing something? Why is it not displaying anything when I deploy the app to my device? iPhone 7.
I am using Xamarin.Forms
Check the space available for the adview should not be less than 360 pixel wide so check the main layout of the page if there margins remove them.
as a clue check the build output window in visual studio it will show if the ads are loaded or not and show a reason for why ads are not visible if they are loaded.
in your sample remove the WidthRequest.
this is a late reply for future searches.
Try change adMobId to a test ad id.
https://developers.google.com/admob/android/test-ads
(ca-app-pub-3940256099942544/6300978111)
I had the same issue, and if I navigated to another page and went back my ads showed up.
https://www.linkedin.com/pulse/xamarin-forms-contentpage-searchbar-navigation-bar-vipin-mathews/
I tried to implement the above code but not succeed, Search Icon not coming in page,
After that I tried this Adding a Search Bar in the toolbar of a navigationpage in Prism
, and its appears but once I changes the orientation or I logout or clicked on other page and come back again at this page its gone
I downloaded the code from git but not able to run that also.
<?xml version="1.0" encoding="utf-8" ?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="#+id/action_search"
android:title="Search"
android:icon="#android:drawable/ic_menu_search"
app:showAsAction="always|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView"/>
</menu>
But ic_menu_search file not there in drawable folder, Is that an issue?
Just use the TitleView something like:
<NavigationPage.TitleView>
<StackLayout HorizontalOptions="FillAndExpand" Orientation="Horizontal">
<Label
HorizontalOptions="FillAndExpand"
Text="{StaticResource PageTitle}"
TextColor="White"
VerticalOptions="Center" />
<SearchBar
HorizontalOptions="End"
Placeholder="Search"
PlaceholderColor="{StaticResource GrayPlaceHolderColor}"
TextColor="White"
VerticalOptions="Center" />
</StackLayout>
</NavigationPage.TitleView>
We can create a custom renderer in both the Xamarin.iOS and Xamarin.Android to accomplish it.
Here's a sample application for reference:
https://github.com/brminnick/GitTrends
And here's a blog post that shows how to add a search bar to a Xamarin.Forms app for both Xamarin.iOS & Xamarin.Android: https://www.codetraveler.io/2019/08/10/adding-a-search-bar-to-xamarin-forms-navigationpage/
App.cs
Use a Xamarin.Forms Platform-Specific to use LargeTitles on the Xamarin.iOS app.
using Xamarin.Forms.PlatformConfiguration;
using Xamarin.Forms.PlatformConfiguration.iOSSpecific;
public class App : Xamarin.Forms.Application
{
public App()
{
var navigationPage = new Xamarin.Forms.NavigationPage(new MyContentPage());
navigationPage.On<iOS>().SetPrefersLargeTitles(true);
MainPage = navigationPage;
}
}
ISearchPage Interface
Create an Interface that can be used across the Xamarin.Forms, Xamarin.Android and Xamarin.iOS projects.
public interface ISearchPage
{
void OnSearchBarTextChanged(in string text);
event EventHandler<string> SearchBarTextChanged;
}
Xamarin.Forms Page
public class MyContentPage : ContentPage, ISearchPage
{
public MyContentPage()
{
SearchBarTextChanged += HandleSearchBarTextChanged
}
public event EventHandler<string> SearchBarTextChanged;
public void OnSearchBarTextChanged(in string text) => SearchBarTextChanged?.Invoke(this, text);
void HandleSearchBarTextChanged(object sender, string searchBarText)
{
//Logic to handle updated search bar text
}
}
iOS Custom Renderer
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UIKit;
using MyNamespace;
using MyNamespace.iOS;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(MyContentPage), typeof(SearchPageRenderer))]
namespace MyNamespace.iOS
{
public class SearchPageRenderer : PageRenderer, IUISearchResultsUpdating
{
bool _isFirstAppearing = true;
public override void WillMoveToParentViewController(UIViewController parent)
{
base.WillMoveToParentViewController(parent);
var searchController = new UISearchController(searchResultsController: null)
{
SearchResultsUpdater = this,
DimsBackgroundDuringPresentation = false,
HidesNavigationBarDuringPresentation = false,
HidesBottomBarWhenPushed = true
};
searchController.SearchBar.Placeholder = string.Empty;
parent.NavigationItem.SearchController = searchController;
DefinesPresentationContext = true;
}
public override void ViewDidAppear(bool animated)
{
base.ViewDidAppear(animated);
//Work-around to ensure the SearchController appears when the page first appears https://stackoverflow.com/a/46313164/5953643
if (_isFirstAppearing)
{
ParentViewController.NavigationItem.SearchController.Active = true;
ParentViewController.NavigationItem.SearchController.Active = false;
_isFirstAppearing = false;
}
}
public void UpdateSearchResultsForSearchController(UISearchController searchController)
{
if (Element is ISearchPage searchPage)
searchPage.OnSearchBarTextChanged(searchController.SearchBar.Text);
}
}
}
Xamarin.Android Menu XML
In the Xamarin.Android project, in the Resources folder, create a new folder called menu (if one doesn't already exist).
Note: the folder, menu, has a lowercase 'm'
In the Resources > menu folder, create a new file called MainMenu.xml.
Open Resources > menu > MainMenu.xml
In MainMenu.xml add the following code:
<?xml version="1.0" encoding="utf-8" ?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="#+id/ActionSearch"
android:title="Filter"
android:icon="#android:drawable/ic_menu_search"
app:showAsAction="always|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView"/>
</menu>
Xamarin.Android CustomRenderer
Uses the Plugin.CurrentActivity NuGet Package.
using Android.Content;
using Android.Runtime;
using Android.Support.V7.Widget;
using Android.Text;
using Android.Views.InputMethods;
using Plugin.CurrentActivity;
using MyNamespace;
using MyNamespace.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(MyContentPage), typeof(SearchPageRenderer))]
namespace MyNamespace.Droid
{
public class SearchPageRenderer : PageRenderer
{
public SearchPageRenderer(Context context) : base(context)
{
}
protected override void OnAttachedToWindow()
{
base.OnAttachedToWindow();
if (Application.Current.MainPage is NavigationPage navigationPage)
navigationPage.Popped += HandleNavigationPagePopped;
if (Element is ISearchPage && Element is Page page && page.Parent is NavigationPage navigationPage && navigationPage.CurrentPage is ISearchPage)
AddSearchToToolbar(page);
}
protected override void Dispose(bool disposing)
{
if (GetToolbar() is Toolbar toolBar)
toolBar.Menu?.RemoveItem(Resource.Menu.MainMenu);
base.Dispose(disposing);
}
void AddSearchToToolbar(in Page page)
{
if (GetToolbar() is Toolbar toolBar
&& toolBar.Menu?.FindItem(Resource.Id.ActionSearch)?.ActionView?.JavaCast<SearchView>().GetType() != typeof(SearchView))
{
toolBar.Title = page.Title;
toolBar.InflateMenu(Resource.Menu.MainMenu);
if (toolBar.Menu?.FindItem(Resource.Id.ActionSearch)?.ActionView?.JavaCast<SearchView>() is SearchView searchView)
{
searchView.QueryTextChange += HandleQueryTextChange;
searchView.ImeOptions = (int)ImeAction.Search;
searchView.InputType = (int)InputTypes.TextVariationFilter;
searchView.MaxWidth = int.MaxValue; //Set to full width - http://stackoverflow.com/questions/31456102/searchview-doesnt-expand-full-width
}
}
}
void HandleQueryTextChange(object sender, SearchView.QueryTextChangeEventArgs e)
{
if (Element is ISearchPage searchPage)
searchPage.OnSearchBarTextChanged(e.NewText);
}
void HandleNavigationPagePopped(object sender, NavigationEventArgs e)
{
if (sender is NavigationPage navigationPage
&& navigationPage.CurrentPage is ISearchPage)
{
AddSearchToToolbar(navigationPage.CurrentPage);
}
}
Toolbar GetToolbar() => CrossCurrentActivity.Current.Activity.FindViewById<Toolbar>(Resource.Id.toolbar);
}
}
Sample App
Here's a sample app for reference:
https://github.com/brminnick/GitTrends
And a blog post that shows how to add a search bar for both Xamarin.iOS and Xamarin.Android: https://www.codetraveler.io/2019/08/10/adding-a-search-bar-to-xamarin-forms-navigationpage/
how would I use Dependency Injection to use the Flyoutnavigation for my iOS project.
I have decided to stick with the default MasterDetailPage for Android as it doesn't look as bad as iOS.
This is what I have done so far:
In PCL
IMainPage.cs:
public interface IMainPage
{
Page GetMainPage();
}
App.cs:
public partial class App : Application
{
public App()
{
MainPage = DependencyService.Get<IMainPage>().GetMainPage();
}
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
}
}
In Android
MainPage_Android.cs:
[assembly: Xamarin.Forms.Dependency(typeof(MainPage_Android))]
namespace ProjectName.Droid
{
public class MainPage_Android : MasterDetailPage, IMainPage
{
private NavigationPage detail;
private MasterPage master;
public Page GetMainPage()
{
MasterDetailPage mdp = new MasterDetailPage();
//Master
master = new MasterPage();
MasterBehavior = MasterBehavior.Popover;
mdp.Master = master;
//Detail
detail = new NavigationPage(new Home())
{
BarBackgroundColor = Color.FromHex("#01A0E1"),
BarTextColor = Color.White
};
mdp.Detail = detail;
return mdp;
}
}
}
In iOS
I am stuck here.. How do I return a page using the Flyoutnavigation?
If you want to use default style on Android and custom style on iOS, you can try to make a custom renderer for MasterDetailPage on iOS. Then embed your Flyoutnavigation.
This is my iPad renderer:
[assembly: ExportRenderer(typeof(MainPage), typeof(MainPageRenderer))]
namespace FlyoutNavigationDemo.iOS
{
public class MainPageRenderer : TabletMasterDetailRenderer
{
//put your Flyoutnavigation's code here
}
}
Since Flyoutnavigation has too much code. I make a small sample for you, you can refer to here for more details.
Good afternoon everyone. I have just begun to work with Xamarin Forms as I will need it for my job and wanted to learn best practices from the beginning so I went for Mvvm Light. My current problem is that, whatever I do, I really can't make binding work (NOTE: it worked for my first project, a simple page where I had a button which was used to navigate to another page). Now, for my current project, an EventApp I tried everything I could, looking on lots of forums and tried various settings and implementations but couldn't make the binding work again. I will show you some of my current code for a test page I've done just for testing purposes.
App.cs class:
public partial class App : Application
{
private static ViewModelLocator _locator;
public static ViewModelLocator Locator { get { return _locator ?? (_locator = new ViewModelLocator()); } }
public App()
{
InitializeComponent() //Tried both with and without this
registerNavigationService();
}
protected override void OnStart()
{
}
protected override void OnSleep()
{
// Handle when your app sleeps
}
protected override void OnResume()
{
// Handle when your app resumes
}
public void registerNavigationService()
{
NavigationService nav = new NavigationService();
nav.Configure(PageNames.GeneralNotificationPage, typeof(GeneralNotificationPage));
nav.Configure(PageNames.CreateNotificationPage, typeof(CreateNotificationPage));
nav.Configure(PageNames.SelectSongPage,typeof(SelectSongPage));
SimpleIoc.Default.Register<INavigationService>(() => nav);
var firstPage = new NavigationPage(new SelectSongPage());
nav.Initialize(firstPage);
MainPage = firstPage;
}
}
`
App.xaml:
<?xml version="1.0" encoding="utf-8"?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="EventAppMvvm.App"
>
</Application>
-Note: here I tried to set a static resource for my ViewModelLocator the next way:
xlmns:vm="clr-namespace:EventAppMvvm.ViewModel;assembly=EventAppMvvm"
and then in resources
<vm:ViewModelLocator x:Key="Locator"/>
doesn't work, if I try in one of my pages to set the DataContext, it says it hasn't found any bindable property. If I set the BindingContext to that I get an NPE when I run the app as there is no object created. So I ended up using the code behind to do the BindingContext and instantiate the locator in my App.cs file so I won't receive an NPE.
ViewModelLocator:
public class ViewModelLocator
{
/// <summary>
/// Initializes a new instance of the ViewModelLocator class.
/// </summary>
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
////if (ViewModelBase.IsInDesignModeStatic)
////{
//// // Create design time view services and models
//// SimpleIoc.Default.Register<IDataService, DesignDataService>();
////}
////else
////{
//// // Create run time view services and models
//// SimpleIoc.Default.Register<IDataService, DataService>();
////}
SimpleIoc.Default.Register<CreateNotificationPageViewModel>();
SimpleIoc.Default.Register<SelectSongPageViewModel>();
SimpleIoc.Default.Register<GeneralNotificationPageViewModel>();
}
public CreateNotificationPageViewModel CreateNotificationPageVM
{
get
{
return ServiceLocator.Current.GetInstance<CreateNotificationPageViewModel>();
}
}
public SelectSongPageViewModel SelectSongPageVM
{
get
{
return ServiceLocator.Current.GetInstance<SelectSongPageViewModel>();
}
}
public GeneralNotificationPageViewModel GeneralNotificationPageVM
{
get
{
return ServiceLocator.Current.GetInstance<GeneralNotificationPageViewModel>();
}
}
public static void Cleanup()
{
// TODO Clear the ViewModels
}
}
One of my ViewModels(test one):
public class SelectSongPageViewModel : ViewModelBase
{
RelayCommand _commandTest;
Song _selectedSong;
INavigationService navigation;
string clicked = "3";
string _message = "I ve not been clicked yet";
public SelectSongPageViewModel(INavigationService navigation)
{
this.navigation = navigation;
}
RelayCommand CommandTest
{
get
{
if(_commandTest == null)
{
_commandTest= new RelayCommand(() =>
{
Message = _message;
//navigation.NavigateTo(PageNames.CreateEventPage);
});
}
return _commandTest;
}
}
public string Message
{
get
{
return clicked;
}
set
{
clicked = value;
RaisePropertyChanged("Message");
}
}
}
Actual page of that ViewModel:
Notes: if I try to use DataContext (defined as static resource previously in App.xaml), no matter if I give the correct namespace and assembly, it says that it hasn't found any binding, property there, if I use BindingContext, it works, I don't get any errors at compile time but I can't make the buttons do something as it is like it doesn't recognize my defined commands but for some reason it just binds simple data like my Message property.
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="EventAppMvvm.Views.SelectSongPage"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
>
<ContentPage.Content>
<StackLayout>
<Label Text="{Binding Message}"></Label>
<Button Text="Press me" Command="{Binding CommandTest}"></Button>
</StackLayout>
</ContentPage.Content>
</ContentPage>
And the code behind for this page.
namespace EventAppMvvm.Views
{
public partial class SelectSongPage : ContentPage
{
public SelectSongPage()
{
InitializeComponent();
var vm = App.Locator.SelectSongPageVM;
BindingContext = vm;
}
}
}
Whatever I do, I can't make the commands/Complex binding work again for some reason but still simple property binding works, I'm using VisualStudio for Mac if it matters.