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

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

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

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

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

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

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

  1)在 phone上:

  2)在 win10 pc 上:

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

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

    

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

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

  

   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工程代码下载

10、Windows10 上,在窗口左侧向右滑动打开 SplitView 的 Pane面板的更多相关文章

  1. Windows10 上运行Ubuntu Bash

    Windows10 上运行Ubuntu Bash 2016年4月6日,Windows 10 Insider Preview 发布的版本 14316,添加了Ubuntu Bash,在Windows上提供 ...

  2. windows10上安装mysql详细图文教程

    在windows10上安装mysql详细图文教程   这篇文章主要介绍了在windows10上安装mysql详细图文教程,本文介绍的非常详细,具有参考借鉴价值,感兴趣的朋友一起看看吧 环境:windw ...

  3. 背水一战 Windows 10 (4) - UI: 多窗口

    [源码下载] 背水一战 Windows 10 (4) - UI: 多窗口 作者:webabcd 介绍背水一战 Windows 10 之 UI 多窗口 示例1.自定义帮助类,用于简化 Secondary ...

  4. 孤荷凌寒自学python第六十天在windows10上搭建本地Mongodb数据服务

     孤荷凌寒自学python第六十天在windows10上找搭建本地Mongodb数据服务 (完整学习过程屏幕记录视频地址在文末) 今天是学习mongoDB数据库的第六天.成功在本地搭建了windows ...

  5. 背水一战 Windows 10 (101) - 应用间通信: 通过协议打开指定的 app 并传递数据以及获取返回数据, 将本 app 沙盒内的文件共享给其他 app 使用

    [源码下载] 背水一战 Windows 10 (101) - 应用间通信: 通过协议打开指定的 app 并传递数据以及获取返回数据, 将本 app 沙盒内的文件共享给其他 app 使用 作者:weba ...

  6. 在windows10上搭建caffe

    caffe环境的搭建一直是让我最头疼的,最近在Windows10上成功搭建了caffe,在此对搭建过程进行记录. 安装主要是按照caffe github上的安装说明进行的,caffe的github主页 ...

  7. TeamCity编译执行selenium上传窗口脚本缺陷

    2015-07-04 18:05 编写本文 TeamCity编译selenium脚本,对于上传窗口处理只支持sendKeys的使用,不支持模拟人为按下Enter键和使用autoIt等操作,即使本地调试 ...

  8. Window 10 Alt Tap 切换窗口,设置成Windows 7风格

    升级了Windows 10 以后,切换窗口非常的难受.新版的窗口切换的图标变成了窗口预览了,这总让我一瞬间找不到要去的窗口,所以我打算切换成Windows 7 的小图标风格. Windows + R ...

  9. Windows10上使用windbg调试Chromium Windows。

    ###目的###Windows10上使用windbg调试Chromium Windows. 安装Windows 10 SDK时, 就包含了windbg.exe."C:\Program Fil ...

随机推荐

  1. ES6 async await 面试题

    转自:https://juejin.im/post/5c0397186fb9a049b5068e54 1.题目一 async function async1(){ console.log('async ...

  2. java 实现文本格式转换

    代码如下,不太规范,仅作学习用 import java.io.*; public class CharSetTest { public static void main(String[] args) ...

  3. [转载]如何使用eclipse 生成runnable jar包

    步骤如下: 1.先找到你的工程中提供接口的类(要包含main方法). 2.在该类中右键选择 Run as. 3.选择 Run configurations. 4.在main窗口中选择main clas ...

  4. redis编译

    简介: Redis是Nosql中比较出名的,分布式数据库缓存,提升相应的速度,降低对数据库的访问! Redis是一种高级key-value数据库.它跟memcached类似,不过数据可以持久化,(永久 ...

  5. 【laravel5.4】发送alisms短信和163邮箱

    public function test() { $res=ClientSource::all(); //dd($res); echo "<br>"; /* 发送短信[ ...

  6. java项目中classpath路径到底指的是哪里?

    本文转自:http://blog.csdn.net/javaloveiphone/article/details/51994268 1.src不是classpath, WEB-INF/classes和 ...

  7. HDUOJ----Safecracker(1015)

    Safecracker Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Tota ...

  8. leetcode621 贪心:任务安排

    题目链接 给定26种任务,每种任务的数量已知. 相同任务之间必须间隔n个时间段,为了不足n个时间段,可以让及其休息. 问:最少需要多长时间才能处理完这些任务? 这道题用贪心策略解决:每次安排任务时,优 ...

  9. 马哥 Linux文本处理和文件查找 笔记

    grep: Global RE(Regular Expression) Printing文本过滤工具,能够实现根据指定的"模式(Pattern)"逐行搜索文件内容,并将匹配到的行显 ...

  10. &&和;和||符号的意思

    http://www.cnblogs.com/xuxm2007/archive/2011/01/16/1936836.html在命令行可以一次执行多个命令,有以下几种:   1.每个命令之间用;隔开 ...