-2

How to have android like scrollbars for my WPF ListView. I mean to say, the scrollbar should be visible only when the user scrolls. They should fade out as soon as the user stops scrolling. How to achieve this?

androider
  • 982
  • 6
  • 16
  • 32

1 Answers1

-1

You can use the DispatcherTimer class from the System.Windows.Threading namespace.
Here is the XAML markup for your window:

<Window x:Class="testwpf.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ListView Name="list" ScrollViewer.VerticalScrollBarVisibility="Hidden" Loaded="list_Loaded">
    </ListView>
</Window>

And here is the code behind:

public partial class MainWindow : Window
{
    DispatcherTimer dispatcherTimer;

    public MainWindow()
    {
        InitializeComponent();

        dispatcherTimer = new DispatcherTimer();
        dispatcherTimer.Tick += dispatcherTimer_Tick;
    }

    private void dispatcherTimer_Tick(object sender, EventArgs e)
    {
        // we are here only if for the last 500 ms there were no changes of
        // the scrollbar's vertical offset and we can hide a scrollbar
        list.SetValue(ScrollViewer.VerticalScrollBarVisibilityProperty, ScrollBarVisibility.Hidden);
        dispatcherTimer.Stop();
    }

    private void list_Loaded(object sender, RoutedEventArgs e)
    {
        // attach a handler
        Decorator border = VisualTreeHelper.GetChild(list, 0) as Decorator;
        ScrollViewer scroll = border.Child as ScrollViewer;
        scroll.ScrollChanged += list_ScrollChanged;
    }

    private void list_ScrollChanged(object sender, ScrollChangedEventArgs e)
    {
        // when vertical scroll position is changed, we set VerticalScrollBarVisibilityProperty 
        // to Auto (scroll bar is displayed only if needed) and run a timer with 500 ms interval
        if (e.VerticalChange != 0)
        {
            list.SetValue(ScrollViewer.VerticalScrollBarVisibilityProperty, ScrollBarVisibility.Auto);
            dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 500);
            dispatcherTimer.Start();
        }
    }
}

This is a raw example. Of course, you can apply your own conditions defining whether you should hide a scrollbar. For example, you might decide not to hide a scrollbar if left mouse button is still pressed over a scrollbar.

undermind
  • 1,779
  • 13
  • 33
  • -1 How on earth did you figure that a `DispatcherTimer` would help? Surely, you'd just need to change the `Opacity` in the `MouseOver` event? – Sheridan May 28 '14 at 12:55
  • @Sheridan, probably I haven't understood the problem correctly. I thought that a scrollbar should become visible when user scrolls the content and it can be done not only over a scrollbar area, but also with mouse wheel and keys. But, alas, I didn't think about `Opacity` and `MouseOver` event, thank you :) – undermind May 28 '14 at 13:43