Forum Xamarin.Forms

Windows RT - Permanently Visible Tab Headers

Matthew.4307Matthew.4307 USMember ✭✭✭
edited April 2016 in Xamarin.Forms

In Xamarin.WindowsRT, unlike the other platforms, on a Tabbed Page the tabs aren't permanently visible but instead are part of the TopAppBar - Is this because Windows RT doesn't actually have a proper Tabbed Page control? It's incredibly annoying and I wanted to solve that.

My solution, which I'm not claiming is the only solution, was to use the new ControlTemplates. It's not the most elegant solution, but the result looks like the attached image and it's fairly clean.

I created a Template that adds to the top of the page a stack layout of buttons with the 'Tabs' and then a title bar with the current page name. To make using the template easier I have a subclass of ContentPage that sets the Template in the constructor only for Windows.

In the Template I hook into OnParentSet, find the Parent to the template and assert it is a Page. I then attach an event so I know when the page parent (Tabbed Page) is changed so I can react to changes in the Tabs.

OnParentSet
{
base.OnParentSet();

        if (!(this.Parent is Page))
        {
            throw new System.Exception("Parent must be a Page");
        }

        this.Parent.PropertyChanged += Parent_PropertyChanged;

}

PropertyChangedEvent
{
if (e.PropertyName == "Parent")
{
(sender as Page).Parent.ChildAdded += this.GrandParent_ChildAdded;
this.CreateTabHeaders();
}
}

Finally I create my tabs in a helper method, I already had an extension to TabbedPage that allowed switching to a tab with a given name.

    private void CreateTabHeaders()
    {
        this.headers.Children.Clear();

        if(!(this.Parent.Parent is RFA.Controls.TabbedPage))
        {
            return;
        }

        var tabbedPage = (this.Parent.Parent as RFA.Controls.TabbedPage);
        foreach (var child in tabbedPage.Children)
        {
            var button = new Button()
            {
                Text = child.Title,
                TextColor = StyleHelper.TextColorMenuBar,
                BorderWidth = 1,
                Margin = new Thickness(0),
                Command = new Command<string>((x) => tabbedPage.SwitchToTab(x)),
                CommandParameter = child.Title
            };

            button.FontSize = StyleHelper.GetFontSize(TextSize.Normal, button);

            this.headers.Children.Add(button);
        }
    }

I'm not interested in setting an indicator on the header bar for the selected tab, though that would be easy because the tab bar is rendered on each tab so is static and only needs to be set once.

Sign In or Register to comment.