添加滑动手势以打开SplitView窗格

iou*_*u90 21 c# windows-runtime winrt-xaml windows-10 uwp

我正在尝试向UWP的SplitView控件(又名"汉堡包菜单")添加滑动手势,类似于Pivot控件的左/右滑动.如何设置手势以更改其显示模式?

在iOS 8及更高版本中,我可以使用UISplitViewController并设置presentsWithGesture属性来做到这一点,但在WinRT中没有类似的东西.

现在看完这篇博客后:http://blogs.msdn.com/b/cdndevs/archive/2015/07/10/uwp-new-controls-part-2-splitview.aspx,我意识到有DisplayMode属性在SplitView控件中,我应该使用VisualStateManager来改变它的状态但是如何使用vsm来平移左侧窗格?我不知道这可以通过vsm实现.

任何帮助/提示将不胜感激.

Jus*_* XL 39

有趣的问题!:)

我最近创建了一个 SwipeableSplitView延伸的SplitView控制,以使从左侧边缘滑动手势时,DisplayMode被设置为Overlay(因为我不明白这一点有它在其它模式下,但随时需要的时候把它扩大).

我所做的就是,在控件的样式中,在PaneRoot图层顶部创建另一个图层并处理那里的所有手势.

<Grid x:Name="PaneRoot" ManipulationMode="TranslateX" Grid.ColumnSpan="2" HorizontalAlignment="Left" 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" TranslateX="{Binding RenderTransform.TranslateX, ElementName=PanArea}" />
    </Grid.RenderTransform>
    <Border Child="{TemplateBinding Pane}" />
    <Rectangle x:Name="HCPaneBorder" Fill="{ThemeResource SystemControlForegroundTransparentBrush}" HorizontalAlignment="Right" Visibility="Collapsed" Width="1" x:DeferLoadStrategy="Lazy" />
</Grid>

<!--a new layer here to handle all the gestures -->
<Grid x:Name="OverlayRoot" Grid.ColumnSpan="2">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="{Binding TemplateSettings.OpenPaneGridLength, RelativeSource={RelativeSource Mode=TemplatedParent}}" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <!--the actual element for panning, manipulations happen here-->
    <Rectangle x:Name="PanArea" Fill="Transparent" ManipulationMode="TranslateX" Width="{Binding PanAreaThreshold, RelativeSource={RelativeSource Mode=TemplatedParent}}" Grid.Column="1">
        <Rectangle.RenderTransform>
            <CompositeTransform TranslateX="{Binding PanAreaInitialTranslateX, RelativeSource={RelativeSource Mode=TemplatedParent}}" />
        </Rectangle.RenderTransform>
    </Rectangle>
    <!--this is used to dismiss this swipeable pane-->
    <Rectangle x:Name="DismissLayer" Fill="Transparent" Grid.Column="2" />
</Grid>
Run Code Online (Sandbox Code Playgroud)

在更新TranslateX新图层的变换对象时,我也会更新PaneRoot它们以保持其位置同步.

void OnManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
{
    _panAreaTransform = PanArea.RenderTransform as CompositeTransform;
    _paneRootTransform = PaneRoot.RenderTransform as CompositeTransform;

    if (_panAreaTransform == null || _paneRootTransform == null)
    {
        throw new ArgumentException("Make sure you have copied the default style to Generic.xaml!!");
    }
}

void OnManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
    var x = _panAreaTransform.TranslateX + e.Delta.Translation.X;

    // keep the pan within the bountry
    if (x < PanAreaInitialTranslateX || x > 0) return;

    // while we are panning the PanArea on X axis, let's sync the PaneRoot's position X too
    _paneRootTransform.TranslateX = _panAreaTransform.TranslateX = x;
}

void OnManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
    var x = e.Velocities.Linear.X;

    // ignore a little bit velocity (+/-0.1)
    if (x <= -0.1)
    {
        CloseSwipeablePane();
    }
    else if (x > -0.1 && x < 0.1)
    {
        if (Math.Abs(_panAreaTransform.TranslateX) > Math.Abs(PanAreaInitialTranslateX) / 2)
        {
            CloseSwipeablePane();
        }
        else
        {
            OpenSwipeablePane();
        }
    }
    else
    {
        OpenSwipeablePane();
    }
}
Run Code Online (Sandbox Code Playgroud)

请记住,因为该IsPaneOpen属性不是虚拟的,我必须创建另一个IsSwipeablePaneOpen来包装前者.因此,无论何时您想使用该IsPaneOpen物业,请使用IsSwipeablePaneOpen改用.

这就是我在GitHub中创建的演示应用程序中的工作方式.您可以在此处找到完整的源代码.

在此输入图像描述


积分

  • 我最近使用另一个很酷的功能更新了GitHub仓库 - 一个'IsPanSelectorEnabled`属性,它允许您通过在窗格底部区域上/下平移来选择菜单项.我相信这可以帮助使用大型手机的用户,因为他们不再需要伸出手指才能到达顶部区域!现场演示:https://www.youtube.com/watch?v = K47MHJFe4dQ (5认同)