Using Tabbed Page with Master Detail page in Xamarin Forms - xamarin.forms

I am using MasterDetail page in xamarin forms, my detail page is a tabbed page with three tabs, my problem is when I am writing below code in MasterDetail Page to remove NavigationBar from that page
protected async override void OnAppearing ()
{
base.OnAppearing ();
NavigationPage.SetHasNavigationBar (this,false);
}
Then my tab page is not working properly like all tabs got disabled.
But without using this code everything is working fine.
But I need to write this code as I don't want that navigation bar on my master detail page.

You can hide the navigation bar by creating a new NavigationPage(new YourTabbedPage) and then you can use the code to hide the NavigationBar
NavigationPage.SetHasNavigationBar (this,false);
You can have different NavigationPage MainPage of your App.cs you can have an instance of your App.cs like this:
public static App Instance { get; private set; }
So now you can set:
App.Instance.MainPage = new NavigationPage(new YoutTabbedPage());
Hope this helps.

Related

Xamarin Forms AppShell How return to previous page

I see a lot of threads on this sort of subject but none seem to apply to my question. I don't have a navigation page, I have a hamburger menu -- so Push/PopAsync() would not appear to be the answer. And I don't want to go to a specific page, I want to go back to the previous page (whatever it was) so GoToAsync() would not appear to be the answer.
Xamarin app for Android and UWP with iOS somewhere in the future. The description of the problem below is specific to Android; it works a little differently on UWP.
I want to put a Help entry in the hamburger menu that will take the user to a help page in the default browser. Hamburger menu seems to only go to an app page, so I defined a "dummy" View page that displays "Loading ..." and issues Browser.OpenAsync() in its OnAppearing() method, and that pretty much works. The problem is that the user would expect that the Back button would take him or her to the page they were on before clicking Help. I tried a couple of things. I have gotten close with the following but it does not quite work correctly:
In each of my other Views' OnAppearing() I call a method that saves the value of Current.MainPage.CurrentItem in a static. Then in the Help page after the OpenAsync() I set Current.MainPage.CurrentItem to its setting from the last page before the Help page.
Console.WriteLine("#### HelpPage loading Web Help");
_ = State.DisplayHelpPage(this, "MainHelp"); // _ = await Browser.OpenAsync(uri, blo);
Console.WriteLine("#### HelpPage returning to previous page");
State.ReloadPreviousPage(); // Current.MainPage).CurrentItem = lastFlyoutItem;
It almost works. The first time I click Help in the hamburger menu I get
#### HelpPage loading Web Help
#### HelpPage returning to previous page
#### HelpPage loading Web Help
#### HelpPage returning to previous page
The Web page loads perfectly. But when I click the Back button it displays again. Obviously my OnAppearing() method has been driven twice, which I do not understand.
If I click the Back button again I come back to the previous page in the application just as I wanted. The next time I click Help in the Hamburger menu it takes me to my dummy View page with no Web page. Obviously, my OnAppearing() is not being driven at all. But after that it works perfectly. I can go to any app page, and click Help in the menu. I get the Web page, and the Back button takes me back to the app and the page. In UWP of course the browser does not load on top of the app Views, and I seem to see it being loaded twice every time.
So ... what should I be doing differently? And why is my OnAppearing() being driven twice and then not at all ... and thereafter as I would expect?
There are several parts to this answer:
Get the previous page on to the Navigation stack. This is done by intercepting the Route "//HelpPage", and replacing it with a route that ISN'T a child of Shell.
Remember "FakePageVisible", so we know to do "PopAsync" in OnResume, when app returns from browser.
(Optional) "Entering" flag prevents going to browser twice.
App.xaml.cs:
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new AppShell();
}
protected override void OnResume()
{
if (HelpPage.FakePageVisible) {
HelpPage.FakePageVisible = false;
var shell = MainPage as AppShell;
if (shell != null) {
shell.Navigation.PopAsync();
}
}
}
}
AppShell.xaml.cs:
public partial class AppShell : Xamarin.Forms.Shell
{
public AppShell()
{
InitializeComponent();
// Define a route that isn't a child of Shell.
Routing.RegisterRoute("Help2", typeof(HelpPage));
}
protected override void OnNavigating(ShellNavigatingEventArgs args)
{
base.OnNavigating(args);
if (args.Current != null) {
if (args.Source == ShellNavigationSource.ShellItemChanged) {
if (args.Target.Location.OriginalString == "//HelpPage") {
// Cancel the original route.
args.Cancel();
Device.BeginInvokeOnMainThread(() => {
// Used by the next OnAppearing.
HelpPage.Entering = true;
// Go there by a route that isn't a child of Shell.
// Doing so, pushes our previous location on to Navigation stack.
Shell.Current.GoToAsync("Help2");
});
}
}
}
}
}
HelpPage.xaml.cs:
public partial class HelpPage : ContentPage
{
public static bool Entering;
public static bool FakePageVisible;
protected override void OnAppearing
{
// Make sure this only happens once (just in case).
if (Entering) {
Entering = false;
FakePageVisible = true;
Xamarin.Essentials.Browser.OpenAsync("https://aka.ms/xamarin-quickstart");
}
}
}
For a simple demo, this code communicates via static variables in HelpPage. Re-factor as appropriate for your situation.

Xamarin forms how to pass parameters from page to tabbed page

I have problem to pass parameter from page. Goal is that after login wanna show logged user info in tabbed page. Can you help me how to pass parameter from page to tabbed page.
Thank you
Solution is
Login Page
await Navigation.PushAsync(new TabbedPage1("Name"));
TabbedPage
<local:Page1 Title="Page1">
<Label x:Name="lblfirstname"/>
</local:Page1>
public partial class TabbedPage1 : TabbedPage
{
public TabbedPage1(string firstname) {
InitializeComponent();
lblfirstname.Text = firstname;
}
}
There are many solutions, but it's depend on your implementation.
The simplest is use MessagingCenter . Your tabbed page can subscribe and your page can publish all necessary parameters.

How to fix Menu for Nevigation pages in Master Detail page for all platform(android and uwp)

I have designed master detail page for my application.
Here I past screentshots of my application.
Homepage overview
I use data grid view to show my data.
Menu
but, I don't want to hide my Menu.I fix that in my application home screen for uwp app only.
So after fix that I want to show my data in datagridview for rest of the screen.
I want to unhide Menu.
Is that posiible using master detail page design.
How can I do it, Please any suggestion or code example.
advance thanks.
Customized screen what I want:-
CustomScreen
You can create a MasterDetailPageRenderer in UWP solution as follows:
[assembly: ExportRenderer(typeof(AppMasterDetailDemo.Views.MainPage), typeof(CustomMasterDetailRenderer))]
namespace AppMasterDetailDemo.UWP
{
public class CustomMasterDetailRenderer: MasterDetailPageRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<MasterDetailPage> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.CollapsedPaneWidth = 0;
Control.CollapseStyle = Xamarin.Forms.PlatformConfiguration.WindowsSpecific.CollapseStyle.Partial;
Control.MasterToolbarVisibility = Windows.UI.Xaml.Visibility.Collapsed;
Control.DetailTitleVisibility = Windows.UI.Xaml.Visibility.Collapsed;
Control.MasterTitleVisibility = Windows.UI.Xaml.Visibility.Collapsed;
Control.ContentTogglePaneButtonVisibility =
Windows.UI.Xaml.Visibility.Collapsed;
}
}
}
}
Then in Xamarin Forms, set as follows can hide the Menu button.
NavigationPage.SetHasBackButton(this, false);
NavigationPage.SetHasNavigationBar(this, false);
Or modify the false to true, can show again.
The effect:

Xamarin.Forms: How to navigate to TabbedPage's child page

I meet a scenario to navigate from MyTabbedPage/ChildTabPage1/Page1 to MyTabbedPage/ChildTabPage2/Page2 in Xamarin.Forms
Right now, I can only switch between MyTabbedPage/ChildTabPage1 and MyTabbedPage/ChildTabPage2. But I need to navigate directly from MyTabbedPage/ChildTabPage1/Page1 to MyTabbedPage/ChildTabPage2/Page2
How to achieve this?
Thank you very much in advance for your helps.
You can try something like this.
public App()
{
InitializeComponent();
var parentPage = new MasterDetailView(); // name of the master detail page
parentPage.IsPresented = false;
var tabbedPage = new MasterDetailTabbedPage(); // name of the tabbed page
tabbedPage.CurrentPage = tabbedPage.Children[2]; // specify the index of the tab
parentPage.Detail = new NavigationPage(tabbedPage); // assign the tabbed page to master detail page
MainPage = parentPage; // navigate to master detail page (3rd tab selected)
}
If you want to navigate MyTabbedPage/ChildTabPage1/Page1 to MyTabbedPage/ChildTabPage2/Page2 in Xamarin.Forms, I suggest you can consider to use Shell to do this.
Xamarin.Forms Shell includes a URI-based navigation experience that uses routes to navigate to any page in the application, without having to follow a set navigation hierarchy. In addition, it also provides the ability to navigate backwards without having to visit all of the pages on the navigation stack.
Here is the article about using Shell:https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/shell/navigation

Xamarin.Forms, using the Prism.Forms NavigationService

I am trying to implement a login scenario with Xamarin Forms and Prism.
My application root page is a MasterDetail page (HomeMasterDetailPage); this being used to provide the side menu.
What I am trying to do is to have the HomeMasterDetailPage page shown with Content set to an instance of LoginPage. When the user logs in, the Content should change to an instance of HomeDetailContentPage. It should not be possible to return to the LoginPage using the back button.
I am using the NavigationService from Prism Forms.
My start up is like this...
public partial class App : PrismApplication {
public App(IPlatformInitializer initializer = null)
: base(initializer) {
}
protected override void OnInitialized() {
InitializeComponent();
Uri uri = new Uri($"/{nameof(NavigationPage)}/{nameof(HomeMasterDetailPage)}/{nameof(HomeDetailContentPage)}", UriKind.Absolute);
var settings = Container.Resolve<SettingsService>();
if (!settings.DeviceUserID.HasValue)
uri = new Uri($"/{nameof(NavigationPage)}/{nameof(HomeMasterDetailPage)}/{nameof(LoginPage)}", UriKind.Absolute);
NavigationService.NavigateAsync(uri);
}
protected override void RegisterTypes() {
Container.RegisterTypeForNavigation<NavigationPage>();
Container.RegisterTypeForNavigation<LoginPage, LoginPageViewModel>();
Container.RegisterTypeForNavigation<HomeMasterDetailPage, HomePageViewModel>();
Container.RegisterTypeForNavigation<HomeMasterContentPage>();
Container.RegisterTypeForNavigation<HomeDetailContentPage>();
}
}
This correctly displays the LoginPage within the HomeMasterDetailPage if the user is not already logged on, and the HomeDetailContentPage within the same HomeMasterDetailPage if the user is logged on.
The problem comes when actually logging on; the following is the code within the view model for the LoginPage...
protected async Task ExecuteLoginCommand() {
Uri uri = new Uri($"/{nameof(NavigationPage)}/{nameof(HomeMasterDetailPage)}/{nameof(HomeDetailContentPage)}", UriKind.Absolute);
await this.navigationService.NavigateAsync(uri);
}
It is my understanding that by using an absolute Uri this should reset the navigation so that the new page arrangement (/NavigationPage/HomeMasterDetailPage/HomeDetailContentPage) is at the top and bottom of the stack, allowing me to then move forward from there. Instead, I am getting an unhandled exception (on Android 7.0).
What am I doing wrong?
Note: All of the examples that I see have the MasterDetailPage at the root with Content being set to NavigationPage/ContentPage; when I try this I do not get exceptions, however the side menu operates differently within the MasterDetailPage - when you tap on the "hamburger" the side menu slides in over everything (including the action/title bar) and the only way to clear it is to tap outside of the side menu that slides in whereas when I show the MasterDetailPage within a NavigationPage the side menu slides in below the action/title bar and the hamburger changes to an arrow that you can click to hide the side menu again.
I can't say I've tested this exact scenario. However, if your LoginPage is the Detail of a MasterDetailPage, you may not want to perform the navigation from the LoginPage. You could, instead create a SuccessfulLoginEvent, which you would then publish from the LoginPage using the IEventAggregator, and you would subscribe to on your MasterDetailPage's ViewModel. You could then perform the navigation as _navigationService.NavigateAsync("NavigationPage/ViewA") and it should reset the Detail such that the back button doesn't bring you to the LoginPage.
Alternatively, you can simply perform an absolute Navigation which has the effect of:
Application.Current.MainPage = new MyPage().
To do to this, you could do the navigation from anywhere as:
_navigationService.NavigateAsync("/MyMasterDetailPage/NavigationPage/ViewA")

Resources