【问题标题】:What event fires when user lifts finger from ScrollViewer on touch capable screens当用户在支持触摸的屏幕上从 ScrollViewer 抬起手指时会触发什么事件
【发布时间】:2013-12-13 02:28:59
【问题描述】:

我发现当我点击 ScrollViewer 时,PointerPressed 和 PointerExited 事件会按预期触发。但是,如果我在触摸屏幕并抬起手指后向任何方向滚动,除了 PointerCaptureLost 之外不会触发任何事件,它会在我滚动时立即触发。

当我捕获指针 ID 并使用计时器轮询 PointerPoint 的状态时,IsInContact 标志保持为真,即使在我滚动后抬起手指也是如此。当我只需点击屏幕时,它就会按预期工作。

ManipulationCompleted 与上面的效果相同,我不能使用 ViewChanged 事件,因为它在我抬起手指之前触发。

这是一个错误还是我在这里遗漏了什么?是否有另一种方法可以检测用户何时将手指从屏幕上抬起?这让我很生气。

下面的示例代码。您需要在触摸模式下使用模拟器或使用可触摸的屏幕进行测试:

代码

using System;
using Windows.UI.Input;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;

namespace App1
{
    public sealed partial class MainPage : Page
    {

        private readonly DispatcherTimer pointerTimer = new DispatcherTimer();
        private uint? CurrentPointerID; //container for the current pointer id when user makes contact with the screeen

        public MainPage()
        {
            this.InitializeComponent();

            scrollviewer.PointerPressed += scrollviewer_PointerPressed;
            scrollviewer.PointerMoved += scrollviewer_PointerMoved;
            scrollviewer.PointerExited += scrollviewer_PointerExited;
            scrollviewer.PointerReleased += scrollviewer_PointerReleased;
            scrollviewer.PointerCaptureLost += scrollviewer_PointerCaptureLost;
            scrollviewer.PointerCanceled += scrollviewer_PointerCanceled;


            pointerTimer.Tick += pointerTimer_Tick;
            pointerTimer.Interval = TimeSpan.FromMilliseconds(300);
            pointerTimer.Start();


        }

        #region ScrollViewer Events

        void scrollviewer_PointerMoved(object sender, PointerRoutedEventArgs e)
        {
            EventCalledTextBlock.Text = "Pointer Moved";
        }

        void scrollviewer_PointerExited(object sender, PointerRoutedEventArgs e)
        {
            EventCalledTextBlock.Text = "Pointer Exited";
        }

        void scrollviewer_PointerPressed(object sender, PointerRoutedEventArgs e)
        {
            CurrentPointerID = e.Pointer.PointerId;
            EventCalledTextBlock.Text = "Pointer Pressed";
        }

        void scrollviewer_PointerCanceled(object sender, PointerRoutedEventArgs e)
        {
            EventCalledTextBlock.Text = "Pointer Canceled";
        }

        void scrollviewer_PointerCaptureLost(object sender, PointerRoutedEventArgs e)
        {
            EventCalledTextBlock.Text = "Capture Lost";
        }

        void scrollviewer_PointerReleased(object sender, PointerRoutedEventArgs e)
        {
            EventCalledTextBlock.Text = "Pointer Released";
        }
        #endregion



        void pointerTimer_Tick(object sender, object e)
        {
            if (!CurrentPointerID.HasValue)
            {
                PollingTextBlock.Text = string.Empty;
                return;
            }

            try
            {
                var pointerPoint = PointerPoint.GetCurrentPoint(CurrentPointerID.Value);

                PollingTextBlock.Text = pointerPoint.IsInContact ? "Is In Contact" : "Not in Contact";
            }
            catch (Exception ex)
            {
                //This exception is raised when the user lifts finger without dragging.
                //assume finger is not in contact with screen
                PollingTextBlock.Text = "Not in Contact";
            }
        }

    }
}

XAML

 <Page
    x:Class="App1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App1"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Name="grid">
        <Grid.RowDefinitions>
            <RowDefinition Height="113*"/>
            <RowDefinition Height="655*"/>
        </Grid.RowDefinitions>
        <ScrollViewer x:Name="scrollviewer" VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Visible" Grid.Row="1" >
            <Rectangle Fill="#FF3783CF" Height="100" Stroke="#FF33D851" Width="{Binding ElementName=grid, Path=ActualWidth}" Margin="100" StrokeThickness="4" />
        </ScrollViewer>
        <StackPanel Orientation="Vertical" Margin="45,25,0,0">
            <StackPanel Orientation="Horizontal">
            <TextBlock  HorizontalAlignment="Left" TextWrapping="Wrap" Text="Event Called:" VerticalAlignment="Top" FontSize="24" Margin="0,0,20,0"/>
            <TextBlock x:Name="EventCalledTextBlock" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="24"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock  HorizontalAlignment="Left" TextWrapping="Wrap" Text="Polling Value:" VerticalAlignment="Top" FontSize="24" Margin="0,0,20,0"/>
            <TextBlock x:Name="PollingTextBlock" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="24"/>
        </StackPanel>
    </StackPanel>

    </Grid>
</Page>

【问题讨论】:

  • 你尝试过操纵事件而不是指针事件吗?
  • 是的。它会导致与上述相同的行为,即在滚动后永远不会调用 ManipulationCompleted。
  • 我想知道您的 ScrollViewer 中的 Rectangle 是否正在“吃掉”您的 Pointer Released 事件。
  • 理论不错,但是当我通过 ((UIElement) scrollviewer.Content) 将指针事件添加到 Rectangle 时,它​​们根本不会触发。同样在 Rectangle 上设置 ManipulationMode 允许引发 Scrollviewer 上的 PointerExit 事件,但是这会一起禁用滚动。
  • 嗯,我记得在 MSDN 文档中读到 PointerReleased 事件并不总是必须触发。它给出了为什么会出现这种情况的几个原因。找到了。请查看“不要依赖总是成对发生的 PointerPressed 和 PointerReleased 事件。要正常运行,您的应用程序必须侦听并处理所有代表 Press 操作可能得出的结论的事件。”这是链接:msdn.microsoft.com/library/windows/apps/br208972

标签: c# xaml windows-runtime windows-store-apps winrt-xaml


【解决方案1】:

我偶然发现了这个问题,因为我正在努力解决类似的问题。我有一个 ScrollViewer,其中有几个图像,我想知道 ScrollViewer 停止移动时显示的图像...

最后我确实使用了 ScrollViewer.ViewChanged 事件。此事件会一直触发,直到完成滚动。

我实际上只对这些事件中的最后一个事件感兴趣,但由于没有事件仅在该特定时刻触发,我需要对此做出响应并检查自己是否是采取行动的合适时机。

我希望这会有所帮助。

ScrollViewer.ViewChanged 事件:https://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.scrollviewer.viewchanged?f=255&MSPPError=-2147217396

【讨论】:

    【解决方案2】:

    我认为您需要使用 PointerReleased 事件。 参考以下链接:https://msdn.microsoft.com/library/windows/apps/br208279

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多