简体   繁体   中英

Pivot control customization on UWP

Basically I need to customize the pivot control on my uwp app and I use the style of pivot from windows phone 8.1. And it looks like this eventually(the yellow part is the content of the pivot item, I just use color to differentiate the header and the content)

在此处输入图片说明

But right now it does not meet the require of the original design. So I have two questions here:

1.How do I limit user flick the pivot in one direction? For example, users could only flick the control from left to right because the yellow content part will move to left and cover the header if the pivot is flicked from the right to the left. The content, which is the yellow part, will move entirely along with your finger and the other covered pivot header will be shown because the yellow part moves away, as you can see on the image. This is the reason why I care about the swiping direction because if you swipe left, the yellow part will covers part of the header before the gesture is done(which is not showing up in the image).

2.How to change the foreground color of the unselected pivotitem header? Right now as you can see, during the flicking process, the yellow content part will move away and the unselected header will be shown. That looks weird and it is not a good design at all. The unselected header is suppose to be transparent or be the same as the background color of the page.

Here is the code of the style:

<Style x:Key="PivotStyle1" TargetType="Pivot">
        <Setter Property="Margin" Value="0"/>
        <Setter Property="Padding" Value="0"/>
        <Setter Property="Foreground" Value="{ThemeResource PivotForegroundThemeBrush}"/>
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="ItemsPanel">
            <Setter.Value>
                <ItemsPanelTemplate>
                    <Grid/>
                </ItemsPanelTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Pivot">
                    <Grid x:Name="RootElement" Background="{TemplateBinding Background}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="*"/>
                        </Grid.RowDefinitions>
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="Orientation">
                                <VisualState x:Name="Portrait">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Margin" Storyboard.TargetName="TitleContentControl">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource PivotPortraitThemePadding}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Landscape">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Margin" Storyboard.TargetName="TitleContentControl">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource PivotLandscapeThemePadding}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <ContentControl x:Name="TitleContentControl" ContentTemplate="{TemplateBinding TitleTemplate}" Content="{TemplateBinding Title}" Style="{StaticResource PivotTitleContentControlStyle}"/>
                        <ScrollViewer x:Name="ScrollViewer" HorizontalSnapPointsAlignment="Center" HorizontalSnapPointsType="MandatorySingle" HorizontalScrollBarVisibility="Hidden" Margin="{TemplateBinding Padding}" Grid.Row="1" Template="{StaticResource ScrollViewerScrollBarlessTemplate}" VerticalSnapPointsType="None" VerticalScrollBarVisibility="Disabled" VerticalScrollMode="Disabled" VerticalContentAlignment="Stretch" ZoomMode="Disabled">
                            <PivotPanel x:Name="Panel" VerticalAlignment="Stretch">
                                <PivotHeaderPanel x:Name="Header">
                                    <PivotHeaderPanel.RenderTransform>
                                        <CompositeTransform x:Name="HeaderTranslateTransform" TranslateX="0"/>
                                    </PivotHeaderPanel.RenderTransform>
                                </PivotHeaderPanel>
                                <ItemsPresenter x:Name="PivotItemPresenter">
                                    <ItemsPresenter.RenderTransform>
                                        <TranslateTransform x:Name="ItemsPresenterTranslateTransform" X="0"/>
                                    </ItemsPresenter.RenderTransform>
                                </ItemsPresenter>
                            </PivotPanel>
                        </ScrollViewer>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

And the XAML code for the pivot control:

<Pivot Style="{StaticResource PivotStyle1}">
        <Pivot.HeaderTemplate>
            <DataTemplate>
                <Grid Height="auto">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="21*"/>
                        <RowDefinition Height="299*"/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="5*"/>
                        <ColumnDefinition Width="19*"/>
                    </Grid.ColumnDefinitions>


                    <TextBlock  Text="{Binding}"
                                Margin="14,50,9,-120"
                                Grid.Row="1"
                                HorizontalAlignment="Center"
                                FontSize="48"
                                FontFamily="ms-appx:NotoSansCJKsc-Black.otf#Noto Sans CJK SC"
                                TextWrapping="Wrap"
                                LineStackingStrategy="BlockLineHeight"
                                LineHeight="49" Width="48"
                                Height="auto"/>
                </Grid>
            </DataTemplate>
        </Pivot.HeaderTemplate>

        <PivotItem Header="评论" Margin="83,-47,0,0" Background="Yellow">
            <Grid>
                <ListView x:Name="listview" d:LayoutOverrides="TopPosition, BottomPosition" ItemTemplate="{StaticResource GroupTemplate}" ItemsSource="{Binding Groups}" Margin="10,0,0,0"/>
            </Grid>
        </PivotItem>
        <PivotItem Header="转发" Margin="93,-47,0,0" Background="Yellow">
            <Grid>
                <ListView x:Name="listview2" d:LayoutOverrides="TopPosition, BottomPosition" ItemTemplate="{StaticResource GroupTemplate}" ItemsSource="{Binding Groups}"/>
            </Grid>
        </PivotItem>
    </Pivot>

For your first question, you have customize the style of the Pivot control, your gesture shown above works fine on the mobile emulator, but not on the local machine. This is the problem about ManipulationMode in the design of a Pivot control. Pivot control's Gesture is achieved inside it's style, so it is possible to manipulate it in one direction, but we need to find the key point in the style.

You can use Manipulation to do this. You can modify your style of Pivot control like this:

<PivotPanel x:Name="Panel" VerticalAlignment="Stretch">
    <PivotHeaderPanel x:Name="Header" ManipulationMode="None">
        <PivotHeaderPanel.RenderTransform>
            <CompositeTransform x:Name="HeaderTranslateTransform" TranslateX="0" />
        </PivotHeaderPanel.RenderTransform>
    </PivotHeaderPanel>
    <ItemsPresenter x:Name="PivotItemPresenter" ManipulationMode="None">
        <ItemsPresenter.RenderTransform>
            <TranslateTransform x:Name="ItemsPresenterTranslateTransform" X="0" />
        </ItemsPresenter.RenderTransform>
    </ItemsPresenter>
</PivotPanel>

and use this Pivot control like this:

<Pivot Style="{StaticResource PivotStyle1}" x:Name="myPivot" ManipulationMode="TranslateX" ManipulationStarting="OnStarting" ManipulationCompleted="OnCompleted">
   ...
</Pivot>

And the code behind:

public double pointx1;

private void OnCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
    var pointx2 = Window.Current.CoreWindow.PointerPosition.X;
    if (pointx2 > pointx1)
    {
        if (myPivot.SelectedIndex == 0)
            myPivot.SelectedIndex = 1;
        else
            myPivot.SelectedIndex = 0;
    }
    else
        return;
}

private void OnStarting(object sender, ManipulationStartingRoutedEventArgs e)
{
    pointx1 = Window.Current.CoreWindow.PointerPosition.X;
}

Here is also a workaround method to solve this problem, consider that there is no manipulation in the style of Pivot , you can achieve this using PointerPoint you can modify your style of Pivot control like this:

<PivotPanel x:Name="Panel" VerticalAlignment="Stretch" ManipulationMode="None">
    <PivotHeaderPanel x:Name="Header">
        <PivotHeaderPanel.RenderTransform>
            <CompositeTransform x:Name="HeaderTranslateTransform" TranslateX="0" />
        </PivotHeaderPanel.RenderTransform>
    </PivotHeaderPanel>
    <ItemsPresenter x:Name="PivotItemPresenter">
        <ItemsPresenter.RenderTransform>
            <TranslateTransform x:Name="ItemsPresenterTranslateTransform" X="0" />
        </ItemsPresenter.RenderTransform>
    </ItemsPresenter>
</PivotPanel>

and use this Pivot control like this:

<Pivot Style="{StaticResource PivotStyle1}" PointerReleased="OnPointerExited" PointerPressed="OnPointerPressed" x:Name="myPivot">
  ...
</Pivot>

And the code behind:

public PointerPoint pointer1;

private void OnPointerExited(object sender, PointerRoutedEventArgs e)
{
    var pointer2 = e.GetCurrentPoint(myPivot);
    var position1x = pointer1.Position.X;
    var position2x = pointer2.Position.X;
    if (position2x > position1x)
    {
        if (myPivot.SelectedIndex == 0)
            myPivot.SelectedIndex = 1;
        else
            myPivot.SelectedIndex = 0;
    }
    else
        return;
}

private void OnPointerPressed(object sender, PointerRoutedEventArgs e)
{
    pointer1 = e.GetCurrentPoint(myPivot);
}

And for your second question, as @ganchito55 said, you can modify the style of PivotHeaderItem .

Update:

If you just don't want to see the header of the other item when you manipulate it, you can modify the PivotHeaderItem like this:

......
<Setter Property="FontWeight" Value="{ThemeResource PivotHeaderItemThemeFontWeight}" />
<Setter Property="CharacterSpacing" Value="{ThemeResource PivotHeaderItemCharacterSpacing}" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="Transparent" />
<Setter Property="Padding" Value="{ThemeResource PivotHeaderItemMargin}" />
<Setter Property="Height" Value="48" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="IsTabStop" Value="False" />

......

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM