none
C# Gesture Recognition Example

    Question

  • Hi, I'm trying to work out how to detect a cross-swipe gesture for ui elements held within a horizontal StackPanel in a ScrollViewer - but not getting very far.  Does anyone know of some c#/vb examples of how you can do this?

    Also, I notice that if I don't perform a perfect vertical swipe I get some horizontal panning movement.  Is there a way to reduce the sensitivity so that panning only occurs after a certain threshold of horizontal movement?

    Thanks, David

    Saturday, November 12, 2011 11:50 AM

All replies

  • There isn't a C# example of this yet, but there are JavaScript and C++ samples which use the same API.  The Manipulations and Gestures in C++ is a good place to start looking.

    The basic concept is to take your PointerPressed, Move, and Release events and pass the data to a GestureRecognizer object.  The GestureRecognizer can be set to watch for CrossSlide only in which case it won't trigger horizontal panning.  You can also use multiple GestureRecognizers if you want to prioritize recognition of different events.

    --Rob

    Monday, November 14, 2011 6:37 AM
  • Hi Rob.  I'm really struggling here.  This is the very simple test project that I've put together in order to try and understand how all of this hangs together.

    The relevant XAML:
            <StackPanel Orientation="Vertical">
                <ScrollViewer x:Name="ScrollTest"
                              Margin="20" Grid.Row="1"
                              Grid.Column="2"
                              HorizontalScrollBarVisibility="Auto"
                              VerticalScrollBarVisibility="Disabled"
                              Height="80"
                              VerticalAlignment="Top"
                              HorizontalSnapPointsType="Optional"
                              HorizontalSnapPointsAlignment="Near"
                              HorizontalScrollMode="Rails"
                              VerticalScrollMode="Disabled"
                              ZoomMode="Disabled"
                              PointerPressed="ScrollTest_PointerPressed"
                              PointerMoved="ScrollTest_PointerMoved"
                              PointerReleased="ScrollTest_PointerReleased">

                    <StackPanel Orientation="Horizontal" >
                        <Border x:Name="Border1" Width="100" Height="60" Margin="0,0,20,0" Background="#FF78A4E2" >
                            <TextBlock Text="1" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                        </Border>
                        <Border Width="100" Height="60" Margin="0,0,20,0" Background="#FF78A4E2">
                            <TextBlock Text="2" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                        </Border>
                        ... 16 of these Border controls in total ...
                    </StackPanel>
                </ScrollViewer>
                <ListBox x:Name="lstTrace" Margin="20"/>
            </StackPanel>

    The C# code:
            private void UserControl_Loaded(object sender, RoutedEventArgs e)
            {
                gr = new GestureRecognizer();
                gr.GestureSettings = GestureSettings.CrossSlide;
                gr.CrossSliding += new TypedEventHandler<GestureRecognizer, CrossSlidingEventArgs>(gr_CrossSliding);
            }

            void gr_CrossSliding(GestureRecognizer sender, CrossSlidingEventArgs args)
            {
                lstTrace.Items.Add("ClossSlide detected");
            }

            private void ScrollTest_PointerPressed(object sender, Windows.UI.Xaml.Input.PointerEventArgs e)
            {
                gr.ProcessDownEvent(e.GetCurrentPoint(ScrollTest));
            }

            private void ScrollTest_PointerMoved(object sender, Windows.UI.Xaml.Input.PointerEventArgs e)
            {
                gr.ProcessMoveEvents(e.GetIntermediatePoints(ScrollTest));
            }

            private void ScrollTest_PointerReleased(object sender, Windows.UI.Xaml.Input.PointerEventArgs e)
            {
                gr.ProcessUpEvent(e.GetCurrentPoint(ScrollTest));
            }

    At the moment I do not see any entries appear in the ListBox.

    Can you shed any light on this?

    Thanks.

    Monday, November 14, 2011 11:11 PM
  • With your code I can generally get the CrossFade on the first gesture attempt (if I stay within the ScrollViewer), but after that it looks like the ScrollViewer is capturing the pointer and handling the PointerReleased events before your events do.  Without being able to process the Up event it won't ever detect a CrossFade.

    Is there a reason you are trying to add CrossFade to a ScrollViewer rather than using a GridView which already supports it?

    --Rob

    Friday, November 18, 2011 8:10 AM
  • I'm having the same problem.  The GridView drag threshold is too large for my scenario so I'm trying to implement my own, super simple, items control that supports drag and drop.  The problem is that when I put my items control in a scroll viewer, gesture recognition stops working.  I think I'm getting a pointer capture lost.

    What's up with the ScrollViewer and how can I use it and still get gesture recognition to work?

    Friday, May 11, 2012 3:56 AM
  • Some additional info that might help.

    The ScrollViewer is configured to scroll horizontally and the items in the itemscontrol are set to cross slide vertically.  I've disabled vertical scrolling and zooming.

    <ScrollViewer VerticalScrollMode="Disabled" VerticalScrollBarVisibility="Hidden" HorizontalScrollMode="Enabled" HorizontalScrollBarVisibility="Auto" ZoomMode="Disabled" Height="150" VerticalAlignment="Bottom">
        <local:DragSource Height="150" VerticalAlignment="Bottom"/>
    </ScrollViewer>



    Friday, May 11, 2012 4:08 AM