Подтвердить что ты не робот

Добавление жестов салфетки для открытия панели SplitView

Я пытаюсь добавить жестом салфетки в элемент управления SplitView (иначе называемый "меню гамбургера" ) UWP, похожий на прокрутку влево/вправо элемента управления Pivot. Как я могу установить жест, чтобы изменить режим отображения?

В iOS 8 и более поздних версиях я могу использовать UISplitViewController и установить для свойства presentationWithGesture значение, но в WinRT ничего подобного не наблюдается.

Теперь, прочитав этот блог: http://blogs.msdn.com/b/cdndevs/archive/2015/07/10/uwp-new-controls-part-2-splitview.aspx, я понял, что в элементе управления SplitView есть свойство DisplayMode, и я должен использовать VisualStateManager для изменения состояние его Но как я могу использовать vsm для панорамирования левой панели и выхода? Я не знаю, что это возможно с помощью vsm.

Приветствуем любую помощь/подсказку.

4b9b3361

Ответ 1

Интересный вопрос!:)

Недавно я создал 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>

При обновлении объекта 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 sync the PaneRoot 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();
    }
}

Имейте в виду, что поскольку свойство IsPaneOpen не является виртуальным, мне нужно создать еще один IsSwipeablePaneOpen, чтобы обернуть его вокруг. Поэтому всякий раз, когда вы хотите использовать свойство IsPaneOpen, используйте IsSwipeablePaneOpen.

Вот как это работает в демонстрационном приложении, которое я создал в GitHub. Вы можете найти полный исходный код здесь.

введите описание изображения здесь


Кредиты

Ответ 2

Ну, vsm используется для создания адаптивного интерфейса в этом блоге. Чтобы добавить жестов в SplitView, вот что я сделал:

  • Обнаружение жестов на корневой панели содержимого SplitView и добавление в него обработчика событий Manipulatioin.
  • Расположить свойство SplitView IsPaneOpen в событии Manipulation.