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
Related
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")
I am creating an app using Xamarin Forms. I have a MainTab page that displays all the 4 tabs. There is one specific tab call Me tab.
As of now the Me Tab displays the user's profile. However, when the user is not logged in, it my UserLogin page should be displayed instead. How do I do that in Xamarin forms?
You can achieve this in various ways. If you're using a MVVM approach the most straight forward solution would be to set a binding in your viewmodel indicating user logging. Based on that you can set your
tabbedPage.CurrentPage = TheTabPageYouWant.
If you're using codebehind, just use in your ;
public bool UserLogged
{
get { return _userLogged; }
set
{
_userLogged = value;
if (_userLogged)
{
tabbedPage.CurrentPage = UserProfilePage.
return;
}
tabbedPage.CurrentPage = LogInPage.
}
I strongly recommend any Xamarin.Forms book and MVVM techniques for you.
Don't hesitate to ask any further questions.
I have masterdetail page and there is left menu in it. Its working fine during user is on masterdetail page. But When user move from master detail page to simple content page(that is not part of master detail page), on this content page if he swipe from left to right left menu opens.
How I can disable the left menu on this content page? and why left menu is showing on simple content page while it is not part of the master detail page?
If you're still looking for a solution, you can do it like so:
IsGestureEnabled = false;
You can continue to use
await Navigation.PushAsync(new PageWhichWontOpenTheMenu());
To use it, simply get the RootPage (the MasterDetailPage) on the OnAppearing method like so:
protected override void OnAppearing(){
base.OnAppearing();
(Application.Current.MainPage as RootPage).IsGestureEnabled = false;
}
Tell me if it works for you, cheers!
You can only disable the gesture from master details page.
It can be solve by notifying that the current page is not master page:
1)When we are setting the Master details page by
Detail = new NavigationPage((Page)Activator.CreateInstance(page));
IsGestureEnabled = true;// always set it true when setting a page to master page
2)Use MessagingCenter from MasterDetails Page for notifying that the current page is not a master page:(inside the master page constructor)
MessagingCenter.Subscribe<string>(this, "DisableGesture", (sender) =>
{
if(sender == "0")
{
IsGestureEnabled = false;
}
else
{
IsGestureEnabled = true;
}
});
3)when you navigate from a nornal content page,and you dont want to open the master menu from here then notify the master page IsGestureEnabled = false;
//content page OnAppearing method
protected override void OnAppearing()
{
MessagingCenter.Send<string>("0", "DisableGesture");
}
do this for all your content page,where you dont want to open master menu.
****and remember that which pages you are setting as master page,for those pages onappearing method send messaging center with value "1"
protected override void OnAppearing()
{
MessagingCenter.Send<string>("1", "DisableGesture");
}
Thanks
Better yet what you can do in your OnMenuItemSelected event for your SideMenu list is check for the type that you want to Disable the SideMenu for and then set IsGestureEnabled to false when navigating to that page:
private void OnMenuItemSelected(object sender, SelectedItemChangedEventArgs e)
{
var item = (SideMenuItem)e.SelectedItem;
var page = item.TargetType;
if (page == typeof(PageToDisableMenu))
IsGestureEnabled = false;
Detail = new NavigationPage((Page)Activator.CreateInstance(page));
IsPresented = false;
}
I know this answer is late but I hope it helps someone in the future :).
You probably use Detail.Navigation.PushAsync(...) instead of that use Navigation.PushAsync(...)
To really disable, I found one way, use Navigation.PushModalAsync(...). But this way, you don't have the navigation bar at the top anymore. You can build one yourself though.
What worked for was to disable the whole MasterDetailPage with the IsEnabled property.
In may case executing a process from an option menu (not navigation or change the Detail page) and I needed to block any interaction of the user with the page.
Hope this helps.
Regards
I'm using DX 15.1, and I'm trying to create a new tab from a child form.
So, basically, I have a parent form called "pForm", and a child form called "cForm".
I'm using DocumentManager module and switched it to TabbedView mode.
When I'm trying to create a new tab from pForm, it's totally fine.
the problem is, when I'm can't create a new tab from cForm into pForm's TabbedView.
How do I achieve this?
Thanks, mate :)
UPDATE :
#DmitryG, thanks for your response.
I've attached a screenshot below.
The MDI-Parent is the RGP page with a settings header. and the MDI-Child is the Class Attendance form (popped-up window, triggered by a button inside the RGP form).
Can you give a solution, how to make the Class Attendance Form (mdi-child) became a new Tab beside RGP tab when it's triggered by a button within mdi-parent? Not as a popped-up window.
thanks!
When the DocumentManager works in MDI Mode you can just work with mdi parent and child forms. So, I believe, you code for adding a new mdi-child into mdi-parent form can looks like this:
static void AddMdiChildFromMdiParent(Form mdiParent) {
Form child = new Form();
child.MdiParent = mdiParent;
child.Show();
}
Within the mdi-parent form you can call this code like this:
AddMdiChildFromMdiParent(this);
To add a new mdi-child from an existing mdi-child you can reuse the code above as follows:
static void AddMdiChildFromMdiChild(Form child) {
AddMdiChildFromMdiParent(child.MdiParent);
}
I created a SWT based Wizard which has an own help Button by custom. Now i want to put some content behind that, so maybe a SWT browser will be openend and a predifined HTML Doc will be shown. But I don't have any clue where to access the Actions of the Help Button within my Wizard. Any idea?
I am assuming that you are using the standard JFace interfaces and classes for the wizard implementation. So, in your wizard page (extending org.eclipse.jface.wizard.WizardPage) you just have to override the performHelp method. See the below snippet.
#Override
public void performHelp()
{
Shell shell = new Shell(getShell());
shell.setText("My Custom Help !!");
shell.setLayout(new GridLayout());
shell.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
Browser browser = new Browser(shell, SWT.NONE);
browser.setUrl("http://stackoverflow.com/questions/7322489/cant-put-content-behind-swt-wizard-help-button");
browser.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
shell.open();
}
>>Wizard image
>>After pressing the help button