1
votes

I was looking for a solution to customize the TabbedView in Xamarin Forms so that I can make the tabs at the bottom for UWP. In iOS and Android its coming at the bottom, but for UWP its not working. I have tried to write a custom render for the UWP version for making it at the bottom of the screen.

[assembly: ExportRenderer(typeof(TabbedPage), typeof(CustomTabRenderer))]
namespace TabbedPageWithNavigationPage.UWP.Renders
{
    class CustomTabRenderer : TabbedPageRenderer
    {
        public CustomTabRenderer()
        {
            this.ElementChanged += CustomTabRenderer_ElementChanged;

        }

        private void CustomTabRenderer_ElementChanged(object sender, VisualElementChangedEventArgs e)
        {
            Control.HeaderTemplate = GetStyledTitleTemplate();
        }

        private Windows.UI.Xaml.DataTemplate GetStyledTitleTemplate()
        {
            string dataTemplateXaml = @"<DataTemplate xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
            xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"">
                <TextBlock
                    Text=""{Binding Title}""
                    FontFamily=""/Assets/Fonts/museosans-500.ttf#museosans-500""
                    FontSize =""25"" />
                  </DataTemplate>";

            return (Windows.UI.Xaml.DataTemplate)XamlReader.Load(dataTemplateXaml);
        }
}
}

On research, I found post related to this and found some styles getting applied to Pivot for making the tabs at the bottom. I \'m struggling to get this applied through the custom render class. Could you please help me to resolve the same.

Thank you so much for the consideration.

1

1 Answers

1
votes

You need to customize FormsPivot control style in order to make title appear at the bottom. Please refer to the below code:

In your UWP project App.xaml add this ControlTemplate:

Namespace ( xmlns:uwp="using:Xamarin.Forms.Platform.UWP")

      <ControlTemplate TargetType="uwp:FormsPivot" x:Key="FormsPivotTemplate">
                    <Grid x:Name="RootElement" Background="{TemplateBinding Background}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="*" />
                            <RowDefinition Height="Auto" />
                        </Grid.RowDefinitions>
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="NavigationButtonsVisibility">
                                <VisualState x:Name="NavigationButtonsHidden" />
                                <VisualState x:Name="NavigationButtonsVisible">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity" Storyboard.TargetName="NextButton">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="1" />
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IsEnabled" Storyboard.TargetName="NextButton">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="True" />
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity" Storyboard.TargetName="PreviousButton">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="1" />
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IsEnabled" Storyboard.TargetName="PreviousButton">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="True" />
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                            <VisualStateGroup x:Name="HeaderStates">
                                <VisualState x:Name="HeaderDynamic" />
                                <VisualState x:Name="HeaderStatic">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="Header">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="StaticHeader">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>

                        <Border x:Name="TopCommandBarArea" HorizontalAlignment="Stretch" Background="{TemplateBinding ToolbarBackground}">
                            <uwp:FormsCommandBar x:Name="CommandBar" Background="{TemplateBinding ToolbarBackground}" MinHeight="{ThemeResource TitleBarHeight}">
                                <uwp:FormsCommandBar.Content>
                                    <Border x:Name="TitleArea" Visibility="{TemplateBinding TitleVisibility}" Height="{ThemeResource TitleBarHeight}">
                                        <TextBlock Text="{TemplateBinding Title}" TextWrapping="NoWrap" VerticalAlignment="Center" Margin="10,0,0,0" Foreground="{TemplateBinding ToolbarForeground}" Style="{ThemeResource TitleTextBlockStyle}" />
                                    </Border>
                                </uwp:FormsCommandBar.Content>
                            </uwp:FormsCommandBar>
                        </Border>

                        <Grid Grid.Row="1">
                            <Grid.Resources>
                                <ControlTemplate x:Key="NextTemplate" TargetType="Button">
                                    <Border x:Name="Root" BorderBrush="{ThemeResource SystemControlForegroundTransparentBrush}" BorderThickness="{ThemeResource PivotNavButtonBorderThemeThickness}" Background="{ThemeResource SystemControlBackgroundBaseMediumLowBrush}">
                                        <VisualStateManager.VisualStateGroups>
                                            <VisualStateGroup x:Name="CommonStates">
                                                <VisualState x:Name="Normal" />
                                                <VisualState x:Name="PointerOver">
                                                    <Storyboard>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="Root">
                                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseMediumBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="Arrow">
                                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltAltMediumHighBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                    </Storyboard>
                                                </VisualState>
                                                <VisualState x:Name="Pressed">
                                                    <Storyboard>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="Root">
                                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseMediumHighBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="Arrow">
                                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltAltMediumHighBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                    </Storyboard>
                                                </VisualState>
                                            </VisualStateGroup>
                                        </VisualStateManager.VisualStateGroups>
                                        <FontIcon x:Name="Arrow" Foreground="{ThemeResource SystemControlForegroundAltMediumHighBrush}" FontSize="12" FontFamily="{ThemeResource SymbolThemeFontFamily}" Glyph="&#xE0E3;" HorizontalAlignment="Center" MirroredWhenRightToLeft="True" UseLayoutRounding="False" VerticalAlignment="Center" />
                                    </Border>
                                </ControlTemplate>
                                <ControlTemplate x:Key="PreviousTemplate" TargetType="Button">
                                    <Border x:Name="Root" BorderBrush="{ThemeResource SystemControlForegroundTransparentBrush}" BorderThickness="{ThemeResource PivotNavButtonBorderThemeThickness}" Background="{ThemeResource SystemControlBackgroundBaseMediumLowBrush}">
                                        <VisualStateManager.VisualStateGroups>
                                            <VisualStateGroup x:Name="CommonStates">
                                                <VisualState x:Name="Normal" />
                                                <VisualState x:Name="PointerOver">
                                                    <Storyboard>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="Root">
                                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseMediumBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="Arrow">
                                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltAltMediumHighBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                    </Storyboard>
                                                </VisualState>
                                                <VisualState x:Name="Pressed">
                                                    <Storyboard>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="Root">
                                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseMediumHighBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="Arrow">
                                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltAltMediumHighBrush}" />
                                                        </ObjectAnimationUsingKeyFrames>
                                                    </Storyboard>
                                                </VisualState>
                                            </VisualStateGroup>
                                        </VisualStateManager.VisualStateGroups>
                                        <FontIcon x:Name="Arrow" Foreground="{ThemeResource SystemControlForegroundAltMediumHighBrush}" FontSize="12" FontFamily="{ThemeResource SymbolThemeFontFamily}" Glyph="&#xE0E2;" HorizontalAlignment="Center" MirroredWhenRightToLeft="True" UseLayoutRounding="False" VerticalAlignment="Center" />
                                    </Border>
                                </ControlTemplate>
                            </Grid.Resources>
                            <ScrollViewer x:Name="ScrollViewer" BringIntoViewOnFocusChange="False" HorizontalSnapPointsAlignment="Center" HorizontalSnapPointsType="MandatorySingle" HorizontalScrollBarVisibility="Hidden" Margin="{TemplateBinding Padding}" Template="{StaticResource ScrollViewerScrollBarlessTemplate}" VerticalSnapPointsType="None" VerticalScrollBarVisibility="Disabled" VerticalScrollMode="Disabled" VerticalContentAlignment="Stretch" ZoomMode="Disabled">
                                <PivotPanel x:Name="Panel" VerticalAlignment="Stretch">
                                    <Grid x:Name="PivotLayoutElement">
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="Auto"/>
                                            <ColumnDefinition Width="*"/>
                                            <ColumnDefinition Width="Auto"/>
                                        </Grid.ColumnDefinitions>
                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="*"/>
                                            <RowDefinition Height="Auto"/>
                                        </Grid.RowDefinitions>
                                        <Grid.RenderTransform>
                                            <CompositeTransform x:Name="PivotLayoutElementTranslateTransform"/>
                                        </Grid.RenderTransform>
                                        <ContentPresenter x:Name="LeftHeaderPresenter"
                                                              ContentTemplate="{TemplateBinding LeftHeaderTemplate}"
                                                              Content="{TemplateBinding LeftHeader}"
                                                              HorizontalAlignment="Stretch"
                                                              VerticalAlignment="Stretch"/>
                                        <ContentControl x:Name="HeaderClipper"
                                                            Grid.Column="1"
                                                            Grid.Row="1"
                                                            HorizontalContentAlignment="Stretch"
                                                            UseSystemFocusVisuals="True">
                                            <ContentControl.Clip>
                                                <RectangleGeometry x:Name="HeaderClipperGeometry"/>
                                            </ContentControl.Clip>
                                            <Grid Background="Transparent">
                                                <PivotHeaderPanel x:Name="StaticHeader" Visibility="Collapsed"/>
                                                <PivotHeaderPanel x:Name="Header">
                                                    <PivotHeaderPanel.RenderTransform>
                                                        <TransformGroup>
                                                            <CompositeTransform x:Name="HeaderTranslateTransform"/>
                                                            <CompositeTransform x:Name="HeaderOffsetTranslateTransform"/>
                                                        </TransformGroup>
                                                    </PivotHeaderPanel.RenderTransform>
                                                </PivotHeaderPanel>
                                            </Grid>
                                        </ContentControl>
                                        <Button x:Name="PreviousButton"
                                                    Background="Transparent"
                                                    Grid.Column="1" 
                                                    HorizontalAlignment="Left"
                                                    Height="36" IsTabStop="False" 
                                                    Grid.Row="1"
                                                    IsEnabled="False"
                                                    Margin="{ThemeResource PivotNavButtonMargin}" 
                                                    Opacity="0"
                                                    Template="{StaticResource PreviousTemplate}" 
                                                    UseSystemFocusVisuals="False"
                                                    VerticalAlignment="Top" 
                                                    Width="20"/>
                                        <Button x:Name="NextButton"
                                                    Background="Transparent"
                                                    Grid.Column="1"
                                                    HorizontalAlignment="Right"
                                                    Height="36"
                                                    IsTabStop="False"
                                                    IsEnabled="False"
                                                    Margin="{ThemeResource PivotNavButtonMargin}"
                                                    Opacity="0"
                                                    Grid.Row="1"
                                                    Template="{StaticResource NextTemplate}"
                                                    UseSystemFocusVisuals="False"
                                                    VerticalAlignment="Top"
                                                    Width="20"/>
                                        <ContentPresenter x:Name="RightHeaderPresenter"
                                                              ContentTemplate="{TemplateBinding RightHeaderTemplate}"
                                                              Content="{TemplateBinding RightHeader}"
                                                              Grid.Column="2"
                                                              Grid.Row="1"
                                                              HorizontalAlignment="Stretch"
                                                              VerticalAlignment="Stretch"/>
                                        <ItemsPresenter x:Name="PivotItemPresenter"
                                                            Grid.ColumnSpan="3"
                                                            Grid.Row="0">
                                            <ItemsPresenter.RenderTransform>
                                                <TransformGroup>
                                                    <TranslateTransform x:Name="ItemsPresenterTranslateTransform"/>
                                                    <CompositeTransform x:Name="ItemsPresenterCompositeTransform"/>
                                                </TransformGroup>
                                            </ItemsPresenter.RenderTransform>
                                        </ItemsPresenter>
                                    </Grid>
                                </PivotPanel>
                            </ScrollViewer>
                        </Grid>
                        <Border x:Name="BottomCommandBarArea" Grid.Row="2" HorizontalAlignment="Stretch"></Border>
                    </Grid>
</ControlTemplate>

Thank in your custom renderer you can apply this ControlTemplate as below:

 class CustomTabRenderer : TabbedPageRenderer
    {
        public CustomTabRenderer()
        {
            this.ElementChanged += CustomTabRenderer_ElementChanged;

        }

        private void CustomTabRenderer_ElementChanged(object sender, VisualElementChangedEventArgs e)
        {
            if (Control != null)
            {
                Control.HeaderTemplate = GetStyledTitleTemplate();
                Control.Template = (ControlTemplate)Application.Current.Resources["FormsPivotTemplate"];
            }
        }

        private Windows.UI.Xaml.DataTemplate GetStyledTitleTemplate()
        {
            string dataTemplateXaml = @"<DataTemplate xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
            xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"">
                <TextBlock
                    Text=""{Binding Title}""
                    FontFamily=""/Assets/Fonts/museosans-500.ttf#museosans-500""
                    FontSize =""25"" />
                  </DataTemplate>";

            return (Windows.UI.Xaml.DataTemplate)XamlReader.Load(dataTemplateXaml);
        }
    }