Xamarin.Forms How to switch pages using MVVMLight - xamarin

I'm currently working on a Xamarin.forms project using .NET Standard as code sharing strategy. I try to use the MVVM pattern by using the MvvmLightLibsStd10 library. I already successfully setup the MVVM structure by using this tutorial:
https://www.linkedin.com/pulse/build-xamarinforms-net-standard-mvvm-light-app-rafael-carvalho
I can't use Navigation.PushAsync(new Page()); because it only works in code behind and not in the ViewModel.
I already tried to Pass Navigation trough the VM constructor, like describe over here:
Xamarin.form Page Navigation in mvvm
But when I try this method, an error occurred at "LoadApplication(new DemoMVVM2.App());" in MainPage.
How can I switch pages using MVVM Xamarin.Forms with MVVMLight (based on the code from my first url)?
but I have no Idea how I can switch Pages via the ViewModel and keeping the header with back button.

Generally when working with MVVMLight you'll be using a NavigationService.
This class can be constructor injected in your VM, thanks to the build in IOC in MVVMLight.
With it you can do Navigate and GoBack in your VM, triggering a real navigation on the current stack.
Only thing that you maybe missed, is the fact that you need to write one yourself for Xamarin forms.
But Laurent Bugnion ( the owner of MVVMLight ) supplied an example available here:
https://github.com/lbugnion/sample-2016-vslive-crossplatform/blob/master/Flowers/Flowers.Forms/Flowers.Forms/Helpers/NavigationService.cs

You can pass a callback to your ViewModel(VM) and on Command or whatever action call your navigation code which is in your page (View). this way you can keep your navigation code in your page and your binding logic in your ViewModel.
interface NavHandler{
void navigateToSomeView();
}
public class MyPage : ContentPage,NavHandler{
public MyPage(){
BindingContext = new MyViewModel(this);
}
void navigateToSomeView(){
Navigation.PushAsync(new Page2());
}
}
public class MyViewModel{
NavHandler handler;
public MyViewModel(NavHandler handler){
this.handler = handler
}
//Your action
this.btnClicked = new Command(async()=>{
handler.navigateToSomeView()
}
}

Related

How to import Activity of NfcFCardEmulation.EnableService from Xamarin common project, not Android project?

I'm developing an app using Xamarin's HCE feature.
The project structure is as follows.
hceSample
hceSample.Android
hceSample.iOS
I am implementing hce simulation code called hceService in hceSample, not hceSample.Android.
A function called Enable_Card exists in the hce service, and you want to use the NfcFCardEmulation.EnableService function in that function.
Activity and ComponentName are requested as parameters of the function.
The ComponentName area was handled easily, but I don't know how to get the Activity. Please advise.
This is the contents of enable_Card function of hceService.
private Activity activity = null;
private bool enable_Card(cardModel card)
{
try
{
sid = card.cardSN;
tag = "Felica";
emulation.EnableService(, componentName); //<- How to get Activity??
emulation.SetNfcid2ForService(componentName, sid);
return true;
}
catch
{
return false;
}
}
This is my first time asking a question on Stackoverflow.
I would appreciate it if you could point out any missing or incorrect parts.
I trying this
activity = Xamarin.Essentials.Platform.CurrentActivity; //<- this function is not found!
Added missing information!
The namespace of the Enable_Card function is located in hceSample.Service.
Are you using the NfcFCardEmulation.EnableService(Activity, ComponentName) Method, right?
The method is an android api from android sdk,you cannot use it directly in xamarin.form(yours is hceSample) project.
If you want to call the function in xamarin form project(hceSample) from native platform(hceSample.Android, or hceSample.iOS),you can use Xamarin.Forms DependencyService to achieve this.
The DependencyService class is a service locator that enables Xamarin.Forms applications to invoke native platform functionality from shared code.
For more information about DependencyService, you can check document Xamarin.Forms DependencyService. And there is a sample included in above document,which is helpful for you to understand DependencyService.
Note:
We recognize that hardware service is the right and ideal way to
implement in each OS project. However, I'm curious if there is a way
to code Android and iOS at the same time
Since the api you used is from android sdk, you can call it in native android or use DependencyService to call it on xamarin.form(yours is hceSample) project.
If you call it on xamarin.form(yours is hceSample) project, you also need to find the the corresponding function or interface in iOS.

How can I implement SfMap in Xamarin

How can I implement SfMaps in my project which is based on MVVM structure? 1st I have to get my current location and show it on the map then I have to drag that marker point anywhere and set it as the current location
Add SfMaps to your project from NuGet. In android no need for native configurations, but to launch the SfMaps in iOS, call the SfMapsRenderer.Init() in the FinishedLaunching overridden method of the AppDelegate class
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
…
global::Xamarin.Forms.Forms.Init ();
Syncfusion.SfMaps.XForms.iOS.SfMapsRenderer.Init();
LoadApplication (new App ());
…
}
Add the following namespace in your view file.
xmlns:maps="clr-namespace:Syncfusion.SfMaps.XForms;assembly=Syncfusion.SfMaps.XForms"
And add the below code to initializing map in view
<maps:SfMaps >
</maps:SfMaps>
this is a very basic way to add SFMap in Xamarin. forms for more details and help
please visit this link: https://help.syncfusion.com/xamarin/maps/getting-started?cs-save-lang=1&cs-lang=xaml

MVVMCross View Model Prepare method not called when Hot Reload (ing) XAML changes

I started using MVVMCross several weeks ago and so far I love it, but I've noticed that whenever I'm working on the UI and making changes in the XAML and pressing save which activates the Hot Reload in Visual Studio 2019, I'm getting Null Reference Exceptions.
This is down to the fact that the MVVMCross' Prepare method is not getting called. According to their doc's this method is used to pass a parameter to the VM which can then be used throughout the VM.
public override void Prepare(MyClass param)
{
MyClass = param;
}
public override Task Initialize()
{
MyClass.DoSomething();
return base.Initialize();
}
So this is the basic usage (I think). However when I Hot Reload the XAML changes Prepare isn't called but Initialize is, which causes the Exception.
Is this a bug ?
Prepare in normal cases will only be called when calling NavigationService.Navigate.
What Hot Reload actually does is unclear. This use case is currently not officially supported by MvvmCross.

Load startup model in platform project code and pass it to PCL on Xamarin Forms Initialization

The application I'm currently working on requires data to be retrieved from a web service during app startup that roughly takes 1.5 seconds. After the data is retrieved, it needs to be displayed on the MainPage and that is another 1.5 - 2 seconds since the data is mostly URLs of images that have to be displayed, in my case, using ffimageloading library; which means actually downloading those images first to be displayed.
I have splash startup screens for both Android and iOS implemented separately in platform projects but splash screen only stays up for the amount of time Xamarin Forms needs to load and afterwards disappears not waiting for my actual model to load from the web service. I have searched for solutions to extend the splash screen duration and mostly every solution I have read involves creating another splash screen page, loading page if you will, that is already controlled in PCL project but having two separate splash loading screens just seams not feasible to me at the moment.
So I was wondering, how would one load the initial model in platform projects, during the actual splash screen, and then later pass it to PCL project when Xamarin Forms has finished initialization, presumably to App.xaml.cs 's App() constructor function?
There is no code or enough details so I am assuming this is what you want to do.
Call the APIs asynchrnously , till then show splash screen.
Before assigning MainPage in your App.xaml.cs you should call these APIs asynchronously with await and then you use the same for binding of your mainpage
public App()
{
InitializeComponent();
//do all my prefetch stuff for app initialization.
// API and what not
var viewmodel = new AppMainViewModel();
await viewmodel.CallFooFetchAsync();
await viewmodel.BlahBlahAsync();
MainPage = new NavigationPage(new AppMainPage(viewmodel));
}
In Page
public AppMainPage(AppMainViewModel vm)
{
BindingContext =vm;
}
So by the time page loads it has all the data handy.
You can explore adding this code in OnAppearing of the page.
Note that the concept of default Splash screen is just to show an image(with different theme in Android) and setting image in iOS. You need to have conventional UI technically its not splash screen anymore.
Alternatively you can get shared project handle in native
Android Sp
protected override void OnCreate(Bundle bundle)
{
...
var app = new App(); //this will be shared project App object
Device.BeginInvokeOnMainThread(async () => await app.DoPrefetchStuffFirst()); //API calls if needed in this async method
//then
LoadApplicationm(app)
}
You can do similar thing in iOS AppDelegate
And if you call native specific methods in platforms (may be for API calls) then you would use DependencyService feature , that will pass it to shared project or Custom renderer based on where you want to use it.

Custom BasePage causing design view to break

I was getting fed up with typing this.NavigationService.Navigate(new Uri(page.xaml, UriKind.Relative));, every time I need to navigate to a different page in my app.
So I've created a custom BasePage with a virtual to help with Navigating around my app.
The problem I have is in VS2010, if I have the source and design view open, the design just shows the windows phone background and I get some blue wiggly lines right from the top to the bottom of my xaml and messages along the lines of x isn't supported. This happens on any page that I have set up to Inherit from my custom BasePage.
However, if I run the application on my Windows Phone or in the Emmulator it will work.
Does anyone have any suggestions of what I could try to keep my Design view working whilst apply my custom base, or if I have missed something off?
A slightly cut down version of my BasePage is:
public class BasePage : PhoneApplicationPage
{
public virtual void NavigateTo(string pageName, params Tuple<string,string>[] queryString)
{
// Code to perform this.NavigationService.Navigate
}
}
EDIT 2011-08-16
Part of this base page overrides the PhoneApplicationPage's OnNavigatedTo method, in which I perform a security check to see if:
security has been enabled
User is logged in
If the security is enabled but the user is not logged in, they are immediately redirected to a Login Page.
I found this useful as I don't then have to add any code to existing or new pages to handle this, so long as they derive from the BasePage.
I wouldn't recommend using a BasePage for this. Instead, simply add your NavigateTo method in the App.xaml.cs file, as a static method.
public static void NavigateTo(string pageName, params Tuple<string,string>[] queryString)
{
// Code to perform this.NavigationService.Navigate
}
Also, remember to wrap the call to .Navigate in Dispatcher.BeginInvoke so all transition effects are properly executed.
And as a bonus tip: Don't use the designer in Visual Studio. Instead, set the 'default editor' for XAML files to be the "Source Code" editor, so the designer is never opened. This makes Visual Studio much more stable.
If you want a designer, you should get Microsoft Expression (Blend)

Resources