Интересный вопрос! :)
Я недавно создал 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.
Кредиты
- Шаблон SplitView был создан из Koen Zwikstra является удивительным Visual Studio UWP templates.
- Страница анимации и некоторые другие реализации были вдохновлены this post от Jerry Nixon.
Удивительная работа с жестом! – Saurabh3321
Недавно я обновил репо GitHub с помощью еще одной интересной функции - свойство IsPanSelectorEnabled, которое позволяет вам выбирать пункт меню путем панорамирования вверх/вниз в нижней области панели. Я считаю, что это поможет пользователям с большими телефонами, так как им не нужно растягивать пальцы, чтобы добраться до верхней области больше! Живая демонстрация: https://www.youtube.com/watch?v=K47MHJFe4dQ –
Эй, Джастин, в наличии Управление сплитвью (режим наложения), вы испытываете какое-либо отставание во время слайд-анимации на реальном мобильном устройстве (сборка 10152), когда вы нажимаете кнопку гамбургера? – Saurabh3321