如何在 Windows 10 UWP 中为 Grid 添加触摸操作事件?
How to add touch manipulation events for a Grid in Windows 10 UWP?
我目前正在研究 Windows 10,我想为用户添加滑动手势。所以我做了一些研究并发现了 Manipulation Events。我尝试了以下代码,但它在我使用鼠标指针时有效,而不是在使用触摸滑动手势时有效。
pageLayoutGrid.ManipulationMode = ManipulationModes.TranslateX;
pageLayoutGrid.ManipulationDelta += PageLayoutGrid_ManipulationDelta;
pageLayoutGrid.ManipulationCompleted += LayoutManipulationCompleted;
private void PageLayoutGrid_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
e.Handled = true;
}
private void LayoutManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
var velocities = e.Velocities.Linear;
Double swipeLeftRight = velocities.X;
Double swipeUpDown = velocities.Y;
// A negative value means swiping to the left
if (swipeLeftRight < 0)
{
navigateToNextPage();
}
// a positive value is a swipe to the right.
else if (swipeLeftRight > 0)
{
navigateToPreviousPage();
}
}
此 Grid 的子元素是 ScrollViewer。
有人可以建议代码有什么问题吗?
默认情况下,ScrollViewer 会浅化任何触摸输入。如果你想处理触摸手势,那么滚动功能将丢失。
解决方案可能因您的需要而异。如果您需要完全控制触摸手势的处理,ScollViewer 不适合您,请将其替换为其他面板。
如果您只需要部分手势处理,您可以将 ManipulationMode 设置为类似 TranslateX, System
的值。结果是你可以沿 X 轴处理手势,其余的由 ScrollViewer 处理。
代码示例
xaml 文件:
<Page
x:Class="Sample.TestTextBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Sample"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<Style x:Key="ListViewStyle1" TargetType="ListView">
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="TabNavigation" Value="Once"/>
<Setter Property="IsSwipeEnabled" Value="True"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled"/>
<Setter Property="ScrollViewer.IsHorizontalRailEnabled" Value="False"/>
<Setter Property="ScrollViewer.VerticalScrollMode" Value="Enabled"/>
<Setter Property="ScrollViewer.IsVerticalRailEnabled" Value="True"/>
<Setter Property="ScrollViewer.ZoomMode" Value="Disabled"/>
<Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="False"/>
<Setter Property="ScrollViewer.BringIntoViewOnFocusChange" Value="True"/>
<Setter Property="ItemContainerTransitions">
<Setter.Value>
<TransitionCollection>
<AddDeleteThemeTransition/>
<ContentThemeTransition/>
<ReorderThemeTransition/>
<EntranceThemeTransition IsStaggeringEnabled="False"/>
</TransitionCollection>
</Setter.Value>
</Setter>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<ItemsStackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListView">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" >
<ScrollViewer x:Name="ScrollViewer" AutomationProperties.AccessibilityView="Raw" BringIntoViewOnFocusChange="{TemplateBinding ScrollViewer.BringIntoViewOnFocusChange}" HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}" IsHorizontalScrollChainingEnabled="{TemplateBinding ScrollViewer.IsHorizontalScrollChainingEnabled}" IsVerticalScrollChainingEnabled="{TemplateBinding ScrollViewer.IsVerticalScrollChainingEnabled}" IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}" IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}" TabNavigation="{TemplateBinding TabNavigation}" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" ZoomMode="{TemplateBinding ScrollViewer.ZoomMode}">
<ItemsPresenter FooterTransitions="{TemplateBinding FooterTransitions}" FooterTemplate="{TemplateBinding FooterTemplate}" Footer="{TemplateBinding Footer}" HeaderTemplate="{TemplateBinding HeaderTemplate}" Header="{TemplateBinding Header}" HeaderTransitions="{TemplateBinding HeaderTransitions}" Padding="{TemplateBinding Padding}" ManipulationMode="TranslateX, System"/>
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" ManipulationMode="TranslateX" ManipulationDelta="Grid_ManipulationDelta">
<ListView Style="{StaticResource ListViewStyle1}">
<ListViewItem>A</ListViewItem>
<ListViewItem>A</ListViewItem>
<ListViewItem>A</ListViewItem>
<ListViewItem>A</ListViewItem>
<ListViewItem>A</ListViewItem>
<ListViewItem>A</ListViewItem>
<ListViewItem>A</ListViewItem>
<ListViewItem>A</ListViewItem>
<ListViewItem>A</ListViewItem>
<ListViewItem>A</ListViewItem>
<ListViewItem>A</ListViewItem>
<ListViewItem>A</ListViewItem>
<ListViewItem>A</ListViewItem>
<ListViewItem>A</ListViewItem>
</ListView>
</Grid>
</Page>
隐藏代码:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
namespace Sample
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class TestTextBox : Page
{
public TestTextBox()
{
this.InitializeComponent();
}
private void Grid_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
}
}
}
在 X 轴拖动列表视图时将触发 onManipulationStarted
。
作为对link的参考,这里是解决方案
我在 ScrollViewer
的 PointerEntered
事件中禁用 ScrollViewer
VerticalScrollMode
,以便调用 Grid Manipulation 事件。启用 VerticalScrollMode
一旦操作完成,即在 ManipulationCompleted
事件中
ScrollViewer scroolviewr;
private void ScrollViewer_PointerEntered(object sender, PointerRoutedEventArgs e)
{
scroolviewr = (sender as ScrollViewer);
(sender as ScrollViewer).VerticalScrollMode = ScrollMode.Disabled;
}
private void PageLayoutGrid_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
e.Handled = true;
}
private void LayoutManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
scroolviewr.VerticalScrollMode = ScrollMode.Enabled;
var velocities = e.Velocities.Linear;
Double swipeLeftRight = velocities.X;
Double swipeUpDown = velocities.Y;
// A negative value means swiping to the left
if (swipeLeftRight < 0)
{
navigateToNextPage();
}
// a positive value is a swipe to the right.
else if (swipeLeftRight > 0)
{
navigateToPreviousPage();
}
}
<Grid ManipulationMode="TranslateX" ManipulationDelta="Grid_ManipulationDelta" ManipulationCompleted="Grid_ManipulationCompleted">
<ScrollViewer HorizontalScrollBarVisibility="Disabled" HorizontalScrollMode="Disabled" PointerEntered="ScrollViewer_PointerEntered">
.....
</ScrollViewer>
</Grid>
我目前正在研究 Windows 10,我想为用户添加滑动手势。所以我做了一些研究并发现了 Manipulation Events。我尝试了以下代码,但它在我使用鼠标指针时有效,而不是在使用触摸滑动手势时有效。
pageLayoutGrid.ManipulationMode = ManipulationModes.TranslateX;
pageLayoutGrid.ManipulationDelta += PageLayoutGrid_ManipulationDelta;
pageLayoutGrid.ManipulationCompleted += LayoutManipulationCompleted;
private void PageLayoutGrid_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
e.Handled = true;
}
private void LayoutManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
var velocities = e.Velocities.Linear;
Double swipeLeftRight = velocities.X;
Double swipeUpDown = velocities.Y;
// A negative value means swiping to the left
if (swipeLeftRight < 0)
{
navigateToNextPage();
}
// a positive value is a swipe to the right.
else if (swipeLeftRight > 0)
{
navigateToPreviousPage();
}
}
此 Grid 的子元素是 ScrollViewer。
有人可以建议代码有什么问题吗?
默认情况下,ScrollViewer 会浅化任何触摸输入。如果你想处理触摸手势,那么滚动功能将丢失。
解决方案可能因您的需要而异。如果您需要完全控制触摸手势的处理,ScollViewer 不适合您,请将其替换为其他面板。
如果您只需要部分手势处理,您可以将 ManipulationMode 设置为类似 TranslateX, System
的值。结果是你可以沿 X 轴处理手势,其余的由 ScrollViewer 处理。
代码示例
xaml 文件:
<Page
x:Class="Sample.TestTextBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Sample"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<Style x:Key="ListViewStyle1" TargetType="ListView">
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="TabNavigation" Value="Once"/>
<Setter Property="IsSwipeEnabled" Value="True"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled"/>
<Setter Property="ScrollViewer.IsHorizontalRailEnabled" Value="False"/>
<Setter Property="ScrollViewer.VerticalScrollMode" Value="Enabled"/>
<Setter Property="ScrollViewer.IsVerticalRailEnabled" Value="True"/>
<Setter Property="ScrollViewer.ZoomMode" Value="Disabled"/>
<Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="False"/>
<Setter Property="ScrollViewer.BringIntoViewOnFocusChange" Value="True"/>
<Setter Property="ItemContainerTransitions">
<Setter.Value>
<TransitionCollection>
<AddDeleteThemeTransition/>
<ContentThemeTransition/>
<ReorderThemeTransition/>
<EntranceThemeTransition IsStaggeringEnabled="False"/>
</TransitionCollection>
</Setter.Value>
</Setter>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<ItemsStackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListView">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" >
<ScrollViewer x:Name="ScrollViewer" AutomationProperties.AccessibilityView="Raw" BringIntoViewOnFocusChange="{TemplateBinding ScrollViewer.BringIntoViewOnFocusChange}" HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}" IsHorizontalScrollChainingEnabled="{TemplateBinding ScrollViewer.IsHorizontalScrollChainingEnabled}" IsVerticalScrollChainingEnabled="{TemplateBinding ScrollViewer.IsVerticalScrollChainingEnabled}" IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}" IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}" TabNavigation="{TemplateBinding TabNavigation}" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" ZoomMode="{TemplateBinding ScrollViewer.ZoomMode}">
<ItemsPresenter FooterTransitions="{TemplateBinding FooterTransitions}" FooterTemplate="{TemplateBinding FooterTemplate}" Footer="{TemplateBinding Footer}" HeaderTemplate="{TemplateBinding HeaderTemplate}" Header="{TemplateBinding Header}" HeaderTransitions="{TemplateBinding HeaderTransitions}" Padding="{TemplateBinding Padding}" ManipulationMode="TranslateX, System"/>
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" ManipulationMode="TranslateX" ManipulationDelta="Grid_ManipulationDelta">
<ListView Style="{StaticResource ListViewStyle1}">
<ListViewItem>A</ListViewItem>
<ListViewItem>A</ListViewItem>
<ListViewItem>A</ListViewItem>
<ListViewItem>A</ListViewItem>
<ListViewItem>A</ListViewItem>
<ListViewItem>A</ListViewItem>
<ListViewItem>A</ListViewItem>
<ListViewItem>A</ListViewItem>
<ListViewItem>A</ListViewItem>
<ListViewItem>A</ListViewItem>
<ListViewItem>A</ListViewItem>
<ListViewItem>A</ListViewItem>
<ListViewItem>A</ListViewItem>
<ListViewItem>A</ListViewItem>
</ListView>
</Grid>
</Page>
隐藏代码:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
namespace Sample
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class TestTextBox : Page
{
public TestTextBox()
{
this.InitializeComponent();
}
private void Grid_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
}
}
}
在 X 轴拖动列表视图时将触发 onManipulationStarted
。
作为对link的参考,这里是解决方案
我在 ScrollViewer
的 PointerEntered
事件中禁用 ScrollViewer
VerticalScrollMode
,以便调用 Grid Manipulation 事件。启用 VerticalScrollMode
一旦操作完成,即在 ManipulationCompleted
事件中
ScrollViewer scroolviewr;
private void ScrollViewer_PointerEntered(object sender, PointerRoutedEventArgs e)
{
scroolviewr = (sender as ScrollViewer);
(sender as ScrollViewer).VerticalScrollMode = ScrollMode.Disabled;
}
private void PageLayoutGrid_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
e.Handled = true;
}
private void LayoutManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
scroolviewr.VerticalScrollMode = ScrollMode.Enabled;
var velocities = e.Velocities.Linear;
Double swipeLeftRight = velocities.X;
Double swipeUpDown = velocities.Y;
// A negative value means swiping to the left
if (swipeLeftRight < 0)
{
navigateToNextPage();
}
// a positive value is a swipe to the right.
else if (swipeLeftRight > 0)
{
navigateToPreviousPage();
}
}
<Grid ManipulationMode="TranslateX" ManipulationDelta="Grid_ManipulationDelta" ManipulationCompleted="Grid_ManipulationCompleted">
<ScrollViewer HorizontalScrollBarVisibility="Disabled" HorizontalScrollMode="Disabled" PointerEntered="ScrollViewer_PointerEntered">
.....
</ScrollViewer>
</Grid>