Hi. I am trying to follow the docs on Multi-page applications and Navigation in order to implement the same view as the C# WPF "AppShell" template, but cannot seem to figure out a way to show the Bar with the title. I can see that in the C#/WPF template <TabBar> is used with <Tab>-components as children, while in the Fabulous version, a TabbedPage is used:
let view (model: Model) dispatch =
View.TabbedPage(
hasNavigationBar = true,
shellNavBarIsVisible = true,
shellTabBarIsVisible = true,
title = "Page title should be here",
children = [
View.ContentPage(
title = "About",
icon = InputTypes.Image.Path("tab_about.png"),
content = View.Label(text = "About page content"))
])
.ShellTabBarIsVisible(true)
.ShellNavBarIsVisible(true)
.HasNavigationBar(true)
.ToolbarItems([View.ToolbarItem(text="Some text")])
Basically, I've tried setting all the flags I could find to true, but nothing gets shown at the top of the page.
NOTE: Adding ToolbarItems this way works just fine when using a NavigationPage instead, but not for a TabbedPage.
In general with Xamarin.Forms, the Title property is displayed by the parent control, not by the control itself.
Just like ContentPage.Title is not displayed by the ContentPage itself but by the parent NavigationPage/TabbedPage.
So this would display a title:
View.NavigationPage(
pages = [
View.TabbedPage(
title = "Tabbed Page Title"
)
]
)
Not this
View.TabbedPage(
title = "Tabbed Page Title"
)
If you really want to display a title without a parent control, you would need to add the title to the child page (here your ContentPage).
PS: HasNavigationBar only works with NavigationPage, ShellXXX only works with Shell.
Works great, thanks!
One thing I still can't get to work, however, is now that the parent is tracking what tab is selected/active, how do I update the title when switching tabs? I am guessing, I have to dispatch an action when switching, but I can't seem to find where to dispatch in from.
P.S.: Just realized I can't find a way to give it a background color either. The way it's done in the Shell-template with C#/XAML is by providing Shell.BackgroundColor and Shell.TabBarBackgroundColor, but the only thing I see when trying to create a style is that it wants targetType: System.Type. This is briefly mentioned in the docs: (“Xaml” coding via explicit Style objects), but it just says Style....
@Yakimych For your use case, I would add a "fake" title inside the tabs so they can show their own title, this will greatly simplify your code.
let pageTitle title =
View.Label(
text = title,
backgroundColor = Color.Blue
) // Replace with whatever you want your title to look like
let contentPageWithTitle title content =
View.ContentPage(
content = View.StackLayout(
orientation = StackOrientation.Vertical,
children = [
pageTitle title
content.VerticalOptions(LayoutOptions.FillAndExpand) // The actual page content
]
)
)
let view model dispatch =
View.TabbedPage(
children = [
contentPageWithTitle "Page A"
View.Grid(...) // Page A content
contentPageWithTitle "Page B"
View.Grid(...) // Page B content
]
)
It does indeed! Unfortunately, the color does not get applied all the way up the screen, at least not on iOS 😞

Here is how the default shell template looks with C# and Xaml:

Sorry, both Xamarin and Fabulous is still relatively new to me. I got superexcited as soon as I discovered that it's possible to use the Elm architecture and F# this way for mobile development, but it is still tricky for me to understand what's going on and how to achieve certain "trivial" things so far...
Alright. So TabbedPage might not be what you really want :)
While you could make the color go all the way up, I think you would be more interested by using the Shell control, just like with the C#/XAML template.
Take a look at the Fabimals sample to see how to use Shell with Fabulous.XamarinForms.
https://github.com/fsprojects/Fabulous/tree/master/Fabulous.XamarinForms/samples/Shell/Fabimals/Fabimals
(It's a Fabulous port of the official Xaminals sample, https://github.com/xamarin/xamarin-forms-samples/tree/master/UserInterface/Xaminals)
Also, you can read more about Shell here: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/shell/
Basically, Fabulous.XamarinForms covers almost all Xamarin.Forms, so if something is available in XF, chances are it's also available in Fabulous.XamarinForms.
Ah, that looks much more similar to the Shell template - will give it a try tonight. Apparently I made an incorrect assumption that TabbedPage in Fabulous is the same as TabBar/Tab in the Shell-template for C#.
Is there any kind of beginner discord channel for Fabulous (similar to what they have for Elm and ReasonML), where beginners can ask this kind of questions? Opening an issue was the only way I could find for asking this, but perhaps there is a more suitable forum? In any case, I greatly appreciate your help with this!
@Yakimych We have a Gitter (https://gitter.im/fsprojects/Fabulous). Though some time ago I thought of setting up a Discord, so I might create one in the future.
Finally got a chance to try it out, and it looks like this is exactly what I was searching for, thank you for your help!
One thing I am curious about is if I change the content of ShellContent on line 167 from
content=Cats.view model.CatsPageModel (CatsPageMsg >> dispatch)
to Label(text = "Cats"), the compiler lets it through, but it crashes at runtime in ShellContent.cs GetOrCreateContent() function on this line:
result = ContentCache ?? (Page)template.CreateContent(content, this);
with the following exception:
System.InvalidCastException: Specified cast is not valid.
at Xamarin.Forms.ShellContent.Xamarin.Forms.IShellContentController.GetOrCreateContent () [0x00023] in D:\a\1\s\Xamarin.Forms.Core\Shell\ShellContent.cs:61
at Xamarin.Forms.Platform.iOS.ShellSectionRootRenderer.LoadRenderers () [0x00022] in D:\a\1\s\Xamarin.Forms.Platform.iOS\Renderers\ShellSectionRootRenderer.cs:145
at Xamarin.Forms.Platform.iOS.ShellSectionRootRenderer.ViewDidLoad () [0x00035] in D:\a\1\s\Xamarin.Forms.Platform.iOS\Renderers\ShellSectionRootRenderer.cs:63
at at (wrapper managed-to-native) UIKit.UIApplication.UIApplicationMain(int,string[],intptr,intptr)
at UIKit.UIApplication.Main (System.String[] args, System.IntPtr principal, System.IntPtr delegate) [0x00005] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.14.1.30/src/Xamarin.iOS/UIKit/UIApplication.cs:86
at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0000e] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.14.1.30/src/Xamarin.iOS/UIKit/UIApplication.cs:65
I've figured I need to wrap the Label in View.ContentPage in order to get it work, but I am wondering whether it is possible to catch this error at compile time.
I've figured I need to wrap the Label in View.ContentPage in order to get it work, but I am wondering whether it is possible to catch this error at compile time.
Yes, that's something we are aware of.
We started discussing it in #341.
Ah, great. Closing this. Thanks again for your help!