如何在 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的参考,这里是解决方案

我在 ScrollViewerPointerEntered 事件中禁用 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>