关于C#:UWP上的数据透视控件自定义

Pivot control customization on UWP

基本上,我需要在uwp应用程序上自定义枢轴控件,并且使用Windows Phone 8.1中的枢轴样式。最终看起来像这样(黄色部分是数据透视表项的内容,我只是用颜色区分标题和内容)

enter image description here

但是现在它不能满足原始设计的要求。所以我在这里有两个问题:

1.如何限制用户向一个方向轻拂枢轴?例如,用户只能从左向右轻拂控件,因为如果枢轴从右向左轻拂,则黄色内容部分将移至左侧并覆盖标题。内容(即黄色部分)将完全与您的手指一起移动,并且将显示另一个覆盖的枢轴标题,因为您可以在图像上看到黄色部分的移开。这就是我关心滑动方向的原因,因为如果向左滑动,则在完成手势之前,黄色部分将覆盖标题的一部分(图像中未显示)。

2.如何更改未选中的pivotitem标头的前景色?如您所见,现在在轻拂过程中,黄色内容部分将移开,并且将显示未选择的标题。这看起来很奇怪,而且根本不是一个好的设计。假定未选择的页眉是透明的或与页面的背景色相同。

这是样式的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<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>

以及枢轴控件的XAML代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<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>


对于第一个问题,您已经自定义了Pivot控件的样式,上面显示的手势在移动仿真器上工作正常,但在本地计算机上工作不正常。这是Pivot控件设计中有关ManipulationMode的问题。 Pivot控件的手势是在其样式内实现的,因此可以在一个方向上对其进行操作,但是我们需要找到样式中的关键点。

您可以使用Manipulation执行此操作。您可以像这样修改Pivot控件的样式:

1
2
3
4
5
6
7
8
9
10
11
12
<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>

并使用如下的Pivot控件:

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

以及后面的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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;
}

这也是解决此问题的一种变通方法,考虑到Pivot样式中没有任何操作,可以使用PointerPoint实现此目的,您可以像这样修改Pivot控件的样式:

1
2
3
4
5
6
7
8
9
10
11
12
<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>

并使用如下的Pivot控件:

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

以及后面的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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);
}

关于第二个问题,正如@ ganchito55所说,您可以修改PivotHeaderItem的样式。

更新:

如果只是不想在操作时看到其他项目的标题,则可以这样修改PivotHeaderItem

1
2
3
4
5
6
7
8
9
10
11
......
<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" />

......