Xamarin 形成 UWP 自定义 TabbedView

Xamarin forms UWP custom TabbedView

我一直在寻找一种在 Xamarin Forms 中自定义 TabbedView 的解决方案,以便我可以在底部为 UWP 创建选项卡。在 iOS 和 Android 中它位于底部,但对于 UWP 它不起作用。我尝试为 UWP 版本编写自定义渲染,使其位于屏幕底部。

[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);
        }
}
}

在研究中,我发现 与此相关,并发现一些样式已应用于 Pivot 以制作制表符在底部。我正在努力通过自定义渲染 class 来应用它。你能帮我解决同样的问题吗?

非常感谢您的考虑。

您需要自定义FormsPivot控件样式才能使标题显示在底部。请参考以下代码:

在您的 UWP 项目中 App.xaml 添加此 ControlTemplate:

命名空间(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>

感谢您的自定义渲染器,您可以按如下方式应用此 ControlTemplate

 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);
        }
    }