I have the following XAML for my WPF app, which I am converting from 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.
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. I have also tried putting the ManipulationDelta on the ScrollViewer, with the same result.
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.
I managed this effect in the UWP app which I am porting to WPF, as follows:
<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. 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. When this happens, the ManipulationDelta
event is triggered twice - the first time with e.IsInertial = false
and the second with 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
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"
. 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. So something is causing inertial deltas to be consumed before my event handler gets them
ManipulationStarting
? – ZoManipulationStarting
fires regularly; butManipulationInertiaStarting
only fires if I do a really massive swipe in an arc (e.g. top-right to bottom-left of screen) - in which case actually e.IsInertial is True in theManipulationDelta
event handler too - but this is rare and not at all the same behaviour as the UWP app, which seems to have a much better threshold for what is inertial – ZoManipulationInertiaStarting
fires, the ManipulationDelta gets called twice - once with e.IsInertial = False, followed by e.IsInertial = True. Something weird is going on here – Zo