添加滑动手势打开列SplitView窗格 [英] Adding a swipe gesture to open SplitView Pane

查看:545
本文介绍了添加滑动手势打开列SplitView窗格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想滑动手势添加到控制列SplitView UWP的(又名汉堡菜单),类似留下了枢轴控件/右轻扫。如何设置一个手势来改变它的显示模式?



在iOS 8的,后来,我可以使用UISplitViewController并设置presentsWithGesture属性来做到这一点,但没有类似的事情在WinRT中。



现在阅读这个博客后:的。的

  • 页动画和其他一些实现被的this帖子


  • I am trying to add a swipe gesture to the SplitView control (aka "hamburger menu") of UWP, similar to the swipe left/right of a Pivot control. How can I set a gesture to change the Display mode of it?

    In iOS 8 and later, I can use UISplitViewController and set presentsWithGesture property to do that but there is not a similar thing in WinRT.

    Now after reading this blog: http://blogs.msdn.com/b/cdndevs/archive/2015/07/10/uwp-new-controls-part-2-splitview.aspx, I realized that there is the DisplayMode property in SplitView control and I should use VisualStateManager to change the state of it But how can I use vsm to pan the left Pane in and out? I am not aware that this is achievable with vsm.

    Any help/hint would be greatly appreciated.

    解决方案

    Interesting question! :)

    I recently created a SwipeableSplitView which extends the SplitView control to enable a swipe from left edge gesture when the DisplayMode is set to Overlay (as I don't see the point to have it in other modes, but feel free to extend it whenever needed).

    All I am doing is, inside the control's style, create another layer on top of the PaneRoot layer and handle all the gestures there.

    <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>
    

    While updating the TranslateX of the new layer's transform object, I am also updating the PaneRoot's to keep their position in sync.

    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();
        }
    }
    

    Keep in mind that because the IsPaneOpen property is not virtual, I have to create another one IsSwipeablePaneOpen to wrap the former around. So whenever you feel like using the IsPaneOpen property, use IsSwipeablePaneOpen instead.

    This is how it works in a demo app I created in GitHub. You can find the full source code here.


    Credits

    • The SplitView template was generated from Koen Zwikstra's awesome Visual Studio UWP templates.
    • Page animations and some other implementations were inspired by this post from Jerry Nixon.

    这篇关于添加滑动手势打开列SplitView窗格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆