How to make ScrollView's Scrolled event only respond to user actions in Xamarin.Forms?

Viewed 270

I have a ScrollView that uses code to control automatic scrolling. I need to stop the automatic scrolling when the user inputs, but the ScrollToAsync method of the ScrollView will also trigger the Scrolled event.

   <StackLayout>
            <ScrollView Scrolled="ScrollView_Scrolled">
                <StackLayout></StackLayout>
            </ScrollView>
   </StackLayout>
1 Answers

The short answer

You could use a flag to tell the event who is triggering the scroll event as follows

Boolean scrolledByUser = true;

private async void MyScrollView_Scrolled(object sender, ScrolledEventArgs e)
{
  if (scrolledByUser)
  {
    // do something
  }
  else // scrolled automagically
  {
    // do something else
  }
}

private async void ScrollAutomagically(object sender, EventArgs e)
{
  scrolledByUser = false;
  await MyScrollView.ScrollToAsync(ScrollView.X, 800, true);
  scrolledByUser = true;
}

The long answer

Next you can find a complete sample to illustrate my suggestion.

You start with a new blank project, and then modify App.xaml.cs to look like

App.xaml.cs

using Xamarin.Forms;

namespace scrollviewPrompt
{
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();

            MainPage = new NavigationPage(new MainPage());
        }
    }
}

then go on to modify the MainPage.xaml to include a ScrollView with lots of BoxViews vertically, one above the other:

MainPage.xaml

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="scrollviewPrompt.MainPage">

    <ContentPage.ToolbarItems>
        <ToolbarItem Text="ScrollTo"
                     Clicked="ScrollAutomagically"/>
    </ContentPage.ToolbarItems>

    <ScrollView x:Name="MyScrollView" 
                    Scrolled="MyScrollView_Scrolled">
        <StackLayout>
            <BoxView BackgroundColor="Red"         HeightRequest="128"/>
            <BoxView BackgroundColor="Orange"      HeightRequest="128"/>
            <BoxView BackgroundColor="Blue"      HeightRequest="128"/>
            <BoxView BackgroundColor="Green"      HeightRequest="128"/>
            <BoxView BackgroundColor="Black"      HeightRequest="128"/>
            <BoxView BackgroundColor="AliceBlue"         HeightRequest="128"/>
            <BoxView BackgroundColor="Brown"      HeightRequest="128"/>
            <BoxView BackgroundColor="Pink"      HeightRequest="128"/>
            <BoxView BackgroundColor="White"      HeightRequest="128"/>
            <BoxView BackgroundColor="Yellow"      HeightRequest="128"/>
            <BoxView BackgroundColor="Red"         HeightRequest="128"/>
            <BoxView BackgroundColor="Orange"      HeightRequest="128"/>
            <BoxView BackgroundColor="Blue"      HeightRequest="128"/>
            <BoxView BackgroundColor="Green"      HeightRequest="128"/>
            <BoxView BackgroundColor="Black"      HeightRequest="128"/>
            <BoxView BackgroundColor="AliceBlue"         HeightRequest="128"/>
            <BoxView BackgroundColor="Brown"      HeightRequest="128"/>
            <BoxView BackgroundColor="Pink"      HeightRequest="128"/>
            <BoxView BackgroundColor="White"      HeightRequest="128"/>
            <BoxView BackgroundColor="Yellow"      HeightRequest="128"/>
            <BoxView BackgroundColor="Red"         HeightRequest="128"/>
            <BoxView BackgroundColor="Orange"      HeightRequest="128"/>
            <BoxView BackgroundColor="Blue"      HeightRequest="128"/>
            <BoxView BackgroundColor="Green"      HeightRequest="128"/>
            <BoxView BackgroundColor="Black"      HeightRequest="128"/>
            <BoxView BackgroundColor="AliceBlue"         HeightRequest="128"/>
            <BoxView BackgroundColor="Brown"      HeightRequest="128"/>
            <BoxView BackgroundColor="Pink"      HeightRequest="128"/>
            <BoxView BackgroundColor="White"      HeightRequest="128"/>
            <BoxView BackgroundColor="Yellow"      HeightRequest="128"/>
            <BoxView BackgroundColor="Red"         HeightRequest="128"/>
            <BoxView BackgroundColor="Orange"      HeightRequest="128"/>
            <BoxView BackgroundColor="Blue"      HeightRequest="128"/>
            <BoxView BackgroundColor="Green"      HeightRequest="128"/>
            <BoxView BackgroundColor="Black"      HeightRequest="128"/>
            <BoxView BackgroundColor="AliceBlue"         HeightRequest="128"/>
            <BoxView BackgroundColor="Brown"      HeightRequest="128"/>
            <BoxView BackgroundColor="Pink"      HeightRequest="128"/>
            <BoxView BackgroundColor="White"      HeightRequest="128"/>
            <BoxView BackgroundColor="Yellow"      HeightRequest="128"/>
            <BoxView BackgroundColor="Red"         HeightRequest="128"/>
            <BoxView BackgroundColor="Orange"      HeightRequest="128"/>
            <BoxView BackgroundColor="Blue"      HeightRequest="128"/>
            <BoxView BackgroundColor="Green"      HeightRequest="128"/>
            <BoxView BackgroundColor="Black"      HeightRequest="128"/>
            <BoxView BackgroundColor="AliceBlue"         HeightRequest="128"/>
            <BoxView BackgroundColor="Brown"      HeightRequest="128"/>
            <BoxView BackgroundColor="Pink"      HeightRequest="128"/>
            <BoxView BackgroundColor="White"      HeightRequest="128"/>
            <BoxView BackgroundColor="Yellow"      HeightRequest="128"/>
            <BoxView BackgroundColor="Red"         HeightRequest="128"/>
            <BoxView BackgroundColor="Orange"      HeightRequest="128"/>
            <BoxView BackgroundColor="Blue"      HeightRequest="128"/>
            <BoxView BackgroundColor="Green"      HeightRequest="128"/>
            <BoxView BackgroundColor="Black"      HeightRequest="128"/>
            <BoxView BackgroundColor="AliceBlue"         HeightRequest="128"/>
            <BoxView BackgroundColor="Brown"      HeightRequest="128"/>
            <BoxView BackgroundColor="Pink"      HeightRequest="128"/>
            <BoxView BackgroundColor="White"      HeightRequest="128"/>
            <BoxView BackgroundColor="Yellow"      HeightRequest="128"/>
            <BoxView BackgroundColor="Red"         HeightRequest="128"/>
            <BoxView BackgroundColor="Orange"      HeightRequest="128"/>
            <BoxView BackgroundColor="Blue"      HeightRequest="128"/>
            <BoxView BackgroundColor="Green"      HeightRequest="128"/>
            <BoxView BackgroundColor="Black"      HeightRequest="128"/>
            <BoxView BackgroundColor="AliceBlue"         HeightRequest="128"/>
            <BoxView BackgroundColor="Brown"      HeightRequest="128"/>
            <BoxView BackgroundColor="Pink"      HeightRequest="128"/>
            <BoxView BackgroundColor="White"      HeightRequest="128"/>
            <BoxView BackgroundColor="Yellow"      HeightRequest="128"/>
            <BoxView BackgroundColor="Red"         HeightRequest="128"/>
            <BoxView BackgroundColor="Orange"      HeightRequest="128"/>
            <BoxView BackgroundColor="Blue"      HeightRequest="128"/>
            <BoxView BackgroundColor="Green"      HeightRequest="128"/>
            <BoxView BackgroundColor="Black"      HeightRequest="128"/>
            <BoxView BackgroundColor="AliceBlue"         HeightRequest="128"/>
            <BoxView BackgroundColor="Brown"      HeightRequest="128"/>
            <BoxView BackgroundColor="Pink"      HeightRequest="128"/>
            <BoxView BackgroundColor="White"      HeightRequest="128"/>
            <BoxView BackgroundColor="Yellow"      HeightRequest="128"/>
            <BoxView BackgroundColor="Red"         HeightRequest="128"/>
            <BoxView BackgroundColor="Orange"      HeightRequest="128"/>
            <BoxView BackgroundColor="Blue"      HeightRequest="128"/>
            <BoxView BackgroundColor="Green"      HeightRequest="128"/>
            <BoxView BackgroundColor="Black"      HeightRequest="128"/>
            <BoxView BackgroundColor="AliceBlue"         HeightRequest="128"/>
            <BoxView BackgroundColor="Brown"      HeightRequest="128"/>
            <BoxView BackgroundColor="Pink"      HeightRequest="128"/>
            <BoxView BackgroundColor="White"      HeightRequest="128"/>
            <BoxView BackgroundColor="Yellow"      HeightRequest="128"/>
            <BoxView BackgroundColor="Red"         HeightRequest="128"/>
            <BoxView BackgroundColor="Orange"      HeightRequest="128"/>
            <BoxView BackgroundColor="Blue"      HeightRequest="128"/>
            <BoxView BackgroundColor="Green"      HeightRequest="128"/>
            <BoxView BackgroundColor="Black"      HeightRequest="128"/>
            <BoxView BackgroundColor="AliceBlue"         HeightRequest="128"/>
            <BoxView BackgroundColor="Brown"      HeightRequest="128"/>
            <BoxView BackgroundColor="Pink"      HeightRequest="128"/>
            <BoxView BackgroundColor="White"      HeightRequest="128"/>
            <BoxView BackgroundColor="Yellow"      HeightRequest="128"/>
        </StackLayout>
    </ScrollView>
</ContentPage>

and finally add the event handlers

using System;
using Xamarin.Forms;

namespace scrollviewPrompt
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
        }

        Boolean handled = false;

        Boolean scrolledByUser = true;

        private async void MyScrollView_Scrolled(object sender, ScrolledEventArgs e)
        {
            if (!handled)
            {
                handled = true;

                if (scrolledByUser)
                {
                    await DisplayAlert("Alert", "ScrollView Scrolled by user!", "Ok");
                }
                else
                {
                    await DisplayAlert("Alert", "ScrollView Scrolled automagically!", "Ok");
                }
                handled = false;
            }
        }

        private async void ScrollAutomagically(object sender, EventArgs e)
        {
            scrolledByUser = false;
            await MyScrollView.ScrollToAsync(MyScrollView.X, 800, true);
            scrolledByUser = true;
        }
    }
}

Hope this helps!

Related