Xamarin Forms, error in the Master Details - xamarin.forms

When I return to the Root Page with this method:
Page page = (Page)Activator.CreateInstance(typeof(TrasfMagaPage), session);
Navigation.InsertPageBefore(page, Navigation.NavigationStack[0]);
await Navigation.PopToRootAsync(true);
The icon of the hamburger menu disappears from the TopBar.
I use the same code with all the other pages, but only in this case it presents the problem.
How is that possible?

I have written code similar to this to prevent a white flicker that appears in Android master detail pages. When inserting a page before the root, I use the Navigation of the Detail page.
Detail.Navigation.InsertPageBefore(page, root);
await Detail.Navigation.PopToRootAsync(false);

Related

Clicking navlinks navigates page to root (http://mypage.se/)

When setting navLinks: true, fullcalendar makes anchor elements without a href property. That makes my page navigate to page root on click.
To resolve this issue tempraraly i have implemented this quick fix:
viewRender: function (view, element) {
var elements = $("[data-goto]");
elements.prop("href", "javascript:void(0)");
}
Now i cant say for certain that this issue is related this project beeing a .net mvc project with knockout or the way browsers handle anchor clicks without href.
If anyone could shed some light on this for me it would be much appritiated.
I'm using FullCalendar v3.9.0
This was due to Sammy.js not being set up correctly.
When clicking a link without a href tag sammy would redirect to root page automaticly.
Resolve by catching navigation to "/" and doing nothing.
Sammy(function () {
this.get('/', function () {
console.log("/");
});
}).run();

How to implement an onboarding page with Prism.Forms?

I am developing a Xamarin.Forms app with Prism in which I'd like to incorporate an onboarding page (more specific a top user benefits page, following the Material Design guidelines).
The app itself is structured around a NavigationPage to which I navigate with
NavigationService.NavigateAsync("/NavigationRootPage/MainPage")
in my App(). On the first start I'd like to show the onboarding page instead and I am having quite some issues getting it right.
My first approach was to navigate to MainPage with
_navigationService.NavigateAsync("/NavigationRootPage/MainPage")
from my viewmodel, when the user clicks the Get Started! button. This kind of worked by is also kind of ugly, since this absolute navigation will destroy the oboarding page immediately and not animate the transition. Furthermore at the moment the oboarding page is destroyed, the MainPage will be built, which will take a small, but noticeable, amount of time. In effect the user will notice the MainPage being built up, which does not look smooth at all.
My second approach was to navigate in a relative fashion from my viewmodel.
_navigationService.NavigateAsync("NavigationRootPage/MainPage")
This works way smoother, with the transition animation and after the animation is done, the MainPage is already ready to go. But again there is a major drawback. You can navigate back to the onbaording page, which we dont't want neither. And - to my knowledge - there is no (clean) way to remove the page from the navigation stack, too. I tried calling PageUtility.DestroyPage on my onboarding page, but this only worsened things, since it seemed to keep the page, but destroy the viewmodel, resulting in my onboarding page being shown without data when pushing the back button.
My third approach did not work at all, although it seemed promising to me. In my App() I pushed my navigation page with the main page then then my onboarding page modal
NavigationService.NavigateAsync("/NavigationRootPage/MainPage");
NavigationService.NavigateAsync("OnboardingPage", useModalNavigation: true);
and then in my viewmodel
_navigationService.GoBackAsync(useModalNavigation: true)
but this approach
showed the header of the NavigationPage although the onbaording page was supposed to be shown as a modal
refused to GoBackAsync - when calling this method, nothing happens
waiting for the first call to NavigateAsync did not change anything either.
Some other things I've tried
Implemented INavigationOptions in my viewmodel with ClearNavigationStackOnNavigation being true
Tried setting Application.MainPage after my NavigationPage was shown, but to no avail
I would have believed that this was king of a common requirement when programming an app. Is there something I've missed? Or will I have to live with one of those drawbacks?
I think you are overthinking this. If you want to show your Onborading page first then just navigate to it first.
`NavigateAsync("NavigationPage/OnboardingPage");
Or if you want to have the MainPage in the stack, then start the app with a deeplink
`NavigateAsync("NavigationPage/MainPage/OnboardingPage");
If you don't want to show the navigation header, just hide it for the onboarding page.
Don't use an absolute navigation unless you want to completely reset the navigation stack (equivalent to MainPage = new MainPage()).
I have found a solution, which is not the most beautiful one (it is actually quite ugly) but working.
In my MainPages viewmodel I implemented INavigatingAware and navigated to my OnboardingPage modally
public async void OnNavigatingTo(NavigationParameters parameters)
{
await _navigationService.NavigateAsync("LandingPage", useModalNavigation: true);
}
However, removing the moal page with
this._navigationService.GoBackAsync(useModalNavigation: true);
does not work as expected. The modal is not removed (although it should work this way from looking at the code, but I did not manage to debug with Re# generated PDBs). Hence I had to go the ugly (non-MVVM) way and create an event handler for Button.Click and remove the modal manually
private void Button_OnClicked(object sender, EventArgs e)
{
this.Navigation.PopModalAsync();
}
This will return to my MainPage smoothly with an animation and my MainPageis already up and running without being built up while already visible.
Still, I'd appreciate an answer on how to do it the Prism way.

How to navigate back from FreshMasterDetailNavigationContainer with FreshMvvm?

I use the following code to start a freshhmvvm master-detail page from a list in a navigation page. This works fine, but the user can not go back to the list page on IOS. On android it is possible using the system back-button from each detailpage.
Does this mean I have to add a 'Back' button to each detailpage to make this work on IOS?
Or are there other ways to start a masterdetail in freshmvvm?
var masterDetailNav = new FreshMasterDetailNavigationContainer();
masterDetailNav.Init("Menu");
masterDetailNav.AddPage<FirstPageModel>("First", item);
masterDetailNav.AddPage<SecondPageModel>("Second", item.id);
await CoreMethods.PushNewNavigationServiceModal(masterDetailNav);

Prism Xamarin Navigation - strange behaviour

I have a MasterDetail page which in Xaml has defined a navigation menu as a master bit and just an empty Detail.
Once user logs in I navigate to the main page using the following path
await _navigationService.NavigateAsync(PageCodes.NavigateTo_MainMenuPage + "/" + PageCodes.NavigateTo_NavigationPage + "/" + PageCodes.NavigateTo_WelcomePage);
NavigateTo_MainMenuPage is my MasterDetail Page
NavigateTo_NavigationPage an empty Navigation page
NavigateTo_WelcomePage my home page (content page)
This works perfectly, iOS shows both Navigation (master) and Welcome page (content page)
One of the options in the navigation is to go to About page (so user triggers this via MasterDetail.Master XAML)
I expected that this code
await _navigationService.NavigateAsync(PageCodes.NavigateTo_WebPage, param);
will replace the Detail bit of the MasterDetail Page but instead of that it opens it as a model page (full screen) and app loses the Hamburger menu. I even tried to add false, after param but it didn't work
This code
await _navigationService.NavigateAsync(PageCodes.NavigateTo_NavigationPage + "/" + PageCodes.NavigateTo_WebPage, param, false);
opens the page as a child of the main page (iOS shows back to welcome page) which I don't want.
I even tried this code
await _navigationService.NavigateAsync(PageCodes.NavigateTo_MainMenuPage + "/" + PageCodes.NavigateTo_NavigationPage + "/" + PageCodes.NavigateTo_WebPage, param, false);
but it shows NavigateTo_WebPage without Master page and as I can see the hamburger menu is missing
Just to clarify all this code is happening in the view of MainMenuPage (MainMenuPageViewModel)
So My question is what I'm doing wrong and how to push with Prism new content to Detail bit of MasterDetail page
thanks in advance!!!
I've managed to fix the problem. My Navigation page didn't have a ViewModel. Frankly, I thought as it's a dummy page without any logic I don't need the ViewModel.
As soon as I added the page, everything was fine

Xamarin Forms - Getting Rid of Back Button In Nav Bar

Lets say the first page in the app is the login page and then it takes me to do the main menu screen, is there a way to get rid of the back button in the main menu navigation bar, like get rid of the login page stack?
thank you
In Xamarin.Forms 1.3 and greater you can use
NavigationPage.SetHasBackButton(this, false);
In Xaml you can add:
<ContentPage ....NameSpaces etc....
NavigationPage.HasBackButton="False"
Title="MyPage">
</ContentPage>
You can avoid having the Back button if you replace the Navigation.PushAsync(page) to Navigation.PushModalAsync(page) in your login page's code. Post some code if this somehow doesn't apply
This has to do with how navigation works in the underlying OS (at least in iOS that's the case) - there is a Navigation Controller which serves for pages to transition between each other and have a trace of previous screen so the user can go back.
There are 2 ways to get rid of back button:
1) You can remove navigation bar from Xaml using Xamarin.Forms using below code
NavigationPage.SetHasNavigationBar (this, false);
Where this stands for current page / form instance.
2) Follow below mentioned steps
Navigate to login page when the app is loaded with Normal ContentPage instance of Login Page
Navigate to Main page from Login page using PushModalAsync and provide the main page instance as NavigationPage
And then from all the other pages, you can use PushAsync and it'll let you navigate to all the pages without any error.
Hope this helps!
By using CustomRenderer, you call this function in ViewWillAppear in your customized view controller
public override void ViewWillAppear (bool animated)
{
base.ViewWillAppear (animated);
this.ParentViewController.NavigationItem.SetHidesBackButton (true, false);
//remember to use ParentViewController to reference to the NavigationViewController (if your contentPage is direct under a navigation controller. I don't know why but Xamarin must have a bug with SetHidesBackButton. If you call with this.NavigationItem.SetHidesBackButton(...), it should not work.
... other implements here ...
}

Resources