Dodawanie gestu machnięcia, aby otworzyć panel SplitView

Próbuję dodać gest machnięcia do kontrolki SplitView (aka "menu hamburgera") UWP, podobnie jak przesunięcie w lewo/prawo kontrolki obrotu. Jak ustawić gest, aby zmienić tryb wyświetlania?

W iOS 8 i nowszych, mogę użyć UISplitViewController i ustawić presentsWithGesture właściwość, aby to zrobić, ale nie ma podobnej rzeczy w WinRT.

Teraz po przeczytaniu tego bloga: http://blogs.msdn.com/b/cdndevs/archive/2015/07/10/uwp-new-controls-part-2-splitview.aspx , zdałem sobie sprawę, że istnieje właściwość DisplayMode w kontrolce SplitView i powinienem użyć VisualStateManager, aby zmienić jej stan, ale jak mogę użyć vsm, aby przesuwać lewy panel w I Na Zewnątrz? Nie jestem świadomy, że jest to osiągalne z vsm.

Każda pomoc / podpowiedź będzie bardzo mile widziana.

Author: BoltClock, 2015-08-20

2 answers

Ciekawe pytanie! :)

Niedawno stworzyłem SwipeableSplitView, który rozszerza kontrolkę SplitView, aby umożliwić przesunięcie od lewej krawędzi gest, gdy DisplayMode jest ustawiony na Overlay (ponieważ nie widzę sensu, aby mieć ją w innych trybach, ale możesz ją rozszerzyć w razie potrzeby).

Wszystko, co robię, to wewnątrz stylu kontrolki, utworzyć kolejną warstwę na wierzchu warstwy PaneRoot i obsługiwać wszystkie gesty tam.

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

Podczas aktualizacji TranslateX nowej warstwy przekształć obiekt, aktualizuję również PaneRoot ' s, aby utrzymać ich pozycję w synchronizacji.

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

Należy pamiętać, że ponieważ IsPaneOpen właściwość nie jest wirtualna, muszę utworzyć kolejną IsSwipeablePaneOpen, aby zawinąć tę pierwszą. Jeśli więc masz ochotę użyć właściwości IsPaneOpen, użyj IsSwipeablePaneOpen.

Tak to działa w aplikacji demo, którą stworzyłem w Githubie. Możesz znaleźć Pełny kod źródłowy tutaj .

Tutaj wpisz opis obrazka


Kredyty

  • szablon SplitView został wygenerowany z niesamowitych szablonów Visual Studio UWP Koen Zwikstra .
  • animacje stron i niektóre inne implementacje zostały zainspirowane przez ten post od Jerry ' ego Nixona.
 37
Author: Justin XL,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-20 06:20:00

Cóż, vsm jest używany do tworzenia responsywnego interfejsu użytkownika w tym blogu. Aby dodać gest machnięcia w SplitView, oto co zrobiłem:

  • Wykryj gest na głównym panelu zawartości SplitView i dodaj jakąś manipulację związaną z obsługą zdarzenia.
  • Obsługa właściwości Ispaneopen SplitView w zdarzeniu manipulacji.
 0
Author: JuniperPhoton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-20 02:35:21