简体   繁体   English

e.IsInertial几乎总是错误的WPF

[英]e.IsInertial almost always false WPF

I have the following XAML for my WPF app, which I am converting from UWP: 我的WPF应用具有以下XAML,这是我从UWP转换而来的:

<ScrollViewer Name="scv_main" Grid.Row="2" ScrollViewer.VerticalScrollBarVisibility="Auto" 
PanningMode="VerticalFirst">
    <TextBlock Name="txbl_display" Grid.Row="2"  Foreground="White"
     FontFamily="Lucida Console" FontSize="22" Text="{Binding Path=ContentPath, Mode=OneWay, 
     UpdateSourceTrigger=PropertyChanged}" Padding="20" TextWrapping="Wrap" 
     IsManipulationEnabled="True" ManipulationDelta="manipulationDeltaHandler"/>
</ScrollViewer>

What I'm finding is, the event handler's e.IsInertial is always false. 我发现的是,事件处理程序的e.IsInertial始终为false。

I thought it might be the ScrollViewer handling the inertial events, but when I remove the ScrollViewer I still can't get any Inertial events to come through. 我以为可能是ScrollViewer处理惯性事件,但是当我删除ScrollViewer时,仍然无法获得任何惯性事件。 I have also tried putting the ManipulationDelta on the ScrollViewer, with the same result. 我也尝试过将ManipulationDelta放在ScrollViewer上,结果相同。

My ultimate aim is that I want the ScrollViewer to scroll on a non-inertial move, but let me control what happens on an inertial swipe. 我的最终目的是希望ScrollViewer进行非惯性移动,但让我控制惯性滑动时会发生什么。

I managed this effect in the UWP app which I am porting to WPF, as follows: 我在要移植到WPF的UWP应用中管理了这种效果,如下所示:

<TextBlock ... ManipulationMode="All" ManipulationDelta="TextBlock_ManipulationDelta/>"

and then in the code-behind: 然后在后面的代码中:

if (e.IsInertial) // inertial = swipe, rather than slide
{
    // X-Translation - change contents of textblock
    if (e.Cumulative.Translation.X <= -500) //500 is the threshold value, where you want to trigger the swipe right event
    {
        showNext();
        e.Complete();
    }
    else if (e.Cumulative.Translation.X >= 500)
    {
        showPrevious();
        e.Complete();
    }

    // Y translation - move the scrollbar
    else if (e.Cumulative.Translation.Y <= -500)
    {
        scv_main.ChangeView(null, scv_main.VerticalOffset + (-1 * e.Cumulative.Translation.Y), null);
        e.Complete();
    }
    else if (e.Cumulative.Translation.Y >= 500)
    {
        scv_main.ChangeView(null, Math.Min(scv_main.VerticalOffset + (-1 * e.Cumulative.Translation.Y), 0), null);
        e.Complete();
    }
}
else // slide,rather than swipe - scroll as the finger moves
{
    if (e.Delta.Translation.Y != 0)
    {
        scv_main.ChangeView(null, scv_main.VerticalOffset + (-1 * e.Delta.Translation.Y), null);
    }
}

But I can't repeat this behaviour in WPF. 但是我无法在WPF中重复这种行为。 Any thoughts? 有什么想法吗?

---UPDATE--- -更新-

I have since found that, by swiping in a large arc from top-right to bottom-left, with the screen full-screened, I can just about trigger an e.IsInertial = True event. 从那以后,我发现通过从右上角向左下角滑动较大的弧度(全屏显示屏幕),我几乎可以触发e.IsInertial = True事件。 When this happens, the ManipulationDelta event is triggered twice - the first time with e.IsInertial = false and the second with e.IsInertial = true . 发生这种情况时,将两次触发ManipulationDelta事件-第一次触发e.IsInertial = false ,第二次e.IsInertial = true I'm not sure why this happens; 我不确定为什么会这样。 and anyway this isn't the behaviour I'm looking for. 无论如何,这不是我要寻找的行为。

Anyone got any more thoughts? 还有其他想法吗? I have tried various things, including putting a panel ontop of everything and putting the manipulation handlers on that; 我尝试了各种方法,包括在所有内容的顶部放置一个面板,并在其上放置操纵处理程序。 but I was still having the same issues. 但我仍然遇到同样的问题。

I am using Visual Studio 2017 and Windows 10. The device I am coding and testing on is a Microsoft Surface Book 我正在使用Visual Studio 2017和Windows10。我正在编码和测试的设备是Microsoft Surface Book


What seems to be happening is, the non-inertial move is happening first; 似乎正在发生的是,非惯性运动首先发生。 then once that's finished the inertial is firing. 然后一旦完成,惯性就会触发 I put some outputs in the events, and got the following when I swiped: 我在事件中添加了一些输出,并且在滑动时获得了以下输出:

ManipulationStarting Fired
ManipulationDelta e.IsInertial = False. X,Y:-5.14288330078125,-1.14288330078125
ManipulationDelta e.IsInertial = False. X,Y:-16.5714111328125,0
ManipulationDelta e.IsInertial = False. X,Y:-16.5714111328125,0
ManipulationDelta e.IsInertial = False. X,Y:-89.1428833007813,1.14288330078125
ManipulationDelta e.IsInertial = False. X,Y:-224,2.28570556640625
ManipulationDelta e.IsInertial = False. X,Y:-224,2.28570556640625
ManipulationDelta e.IsInertial = False. X,Y:-384.571441650391,4
ManipulationDelta e.IsInertial = False. X,Y:-622.285705566406,4
ManipulationDelta e.IsInertial = False. X,Y:-622.285705566406,4
ManipulationDelta e.IsInertial = False. X,Y:-622.285705566406,4
ManipulationDelta e.IsInertial = False. X,Y:-732.571411132813,6.28570556640625
ManipulationDelta e.IsInertial = False. X,Y:-732.571411132813,6.28570556640625
ManipulationDelta e.IsInertial = False. X,Y:-732.571411132813,6.28570556640625
ManipulationDelta e.IsInertial = False. X,Y:-732.571411132813,6.28570556640625
ManipulationInertiaStarting Fired

After that, I don't get any more deltas firing. 在那之后,我不再有三角洲射击。 So what's consuming them; 那么什么在消耗它们呢? and why am I getting non-inertial ones first? 为什么我会先得到非惯性的?

One way I've found to get this kind-of working is to change PanningMode="VerticalFirst" to PanningMode="None" . 我发现获得这种工作的一种方法是将PanningMode="VerticalFirst"更改为PanningMode="None" then handle the scrolling myself (which seems to be what the UWP version was doing anyway)... but I still have to get rid of the "e.IsInertial" check. 然后自己处理滚动(无论如何,这似乎是UWP版本所做的事情)...但我仍然必须摆脱“ e.IsInertial”检查。 So something is causing inertial deltas to be consumed before my event handler gets them 因此,某种原因导致惯性增量在事件处理程序获取之前被消耗

To make sure that the manipulation flow works as intended you want to handle more of the manipulation events and react accordingly. 为确保操纵流按预期工作,您想处理更多操纵事件并做出相应反应。 Here's the overview from MS ( Input overview - Touch and manipulations ) but in general, you usually want to: 这是MS的概述( 输入概述-触摸和操作 ),但是通常,您通常需要:

  • handle ManipulationStarting and set the proper manipulation container for your manipulation. 处理ManipulationStarting并为您的操作设置适当的操作容器。
  • handle ManipulationStarted if you want to store some data like the origin of the manipulation for your own calculations. 如果要存储一些数据(例如用于您自己的计算的操作来源),请处理ManipulationStarted。
  • handle Delta while the user has the finger(s) down 在用户将手指放下时处理Delta
  • handle InertiaStarting - here you should set the deceleration values. 处理InertiaStarting-在此处应设置减速度值。
  • handle Delta while the user has lifted his fingers (Inertial) - from my experience you'll get these events only if you specify inertial values. 在用户抬起手指(惯性)时处理Delta-根据我的经验,仅当您指定惯性值时,您才会获得这些事件。
  • handle ManipulationCompleted if you need to know when and where the input process has finished. 如果您需要知道输入过程何时何地完成,请处理ManipulationCompleted。

From your post I'm not sure whether you know this or not but the InertiaStarting will only happen once the user has lifted his finger (s). 从您的帖子中,我不确定您是否知道这一点,但是InertiaStarting仅在用户抬起手指后才会发生。 And then - if you set the values when handling InertiaStarting properly - you will get a few more ManipulationDeltas incoming (with the Inertial flag). 然后-如果在正确处理InertiaStarting时设置了值 -您将收到更多的ManipulationDeltas输入(带有Inertial标志)。

After that, I don't get any more deltas firing. 在那之后,我不再有三角洲射击。 So what's consuming them; 那么什么在消耗它们呢? and why am I getting non-inertial ones first? 为什么我会先得到非惯性的?

You have completed the manipulation process by calling complete as the if check below has been fulfilled! 您已经通过完成以下调用if的if检查来完成操纵过程! So the 'engine' has skipped all the rest of the events it would otherwise fire and completed the manipulation process: 因此,“引擎”已跳过了所有其他可能触发的事件,并完成了操作过程:

if (e.Cumulative.Translation.X <= -500)
{
    showNext();
    e.Complete();
}

Once the manipulation has been completed you won't get any more events of course. 一旦操作完成,您当然不会再有其他事件了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 ManipulationDeltaRoutedEventArgs.IsInertial始终返回false - ManipulationDeltaRoutedEventArgs.IsInertial always returning false SetupDiEnumDeviceInterfaces()始终返回false-C#WPF - SetupDiEnumDeviceInterfaces() always returns false - C# WPF 如果我们几乎总是使用 DelegateCommands,那么 WPF 命令有什么用? - What are WPF commands for if we almost always use DelegateCommands? wpf-LDAP在验证时始终返回false - wpf - LDAP always returns false when validating 尽管IsHitTestVisible == true,WPF IsMouseOver始终为false - WPF IsMouseOver is always false though IsHitTestVisible == true WPF Applicationdeployment.isnetworkdeployed始终返回false - WPF Applicationdeployment.isnetworkdeployed is always return false WPF DataGrid Validation.HasError始终为false(MVVM) - WPF DataGrid Validation.HasError is always false (MVVM) WPF:将RadioButton&#39;IsChecked&#39;绑定到Settings.Default始终设置为&#39;false&#39; - WPF: Binding RadioButton 'IsChecked' to Settings.Default always setting to 'false' 绑定属性始终返回false,但仍选中WPF绑定的CheckBox - Bound Property always returns false but WPF bound CheckBox is still checked C# WPF 将 RadioSelect 布尔值保存到 XML 文件(始终为假) - C# WPF Saving RadioSelect bool value to XML File (it's always false)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM