According to the documentation of Prism "when selecting a tab programmatically both the INavigationAware and IConfirmNavigation interfaces are invoked". But unfortunately this is not the case for me.
I did the following with Prism.DryIoc.Forms v7.2.0.1422 (also latest version did not work) and Xamarin.Forms v4.8.0.1560:
My MainPage:
<?xml version="1.0" encoding="utf-8" ?>
<TabbedPage
x:Class="SampleApp.Views.MainPage"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prim="http://prismlibrary.com"
xmlns:views="clr-namespace:SampleApp.Views;assembly=SampleApp"
Title="{Binding Title}">
<NavigationPage Title="Page A">
<x:Arguments>
<views:APage Title="Page A" />
</x:Arguments>
<NavigationPage.Behaviors>
<prim:NavigationPageActiveAwareBehavior />
</NavigationPage.Behaviors>
</NavigationPage>
<NavigationPage Title="Page B">
<x:Arguments>
<views:BPage Title="Page B" />
</x:Arguments>
<NavigationPage.Behaviors>
<prim:NavigationPageActiveAwareBehavior />
</NavigationPage.Behaviors>
</NavigationPage>
<NavigationPage Title="Page C">
<x:Arguments>
<views:CPage Title="Page C" />
</x:Arguments>
<NavigationPage.Behaviors>
<prim:NavigationPageActiveAwareBehavior />
</NavigationPage.Behaviors>
</NavigationPage>
</TabbedPage>
In BPageViewModel selecting tab "APage" with NavigationParameters:
private async Task SayHelloOnPage()
{
var navParam = new NavigationParameters
{
{ "SayHelloTo", "Prism" }
};
await NavigationService.SelectTabAsync(nameof(APage), navParam);
}
In APageViewModel override OnNavigatedTo method:
public override void OnNavigatedTo(INavigationParameters parameters)
{
base.OnNavigatedTo(parameters);
System.Diagnostics.Debug.WriteLine($"OnNavigatedTo is called", nameof(APageViewModel));
if (parameters.ContainsKey("SayHelloTo"))
{
var name = parameters["SayHelloTo"] as string;
if (name != null)
{
System.Diagnostics.Debug.WriteLine($"Say Hello to {name}", nameof(APageViewModel));
}
}
}
See also this example project on my DropBox
Is this a bug or do I miss something?
I believe this is a bug, or at least an oversight in the API. It does call OnNavigatedTo, but only on the Page that is directly part of the TabbedPage. If you have your target page inside a NavigationPage, only the NavigationPage will get the OnNavigatedTo call. See https://github.com/PrismLibrary/Prism/blob/master/src/Forms/Prism.Forms/Navigation/TabbedPages/INavigationServiceExtensions.cs#L73-L74 .
I worked around this by copying the above implementation to my project and then changing the behaviour to instead call OnNavigatedTo on the relevant child page of the NavigationPage.
Related
My Xamarin.Forms app is using Shell flyouts for navigation. When I navigate the app on iOS, I notice a strange behaviour. Reproduction steps:
Go to a page that has an Entry in it
Type anything into the Entry
Go to another page
Return to the same page you typed something into the Entry
The keyboard then pops up and then disappears right after. I can see the cursor in the Entry appear then disappear too. I removed a lot of my code to try to find the problem, but I can not find it. My code:
AppShell.xaml:
<Shell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MyApp.Views"
Title="MyApp"
x:Name="shellAppShell"
x:Class="MyApp.AppShell">
<FlyoutItem x:Name="flyoutItemMainPage" Title="Home" Icon="icon_about.png">
<ShellContent x:Name="shellContentMainPage" Route="MainPage" ContentTemplate="{DataTemplate local:MainPage}" />
</FlyoutItem>
<FlyoutItem x:Name="flyoutItemAPage" Title="A Page" Icon="Pagea.png">
<ShellContent x:Name="shellContentPageA" Route="PageA" ContentTemplate="{DataTemplate local:PageA}" />
</FlyoutItem>
<!-- More flyouts... -->
</Shell>
PageA.xaml:
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Name="PageA"
x:Class="MyApp.Views.PageA">
<ContentPage.Content>
<StackLayout Orientation="Vertical" >
<Entry />
<Button Text="back" Clicked="OnBackClicked"/>
</StackLayout>
</ContentPage.Content>
</ContentPage>
PageA.xaml.cs
public partial class PageA : ContentPage
{
public PageA()
{
InitializeComponent();
}
void OnBackClicked(object sender, EventArgs e)
{
Shell.Current.CurrentItem = AppShellGlobal.ShellContentMainPage;
}
}
After my testing, this situation only occurs in iOS.
There is a simpler solution, you can rewrite the ContentPage and end the editing state of the page when the page loads.
First, create the MyPageRenderer class in your project's xxx.iOS directory.
Here is the internal code:
[assembly: ExportRenderer(typeof(ContentPage), typeof(MyPageRenderer))]
namespace App15.iOS
{
public class MyPageRenderer : PageRenderer
{
public override void ViewDidAppear(bool animated)
{
View.EndEditing(true);//Solved the problem with this line of code
base.ViewDidAppear(animated);
}
}
}
Here is the screenshot:
I am working on a Xamarin Forms app with a TabbedPage which has 6 tabs.
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:tabs="clr-namespace:TabbedPageIssue"
xmlns:android="clr-namespace:Xamarin.Forms.PlatformConfiguration.AndroidSpecific;assembly=Xamarin.Forms.Core"
android:TabbedPage.ToolbarPlacement="Bottom"
android:TabbedPage.IsSwipePagingEnabled="False"
android:TabbedPage.BarSelectedItemColor="#F79320"
android:TabbedPage.BarItemColor="#B1B2B3"
x:Class="TabbedPageIssue.MainPage">
<tabs:Tab1 Title="Tab1"/>
<tabs:Tab2 Title="Tab2"/>
<tabs:Tab3 Title="Tab3"/>
<tabs:Tab4 Title="Tab4"/>
<tabs:Tab5 Title="Tab5"/>
<tabs:Tab6 Title="Tab6"/>
</TabbedPage>
In my app, I want to have a button to direct the app to a tab "inbox" in the "More" part with this code:
private void Button_Clicked(object sender, EventArgs e)
{
var mainPage = this.Parent as TabbedPage;
mainPage.CurrentPage = mainPage.Children[4];
}
When i click the button to change tab, the View changes but the "More" tab is not selected, and if i click on tab1, the view of tab 5 doesn't disappear.
This seems to be a bug of TabbedPage. Everybody has any idea to fix this problem?
I was able to reproduce this issue. For workaround, you could use Shell tabs instead. For the latest version of VS, when you create a Tabbed template, it is using Shell. https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/shell/
Xaml:
<?xml version="1.0" encoding="UTF-8"?>
<Shell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:App3.Views"
Title="App3"
x:Class="App3.AppShell">
<TabBar>
<ShellContent Title="Tab1" ContentTemplate="{DataTemplate local:Page1}" />
<ShellContent Title="Tab2" ContentTemplate="{DataTemplate local:Page2 }" />
<ShellContent Title="Tab3" ContentTemplate="{DataTemplate local:Page3 }" />
<ShellContent Title="Tab4" ContentTemplate="{DataTemplate local:Page4}" />
<ShellContent Title="Tab5" Route="page5" ContentTemplate="{DataTemplate local:Page5 }" />
<ShellContent Title="Tab6" ContentTemplate="{DataTemplate local:Page6 }" />
</TabBar>
</Shell>
Navigating from Page1 to Page5:
async void Button_Clicked(object sender, EventArgs e)
{
await Shell.Current.GoToAsync("//page5");//page5 is the route i set in xaml
}
OutPut:
I have a master detail page with a burger icon at the top that shows the drawer menu. But the master detail itself is only one page, id like it to be 2 pages ( like in the tabbed page, where u can swipe between the two).
I have tried the following:
<MasterDetailPage.Detail>
<TabbedPage>
<TabbedPage.Children>
<ContentPage Title="Page 1" Icon="ja.png" />
<ContentPage Title="Page 2" Icon="ja.png" />
<ContentPage Title="Page 3" Icon="ja.png" />
</TabbedPage.Children>
</TabbedPage>
</MasterDetailPage.Detail>
This does display mulitple pages inside the master detail, but it also removes the burger and the whole navigation bar also.
Is there a way to enable a tabbed page inside a master detail and still have the navigation bar with the burger icon?
Thank you!
I only works when you have another page that is a tabbed page and render it here:
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="Q2go.View.MasterDetailPage1"
xmlns:pages="clr-namespace:Q2go.View">
<MasterDetailPage.Master>
<pages:MasterDetailPage1Master x:Name="MasterPage" />
</MasterDetailPage.Master>
<MasterDetailPage.Detail>
<NavigationPage>
<x:Arguments>
<pages:TabbedPage1/>
</x:Arguments>
</NavigationPage>
</MasterDetailPage.Detail>
</MasterDetailPage>
Try wrapping your TabbedPage in a NavigationPage as such:
<MasterDetailPage.Detail>
<NavigationPage>
<x:Arguments>
<TabbedPage>
<TabbedPage.Children>
<ContentPage Title="Page 1" Icon="ja.png" />
<ContentPage Title="Page 2" Icon="ja.png" />
<ContentPage Title="Page 3" Icon="ja.png" />
</TabbedPage.Children>
</TabbedPage>
</x:Arguments>
</NavigationPage>
</MasterDetailPage.Detail>
I'm extending the prism sample here to also include icons, and some additional navigation. My goal is to add something like the code below (where the icon information is) and am unsure how to add that to either my view, or the view model correctly.
<?xml version="1.0" encoding="UTF-8"?>
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
prism:ViewModelLocator.AutowireViewModel="True"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:WebOfTrust.Views"
x:Class="WebOfTrust.Views.Client.WebOfTrustMainPage"
Title="{Binding Title}">
<TabbedPage.Children>
<!-- HOW DO I SET AN ICON FOR THESE? Either in the View or Model? -->
<NavigationPage Title="Contacts" >
<x:Arguments>
<local:Client.MyPeople.MyPeopleList/>
</x:Arguments>
</NavigationPage>
<NavigationPage Title="Places" Icon="Image7DoesntWork.png">
<x:Arguments>
<local:Client.MyPlaces.MyPlacesList/>
</x:Arguments>
</NavigationPage>
<NavigationPage Title="Docs" Icon="Image7DoesntWork.png">
<x:Arguments>
<local:Client.MyWallet.WalletCards/>
</x:Arguments>
</NavigationPage>
</TabbedPage.Children>
</TabbedPage>
What normally works
I normally have a navigation page in the view where I specify the icon below.
<NavigationPage Title="Trust Anchor List">
<NavigationPage.Icon>
<OnPlatform x:TypeArguments="FileImageSource">
<On Platform="iOS" Value="tab_feed.png"/>
</OnPlatform>
</NavigationPage.Icon>
<x:Arguments>
<local:Client.TrustAnchorList />
</x:Arguments>
</NavigationPage>
Question
What is the right way to set an icon in either the view or the model when using Prism?
just add the icon attribute in the children of the tabbed page.
It works fine for me
<local:ContactUs Icon="Icons/History_Tab.png" Title="{Translate:TranslateExtension Text=NewMessage}" />
my icons are under a folder in the resources but you can put them anywhere.
I have a problem making a tabbed layout on my master detail page. I have tried to do it like this:
<?xml version="1.0" encoding="utf-8" ?>
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MasterDetailTest.View"
x:Class="MasterDetailTest.MainPage">
<MasterDetailPage.Master>
<local:MasterPage x:Name="masterPage" />
</MasterDetailPage.Master>
<MasterDetailPage.Detail>
<NavigationPage>
<x:Arguments>
<local:Home />
</x:Arguments>
</NavigationPage>
<TabbedPage>
<TabbedPage.Children>
<ContentPage Title="Home" Icon="home.png"/>
<ContentPage Title="Home" Icon="home.png"/>
<ContentPage Title="Home" Icon="home.png"/>
</TabbedPage.Children>
</TabbedPage>
</MasterDetailPage.Detail>
</MasterDetailPage>
But for some reason it's not working adding tabbed page just on xaml, should i've to try this at the cs?
you can't put TabbedPage inside NavigationPage. The right order is:
- TabbedPage > NavigationPage > page.
In Fact, you shouldn't mix it. Use MasterDetailPage > NavigationPage
OR TabbedPage > NavigationPage BUT NOT MasterDetailPage > TabbedPage.
this would works for you:
MasterDetail:
https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/navigation/master-detail-page/
TabbedPage:
https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/navigation/tabbed-page/