2015-08-20 3 views
19

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

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

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

Любая помощь/подсказка были бы весьма признательны.

ответ

37

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

Я недавно создал 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 «S, чтобы сохранить свои позиции в синхронизации.

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

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

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

enter image description here


Кредиты

  • Шаблон SplitView был создан из Koen Zwikstra является удивительным Visual Studio UWP templates.
  • Страница анимации и некоторые другие реализации были вдохновлены this post от Jerry Nixon.
+4

Удивительная работа с жестом! – Saurabh3321

+5

Недавно я обновил репо GitHub с помощью еще одной интересной функции - свойство IsPanSelectorEnabled, которое позволяет вам выбирать пункт меню путем панорамирования вверх/вниз в нижней области панели. Я считаю, что это поможет пользователям с большими телефонами, так как им не нужно растягивать пальцы, чтобы добраться до верхней области больше! Живая демонстрация: https://www.youtube.com/watch?v=K47MHJFe4dQ –

+0

Эй, Джастин, в наличии Управление сплитвью (режим наложения), вы испытываете какое-либо отставание во время слайд-анимации на реальном мобильном устройстве (сборка 10152), когда вы нажимаете кнопку гамбургера? – Saurabh3321

0

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

  • Detect жест на корневой панели Content SplitView, и добавить Manipulatioin Приглашена обработчик события этого.
  • Обработать свойство IsPaneOpen с помощью SplitView в событии Manipulation.
+5

Делитесь ссылкой, чувак! –

+0

[Это] (https://github.com/JuniperPhoton/HamburgerDemo) - это демо, которое я сделал несколько месяцев назад, чтобы продемонстрировать эту функцию. Это проект Windows Phone 8.1, и, конечно же, я не использовал SplitView для реализации этой функции. Вместо этого демо содержит элемент управления Pivot с некоторыми PivotItems и гамбургским меню, которое я сделал. – JuniperPhoton

+0

Эй, Джерри! @ JerryNixon-MSFT. Вы должны проверить мой ответ. :) –

Смежные вопросы