DZone
Mobile Zone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone > Mobile Zone > WinRT XAML: Automatically Scrolling ListView and Detection

WinRT XAML: Automatically Scrolling ListView and Detection

Mikael Koskinen user avatar by
Mikael Koskinen
·
Aug. 28, 12 · Mobile Zone · Tutorial
Like (0)
Save
Tweet
23.52K Views

Join the DZone community and get the full member experience.

Join For Free

One of our Windows 8 WinRT apps requires a ListView with two features:

  1. "Auto-stick". The ListView must automatically scroll to the bottom when a new message is added to it.
  2. "Scroll detection". User can disable the "Auto-stick" by manually scrolling the ListView. If the user scrolls the ListView to bottom, the "Auto-stick" is enabled, otherwise it's disabled.

Here's some guidance on how you can achieve these features in a WinRT app using C# and XAML.

Automatically scrolling ListView to bottom

The ListView can be programmatically scrolled using the ScrollIntoView-method. You can pass in the item and the ListView jumps to show it. Here's how you can automatically scroll the ListView to show the last item when the list's ItemsSource is an ObservableCollection and a new item is added to the collection:

1. Register a listener to collection's CollectionChanged-event:
private readonly ObservableCollection<string> items = new ObservableCollection<string>();
...

        private void MyListviewLoaded(object sender, RoutedEventArgs e)
        {
            this.MyListView.ItemsSource = items;

            items.CollectionChanged += (s, args) => ScrollToBottom();
        }
2. In the ScrollToBottom-method, set the ListView's SelectedIndex to the last item in the collection, then use ScrollIntoView to scroll to the SelectedItem:
private void ScrollToBottom()
        {
            var selectedIndex = MyListView.Items.Count - 1;
            if (selectedIndex < 0)
                return;

            MyListView.SelectedIndex = selectedIndex;
            MyListView.UpdateLayout();

            MyListView.ScrollIntoView(MyListView.SelectedItem);
        }

 Another option (used by the WinRT XAML Toolkit) is to get the ScrollViewer-control from inside the ListView, and call its ScrollToVerticalOffset-method:

private void ScrollToBottom()
        {
            var scrollViewer = MyListView.GetFirstDescendantOfType<ScrollViewer>();
            scrollViewer.ScrollToVerticalOffset(scrollViewer.ScrollableHeight);
        }

GetFirstDescendantOfType is part of the WinRT XAML toolkit. Here's the VisualTreeHelperExtensions -class from the toolkit which includes this extension method:

expand source

Detecting when ListView is scrolled to the bottom

In our case the auto-stick is enabled or disabled based on where the user scrolls the ListView. This requires that we can detect when the ListView is scrolled (or actually, when the scrolling ends) and also we need to know if the ListView is scrolled to the bottom. In order to achieve these, we first need to access the ListView's ScrollViewer and then the ScrollViewer's vertical ScrollBar. We can use the GetFirstDescendantOfType and GetDescendantsOfType -extension methods from WinRT XAML Toolkit (shown above) to get these controls:

var scrollViewer = MyListView.GetFirstDescendantOfType<ScrollViewer>();

var scrollbars = scrollViewer.GetDescendantsOfType<ScrollBar>().ToList();

var verticalBar = scrollbars.FirstOrDefault(x => x.Orientation == Orientation.Vertical);

Now that we have the vertical scroll bar, we can register an event handler to its Scroll-event:

if (verticalBar != null)
                verticalBar.Scroll += BarScroll;

In the BarScroll-method we receive and event argument of type ScrollEventargs. This argument tells us when the scrolling has ended. After making sure that we have received the event we need, we can use the argument's NewValue-property to make sure if we have scrolled to the bottom:

void BarScroll(object sender, ScrollEventArgs e)
        {
            if (e.ScrollEventType != ScrollEventType.EndScroll) return;

            var bar = sender as ScrollBar;
            if (bar == null)
                return;

            System.Diagnostics.Debug.WriteLine("Scrolling ended");

            if (e.NewValue >= bar.Maximum)
            {
                System.Diagnostics.Debug.WriteLine("We are at the bottom");
                LockToBottom = true;
            }
            else
            {
                System.Diagnostics.Debug.WriteLine("We are away from the bottom");
                LockToBottom = false;
            }
        }

Now we just need to the edit the ScrollToBottom-method so that the automatic scrolling happens only if the LockToBottom-property is set to true:

private void ScrollToBottom()
        {
            if (!LockToBottom)
                return;

            var selectedIndex = MyListView.Items.Count - 1;
            if (selectedIndex < 0)
                return;

            MyListView.SelectedIndex = selectedIndex;
            MyListView.UpdateLayout();

            MyListView.ScrollIntoView(MyListView.SelectedItem);
        }

Sample:

A sample app if available from the GitHub.

image

Add few messages to the list to see how it auto scrolls, because the “Auto Stick” is enabled by default. Then scroll the list up and auto stick is disabled.

app Event Pass (software) GitHub IT

Published at DZone with permission of Mikael Koskinen, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Key Highlights from the New NIST SSDF
  • The Impacts of Blockchain on the Software Development Industry
  • What Is Network-Attached Storage(NAS), and How Does It Work?
  • Testing Strategies for Microservices

Comments

Mobile Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • MVB Program
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends:

DZone.com is powered by 

AnswerHub logo