10、Windows10 上,在窗口左侧向右滑动打开 SplitView 的 Pane面板

时间:2022-12-11 17:25:51

  昨天想在 uwp 上实现,在 SplitView 控件的左侧,通过手指滑动打开 SplitView 的 Pane 面板,

而不仅仅是通过 “汉堡按钮” 点击打开。

  在 * 看到一个帖子, 有讨论一个方案,然后看了一下里面的一个 github 工程,实现了

SwipeableSplitView(工程连接), 不过下载代码分析了一下,代码量太大,通过继承 SplitView 控件,添加很多 xaml 和

C# 代码,有点复杂了。于是想了一个简单的方式,直接控制 SplitView 中 Template 的  CompositeTransform 和

VisualTransition 属性就可以了,几十行 C# 代码就能搞定。

1、运行效果 (VS2015 创建的 win10 UWP 工程)

  1)在 phone上:

10、Windows10 上,在窗口左侧向右滑动打开 SplitView 的 Pane面板

  2)在 win10 pc 上:

10、Windows10 上,在窗口左侧向右滑动打开 SplitView 的 Pane面板

2、分析 SplitView 控件的模板(只用来分析,并不使用)

  1)在空白页面中,添加一个 SplitView,在文档大纲中,右键单击 SplitView 控件,选择编辑副本:

    10、Windows10 上,在窗口左侧向右滑动打开 SplitView 的 Pane面板

  2)在生成的代码中,可以看到,当前 SplitView 控件的组成部分:

  这里重点使用 PaneRoot 中的 PaneTransform 属性,和 视觉状态属性中的  VisualTransition From="Closed" To="OpenOverlayLeft" 属性。

10、Windows10 上,在窗口左侧向右滑动打开 SplitView 的 Pane面板

  

   VS 所有生成的 SplitView 的  Template 代码:

   <ControlTemplate x:Key="SplitViewControlTemplate1" TargetType="SplitView">
<Grid Background="{TemplateBinding Background}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="DisplayModeStates">
<VisualStateGroup.Transitions>
<VisualTransition From="Closed" To="OpenOverlayLeft">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PaneRoot" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HCPaneBorder" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="PaneTransform" Storyboard.TargetProperty="TranslateX">
<DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="{Binding TemplateSettings.NegativeOpenPaneLength, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.35" KeySpline="0.1,0.9 0.2,1.0" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="PaneClipRectangleTransform" Storyboard.TargetProperty="TranslateX">
<DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="{Binding TemplateSettings.OpenPaneLength, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.35" KeySpline="0.1,0.9 0.2,1.0" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="LightDismissLayer" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>
<VisualTransition From="Closed" To="OpenOverlayRight">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PaneRoot" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PaneRoot" Storyboard.TargetProperty="HorizontalAlignment">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Right"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HCPaneBorder" Storyboard.TargetProperty="HorizontalAlignment">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Left"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HCPaneBorder" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="PaneTransform" Storyboard.TargetProperty="TranslateX">
<DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="{Binding TemplateSettings.OpenPaneLength, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.35" KeySpline="0.1,0.9 0.2,1.0" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="PaneClipRectangleTransform" Storyboard.TargetProperty="TranslateX">
<DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="{Binding TemplateSettings.NegativeOpenPaneLength, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.35" KeySpline="0.1,0.9 0.2,1.0" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="LightDismissLayer" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>
<VisualTransition From="ClosedCompactLeft" To="OpenCompactOverlayLeft">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ColumnDefinition1" Storyboard.TargetProperty="Width">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{Binding TemplateSettings.CompactPaneGridLength, FallbackValue=0, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="(Grid.Column)">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="1"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="(Grid.ColumnSpan)">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="1"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PaneRoot" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HCPaneBorder" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="PaneClipRectangleTransform" Storyboard.TargetProperty="TranslateX">
<DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="{Binding TemplateSettings.NegativeOpenPaneLengthMinusCompactLength, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.35" KeySpline="0.1,0.9 0.2,1.0" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="LightDismissLayer" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>
<VisualTransition From="ClosedCompactRight" To="OpenCompactOverlayRight">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ColumnDefinition1" Storyboard.TargetProperty="Width">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="*"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ColumnDefinition2" Storyboard.TargetProperty="Width">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{Binding TemplateSettings.CompactPaneGridLength, FallbackValue=0, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="(Grid.ColumnSpan)">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="1"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PaneRoot" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PaneRoot" Storyboard.TargetProperty="HorizontalAlignment">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Right"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HCPaneBorder" Storyboard.TargetProperty="HorizontalAlignment">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Left"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HCPaneBorder" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="PaneClipRectangleTransform" Storyboard.TargetProperty="TranslateX">
<DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="{Binding TemplateSettings.OpenPaneLengthMinusCompactLength, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.35" KeySpline="0.1,0.9 0.2,1.0" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="LightDismissLayer" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>
<VisualTransition From="OpenOverlayLeft" To="Closed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PaneRoot" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HCPaneBorder" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="PaneTransform" Storyboard.TargetProperty="TranslateX">
<SplineDoubleKeyFrame KeyTime="0:0:0.12" KeySpline="0.1,0.9 0.2,1.0" Value="{Binding TemplateSettings.NegativeOpenPaneLength, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="PaneClipRectangleTransform" Storyboard.TargetProperty="TranslateX">
<SplineDoubleKeyFrame KeyTime="0:0:0.12" KeySpline="0.1,0.9 0.2,1.0" Value="{Binding TemplateSettings.OpenPaneLength, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>
<VisualTransition From="OpenOverlayRight" To="Closed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PaneRoot" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PaneRoot" Storyboard.TargetProperty="HorizontalAlignment">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Right"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HCPaneBorder" Storyboard.TargetProperty="HorizontalAlignment">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Left"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HCPaneBorder" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="PaneTransform" Storyboard.TargetProperty="TranslateX">
<SplineDoubleKeyFrame KeyTime="0:0:0.12" KeySpline="0.1,0.9 0.2,1.0" Value="{Binding TemplateSettings.OpenPaneLength, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="PaneClipRectangleTransform" Storyboard.TargetProperty="TranslateX">
<SplineDoubleKeyFrame KeyTime="0:0:0.12" KeySpline="0.1,0.9 0.2,1.0" Value="{Binding TemplateSettings.NegativeOpenPaneLength, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>
<VisualTransition From="OpenCompactOverlayLeft" To="ClosedCompactLeft">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ColumnDefinition1" Storyboard.TargetProperty="Width">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{Binding TemplateSettings.CompactPaneGridLength, FallbackValue=0, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="(Grid.Column)">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="1"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="(Grid.ColumnSpan)">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="1"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PaneRoot" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HCPaneBorder" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="PaneClipRectangleTransform" Storyboard.TargetProperty="TranslateX">
<DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="0"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.12" KeySpline="0.1,0.9 0.2,1.0" Value="{Binding TemplateSettings.NegativeOpenPaneLengthMinusCompactLength, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>
<VisualTransition From="OpenCompactOverlayRight" To="ClosedCompactRight">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ColumnDefinition1" Storyboard.TargetProperty="Width">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="*"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ColumnDefinition2" Storyboard.TargetProperty="Width">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{Binding TemplateSettings.CompactPaneGridLength, FallbackValue=0, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="(Grid.ColumnSpan)">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="1"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PaneRoot" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PaneRoot" Storyboard.TargetProperty="HorizontalAlignment">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Right"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HCPaneBorder" Storyboard.TargetProperty="HorizontalAlignment">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Left"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HCPaneBorder" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="PaneClipRectangleTransform" Storyboard.TargetProperty="TranslateX">
<DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="0"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.12" KeySpline="0.1,0.9 0.2,1.0" Value="{Binding TemplateSettings.OpenPaneLengthMinusCompactLength, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>
</VisualStateGroup.Transitions>
<VisualState x:Name="Closed"/>
<VisualState x:Name="ClosedCompactLeft">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ColumnDefinition1" Storyboard.TargetProperty="Width">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{Binding TemplateSettings.CompactPaneGridLength, FallbackValue=0, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="(Grid.Column)">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="1"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="(Grid.ColumnSpan)">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="1"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PaneRoot" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation Storyboard.TargetName="PaneClipRectangleTransform" Storyboard.TargetProperty="TranslateX" To="{Binding TemplateSettings.NegativeOpenPaneLengthMinusCompactLength, RelativeSource={RelativeSource Mode=TemplatedParent}}" Duration="0:0:0"/>
</Storyboard>
</VisualState>
<VisualState x:Name="ClosedCompactRight">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ColumnDefinition1" Storyboard.TargetProperty="Width">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="*"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ColumnDefinition2" Storyboard.TargetProperty="Width">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{Binding TemplateSettings.CompactPaneGridLength, FallbackValue=0, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="(Grid.ColumnSpan)">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="1"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PaneRoot" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PaneRoot" Storyboard.TargetProperty="(Grid.ColumnSpan)">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="2"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PaneRoot" Storyboard.TargetProperty="HorizontalAlignment">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Right"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation Storyboard.TargetName="PaneClipRectangleTransform" Storyboard.TargetProperty="TranslateX" To="{Binding TemplateSettings.OpenPaneLengthMinusCompactLength, RelativeSource={RelativeSource Mode=TemplatedParent}}" Duration="0:0:0"/>
</Storyboard>
</VisualState>
<VisualState x:Name="OpenOverlayLeft">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PaneRoot" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HCPaneBorder" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="LightDismissLayer" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="OpenOverlayRight">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PaneRoot" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PaneRoot" Storyboard.TargetProperty="HorizontalAlignment">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Right"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HCPaneBorder" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HCPaneBorder" Storyboard.TargetProperty="HorizontalAlignment">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Left"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="LightDismissLayer" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="OpenInlineLeft">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="(Grid.Column)">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="1"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="(Grid.ColumnSpan)">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="1"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PaneRoot" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PaneRoot" Storyboard.TargetProperty="(Grid.ColumnSpan)">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="1"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HCPaneBorder" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="OpenInlineRight">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ColumnDefinition1" Storyboard.TargetProperty="Width">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="*"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ColumnDefinition2" Storyboard.TargetProperty="Width">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{Binding TemplateSettings.OpenPaneGridLength, FallbackValue=0, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="(Grid.ColumnSpan)">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="1"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PaneRoot" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PaneRoot" Storyboard.TargetProperty="(Grid.Column)">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="1"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PaneRoot" Storyboard.TargetProperty="(Grid.ColumnSpan)">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="1"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HCPaneBorder" Storyboard.TargetProperty="HorizontalAlignment">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Left"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HCPaneBorder" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="OpenCompactOverlayLeft">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ColumnDefinition1" Storyboard.TargetProperty="Width">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{Binding TemplateSettings.CompactPaneGridLength, FallbackValue=0, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="(Grid.Column)">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="1"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="(Grid.ColumnSpan)">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="1"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PaneRoot" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HCPaneBorder" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="LightDismissLayer" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="OpenCompactOverlayRight">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ColumnDefinition1" Storyboard.TargetProperty="Width">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="*"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ColumnDefinition2" Storyboard.TargetProperty="Width">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{Binding TemplateSettings.CompactPaneGridLength, FallbackValue=0, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="(Grid.ColumnSpan)">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="1"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PaneRoot" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PaneRoot" Storyboard.TargetProperty="HorizontalAlignment">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Right"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HCPaneBorder" Storyboard.TargetProperty="HorizontalAlignment">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Left"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HCPaneBorder" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="LightDismissLayer" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups> <Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ColumnDefinition1" Width="{Binding TemplateSettings.OpenPaneGridLength, FallbackValue=0, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
<ColumnDefinition x:Name="ColumnDefinition2" Width="*"/>
</Grid.ColumnDefinitions> <!-- Content Area -->
<Grid x:Name="ContentRoot" Grid.ColumnSpan="2">
<Border Child="{TemplateBinding Content}"/>
<Rectangle x:Name="LightDismissLayer" Fill="Transparent" Visibility="Collapsed"/>
</Grid> <!-- Pane Content Area-->
<Grid
x:Name="PaneRoot"
Grid.ColumnSpan="2"
HorizontalAlignment="Left"
Visibility="Collapsed"
Background="{TemplateBinding PaneBackground}"
Width="{Binding TemplateSettings.OpenPaneLength, RelativeSource={RelativeSource Mode=TemplatedParent}}">
<Grid.Clip>
<RectangleGeometry x:Name="PaneClipRectangle">
<RectangleGeometry.Transform>
<CompositeTransform x:Name="PaneClipRectangleTransform"/>
</RectangleGeometry.Transform>
</RectangleGeometry>
</Grid.Clip>
<Grid.RenderTransform>
<CompositeTransform x:Name="PaneTransform"/>
</Grid.RenderTransform>
<Border Child="{TemplateBinding Pane}"/>
<Rectangle
x:Name="HCPaneBorder"
x:DeferLoadStrategy="Lazy"
Visibility="Collapsed"
Fill="{ThemeResource SystemControlForegroundTransparentBrush}"
Width="1"
HorizontalAlignment="Right"/>
</Grid>
</Grid>
</ControlTemplate>

3、在 xaml 页面中,添加一个 Border 控件,显示在窗口的最左侧,检测用户的滑动手势

 <!--屏幕左侧手势检测区域, 在实际代码中可以把 Opacity 设置为 0 -->
<Border Grid.RowSpan="2"
ManipulationMode="TranslateX"
ManipulationCompleted="Border_ManipulationCompleted"
ManipulationDelta="Border_ManipulationDelta"
Width="36" Opacity=".5" Background="Green" HorizontalAlignment="Left"/>

  通过注册 Manipulation 事件,可以检测底层触摸事件。这个 Border 即为上面 gif 图片中,绿色的部分。

  MainPage.xaml 页面中,全部的 xaml :

<Page
x:Class="SwipeableSplitView.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SwipeableSplitView"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" RequestedTheme="Light"> <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" >
<SplitView x:Name="MySplitView"
DisplayMode="CompactInline"
IsPaneOpen="True"
IsTabStop="False" PaneBackground="#88440000" Loaded="MySplitView_Loaded" CompactPaneLength="88" OpenPaneLength="280" > <SplitView.Pane>
<ListView Margin="0,60,0,0">
<ListView.Resources>
<Style TargetType="StackPanel">
<Setter Property="Orientation" Value="Horizontal"/>
<Setter Property="Margin" Value="20,20"/>
</Style>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="50,0,0,0"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontSize" Value="22"/>
</Style>
<Style TargetType="FontIcon">
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontSize" Value="30"/>
</Style>
</ListView.Resources>
<StackPanel>
<FontIcon Glyph=""/>
<TextBlock Text="页面 1 "/>
</StackPanel>
<StackPanel>
<FontIcon Glyph="" />
<TextBlock Text="页面 2 "/>
</StackPanel>
<StackPanel>
<FontIcon Glyph=""/>
<TextBlock Text="页面 3 "/>
</StackPanel>
</ListView> </SplitView.Pane>
<Grid>
<!--<Frame/>-->
<TextBlock Text="当窗口宽度最小时,通过鼠标或者手指,从窗口最左侧向右滑动,则打开 SplitView.Pane " Width="250" FontSize="30" TextWrapping="Wrap" HorizontalAlignment="Center" VerticalAlignment="Center"/> <!--屏幕左侧手势检测区域, 在实际代码中可以把 Opacity 设置为 0 -->
<Border Grid.RowSpan="2"
ManipulationMode="TranslateX"
ManipulationCompleted="Border_ManipulationCompleted"
ManipulationDelta="Border_ManipulationDelta"
Width="36" Opacity=".5" Background="Green" HorizontalAlignment="Left"/> <!--显示 Debug 数据-->
<Border HorizontalAlignment="Right" Margin="20" Background="Gray" VerticalAlignment="Top">
<TextBlock x:Name="txtDebug" Text="debug" FontSize="30" Foreground="GreenYellow" Margin="10"/>
</Border>
</Grid>
</SplitView> <!--汉堡按钮-->
<CheckBox IsChecked="{Binding IsPaneOpen,ElementName=MySplitView, Mode=TwoWay}" IsThreeState="False" Height="40" Width="40" VerticalAlignment="Top" HorizontalAlignment="Left" Style="{StaticResource CheckBoxStyle1}">
<FontIcon Glyph="" Foreground="White" FontSize="25" />
</CheckBox> <VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="visualState">
<VisualState x:Name="wide">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="1024" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="MySplitView.DisplayMode" Value="CompactInline" />
<Setter Target="MySplitView.IsPaneOpen" Value="True" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="meddium">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="548" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="MySplitView.DisplayMode" Value="CompactInline" />
<Setter Target="MySplitView.IsPaneOpen" Value="False" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="narrow">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="MySplitView.DisplayMode" Value="Overlay" />
<Setter Target="MySplitView.IsPaneOpen" Value="False" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</Page>

4、在 MainPage.xaml.cs 页面中

  1)分析:当 SplitView.IsPaneOpen 设置为 true 时, Pane 的 CompositeTransform 的 TranslateX 的数值变化

  在 SplitView 的 Loaded 事件中,把数值打印出来:

        // Debug 数据输出,左侧面板 TranslateX 的变化
private void MySplitView_Loaded(object sender, RoutedEventArgs e)
{
#if DEBUG
Grid
grid = Utility.FindVisualChild<Grid>(MySplitView); Binding bind = new Binding();
bind.Path = new PropertyPath("TranslateX");
bind.Source = (grid.FindName("PaneRoot") as Grid).RenderTransform as CompositeTransform; // 显示到 TextBlock 上
txtDebug.SetBinding(TextBlock.TextProperty, bind); txtDebug.RegisterPropertyChangedCallback(TextBlock.TextProperty, (dependencyObject, dependencyProperty) =>
{
// 注册 TextBlock.TextProperty 属性回调事件,显示到输出窗口
Debug.WriteLine("txtDebug.Text ; " + txtDebug.Text);
});
#endif
}

  在窄窗口模式下,点击 汉堡按钮,查看输出窗口,数值从 280 (SplitView.OpenPaneLength)变为 0:

txtDebug.Text : -
txtDebug.Text : -279.996
txtDebug.Text : -220.397
txtDebug.Text : -160.79
txtDebug.Text : -101.138
txtDebug.Text : -65.0658
txtDebug.Text : -51.9964
txtDebug.Text : -38.9144
txtDebug.Text : -25.5251
txtDebug.Text : -20.8821
txtDebug.Text : -16.2444
txtDebug.Text : -11.6015
txtDebug.Text : -8.4631
txtDebug.Text : -6.61891
txtDebug.Text : -4.77503
txtDebug.Text : -2.93104
txtDebug.Text : -2.2662
txtDebug.Text : -1.57674
txtDebug.Text : -0.157382
txtDebug.Text :

  结合 VisualState 中 <VisualTransition From="Closed" To="OpenOverlayLeft"> 节点,

在 0秒到 0:0:0.35 秒时,PaneRoot 由 “隐藏”变为“显示”,并且它的 TranslateX 由 OpenPaneLength

变为 0 :

<VisualTransition From="Closed" To="OpenOverlayLeft">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PaneRoot" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HCPaneBorder" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="PaneTransform" Storyboard.TargetProperty="TranslateX">
<DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="{Binding TemplateSettings.NegativeOpenPaneLength, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.35" KeySpline="0.1,0.9 0.2,1.0" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="PaneClipRectangleTransform" Storyboard.TargetProperty="TranslateX">
<DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="{Binding TemplateSettings.OpenPaneLength, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.35" KeySpline="0.1,0.9 0.2,1.0" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="LightDismissLayer" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>

  2) 添加 C# 中的逻辑,加了注释

        #region  从屏幕左侧边缘滑动屏幕时,打开 SplitView 菜单

        // SplitView 控件模板中,Pane部分的 Grid
Grid PaneRoot; // 引用 SplitView 控件中, 保存从 Pane “关闭” 到“打开”的 VisualTransition
// 也就是 <VisualTransition From="Closed" To="OpenOverlayLeft"> 这个
VisualTransition from_ClosedToOpenOverlayLeft_Transition; private void Border_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
e.Handled = true; // 仅当 SplitView 处于 Overlay 模式时(窗口宽度最小时)
if (MySplitView.DisplayMode == SplitViewDisplayMode.Overlay)
{
if (PaneRoot == null)
{
// 找到 SplitView 控件中,模板的父容器
Grid grid = Utility.FindVisualChild<Grid>(MySplitView); PaneRoot = grid.FindName("PaneRoot") as Grid; if (from_ClosedToOpenOverlayLeft_Transition == null)
{
// 获取 SplitView 模板中“视觉状态集合”
IList<VisualStateGroup> stateGroup = VisualStateManager.GetVisualStateGroups(grid); // 获取 VisualTransition 对象的集合。
IList<VisualTransition> transitions = stateGroup[].Transitions; // 找到 SplitView.IsPaneOpen 设置为 true 时,播放的 transition
from_ClosedToOpenOverlayLeft_Transition = transitions?.Where(train => train.From == "Closed" && train.To == "OpenOverlayLeft").First(); // 遍历所有 transitions,打印到输出窗口
foreach (var tran in transitions)
{
Debug.WriteLine("From : " + tran.From + " To : " + tran.To);
}
}
} // 默认为 Collapsed,所以先显示它
PaneRoot.Visibility = Visibility.Visible; // 当在 Border 上向右滑动,并且滑动的总距离需要小于 Panel 的默认宽度。否则会脱离左侧窗口,继续向右拖动
if (e.Cumulative.Translation.X >= && e.Cumulative.Translation.X < MySplitView.OpenPaneLength)
{
CompositeTransform ct = PaneRoot.RenderTransform as CompositeTransform;
ct.TranslateX = (e.Cumulative.Translation.X - MySplitView.OpenPaneLength);
}
}
} private void Border_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
e.Handled = true; // 仅当 SplitView 处于 Overlay 模式时(窗口宽度最小时)
if (MySplitView.DisplayMode == SplitViewDisplayMode.Overlay && PaneRoot != null)
{
// 因为当 IsPaneOpen 为 true 时,会通过 VisualStateManager 把 PaneRoot.Visibility 设置为
// Visibility.Visible,所以这里把它改为 Visibility.Collapsed,以回到初始状态
PaneRoot.Visibility = Visibility.Collapsed; // 恢复初始状态
CompositeTransform ct = PaneRoot.RenderTransform as CompositeTransform; // 如果大于 MySplitView.OpenPaneLength 宽度的 1/2 ,则显示,否则隐藏
if ((MySplitView.OpenPaneLength + ct.TranslateX) > MySplitView.OpenPaneLength / )
{
MySplitView.IsPaneOpen = true; // 因为上面设置 IsPaneOpen = true 会再次播放向右滑动的动画,所以这里使用 SkipToFill()
// 方法,直接跳到动画结束状态
from_ClosedToOpenOverlayLeft_Transition?.Storyboard?.SkipToFill(); } ct.TranslateX = ;
}
}
#endregion

  MainPage.xaml.cs 页面中,全部的 C# :

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation; namespace SwipeableSplitView
{
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
} // Debug 数据输出,左侧面板 TranslateX 的变化
private void MySplitView_Loaded(object sender, RoutedEventArgs e)
{
#if DEBUG
Grid grid = Utility.FindVisualChild<Grid>(MySplitView); Binding bind = new Binding();
bind.Path = new PropertyPath("TranslateX");
bind.Source = (grid.FindName("PaneRoot") as Grid).RenderTransform as CompositeTransform; // 显示到 TextBlock 上
txtDebug.SetBinding(TextBlock.TextProperty, bind); txtDebug.RegisterPropertyChangedCallback(TextBlock.TextProperty, (dependencyObject, dependencyProperty) =>
{
// 注册 TextBlock.TextProperty 属性回调事件,显示到输出窗口
Debug.WriteLine("txtDebug.Text : " + txtDebug.Text);
});
#endif
} #region 从屏幕左侧边缘滑动屏幕时,打开 SplitView 菜单 // SplitView 控件模板中,Pane部分的 Grid
Grid PaneRoot; // 引用 SplitView 控件中, 保存从 Pane “关闭” 到“打开”的 VisualTransition
// 也就是 <VisualTransition From="Closed" To="OpenOverlayLeft"> 这个
VisualTransition from_ClosedToOpenOverlayLeft_Transition; private void Border_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
e.Handled = true; // 仅当 SplitView 处于 Overlay 模式时(窗口宽度最小时)
if (MySplitView.DisplayMode == SplitViewDisplayMode.Overlay)
{
if (PaneRoot == null)
{
// 找到 SplitView 控件中,模板的父容器
Grid grid = Utility.FindVisualChild<Grid>(MySplitView); PaneRoot = grid.FindName("PaneRoot") as Grid; if (from_ClosedToOpenOverlayLeft_Transition == null)
{
// 获取 SplitView 模板中“视觉状态集合”
IList<VisualStateGroup> stateGroup = VisualStateManager.GetVisualStateGroups(grid); // 获取 VisualTransition 对象的集合。
IList<VisualTransition> transitions = stateGroup[].Transitions; // 找到 SplitView.IsPaneOpen 设置为 true 时,播放的 transition
from_ClosedToOpenOverlayLeft_Transition = transitions?.Where(train => train.From == "Closed" && train.To == "OpenOverlayLeft").First(); // 遍历所有 transitions,打印到输出窗口
foreach (var tran in transitions)
{
Debug.WriteLine("From : " + tran.From + " To : " + tran.To);
}
}
} // 默认为 Collapsed,所以先显示它
PaneRoot.Visibility = Visibility.Visible; // 当在 Border 上向右滑动,并且滑动的总距离需要小于 Panel 的默认宽度。否则会脱离左侧窗口,继续向右拖动
if (e.Cumulative.Translation.X >= && e.Cumulative.Translation.X < MySplitView.OpenPaneLength)
{
CompositeTransform ct = PaneRoot.RenderTransform as CompositeTransform;
ct.TranslateX = (e.Cumulative.Translation.X - MySplitView.OpenPaneLength);
}
}
} private void Border_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
e.Handled = true; // 仅当 SplitView 处于 Overlay 模式时(窗口宽度最小时)
if (MySplitView.DisplayMode == SplitViewDisplayMode.Overlay && PaneRoot != null)
{
// 因为当 IsPaneOpen 为 true 时,会通过 VisualStateManager 把 PaneRoot.Visibility 设置为
// Visibility.Visible,所以这里把它改为 Visibility.Collapsed,以回到初始状态
PaneRoot.Visibility = Visibility.Collapsed; // 恢复初始状态
CompositeTransform ct = PaneRoot.RenderTransform as CompositeTransform; // 如果大于 MySplitView.OpenPaneLength 宽度的 1/2 ,则显示,否则隐藏
if ((MySplitView.OpenPaneLength + ct.TranslateX) > MySplitView.OpenPaneLength / )
{
MySplitView.IsPaneOpen = true; // 因为上面设置 IsPaneOpen = true 会再次播放向右滑动的动画,所以这里使用 SkipToFill()
// 方法,直接跳到动画结束状态
from_ClosedToOpenOverlayLeft_Transition?.Storyboard?.SkipToFill(); } ct.TranslateX = ;
}
}
#endregion
}
}

  

  常用的视图帮助类 Utility:  

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml; namespace SwipeableSplitView
{
/// <summary>
/// 视觉状态 工具类
/// </summary>
static partial class Utility
{
public static T FindVisualChild<T>(DependencyObject obj) where T : DependencyObject
{
int count = Windows.UI.Xaml.Media.VisualTreeHelper.GetChildrenCount(obj);
for (int i = ; i < count; i++)
{
DependencyObject child = Windows.UI.Xaml.Media.VisualTreeHelper.GetChild(obj, i);
if (child != null && child is T)
{
return (T)child;
}
else
{
T childOfChild = FindVisualChild<T>(child);
if (childOfChild != null)
return childOfChild;
}
} return null;
} public static VisualStateGroup FindVisualState(FrameworkElement element, string name)
{
if (element == null || string.IsNullOrWhiteSpace(name))
return null; IList<VisualStateGroup> groups = VisualStateManager.GetVisualStateGroups(element);
foreach (var group in groups)
{
if (group.Name == name)
return group;
} return null;
}
}
}

完。

SwipeableSplitView工程代码下载