Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF & MVVM: Save ScrollViewer Postion And Set When Reloading

Tags:

c#

mvvm

wpf

I've got a ScrollViewer for a StackPannel. The users want the save the position of the ScrollViewer so when the application is re-loaded with their data the StackPannel will show the items they were viewing before. It has nothing to do with which items were selected, if any, merely the potion of the ScrollViewer in relation to the StackPannel items. So, if the StackPannel has 50 items and the ScrollViewer is scrolled so that items 20-25 of the StackPannel are visible I need to reload the application and scroll down to that position without selecting an item. Also, I'm using MVVM and I'd like to set the ScrollViewer position via the ViewModel code too.

like image 879
mike Avatar asked Aug 10 '10 16:08

mike


1 Answers

Below sample will store scroll offset in a VM and load it when window (TestWindow) opens. You should also store and load size of window since it will most likely affect scroll offset as well. If you want to you can move the code behind in TestWindow to an attached behavior class.

XAML:

<Window x:Class="ScrollTest.TestWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="TestWindow" Height="200" Width="300"
    Loaded="OnLoaded"
    Closing="OnClosing">
    <Grid>
        <ScrollViewer Name="_scroll"  VerticalScrollBarVisibility="Auto">
            <StackPanel>
                <Button Content="Click me" />
                <Button Content="Click me" />
                <Button Content="Click me" />
                <Button Content="Click me" />
                <Button Content="Click me" />
                <Button Content="Click me" />
                <Button Content="Click me" />
                <Button Content="Click me" />
                <Button Content="Click me" />
                <Button Content="Click me" />
                <Button Content="Click me" />
                <Button Content="Click me" />
                <Button Content="Click me" />
                <Button Content="Click me" />
                <Button Content="Click me" />
                <Button Content="Click me" />
            </StackPanel>
        </ScrollViewer>
    </Grid>
</Window>

Code behind:

using System;
using System.ComponentModel;

using System.Windows;


namespace ScrollTest
{
    public partial class TestWindow : Window
    {
        public TestWindow()
        {
            InitializeComponent();
        }

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            _scroll.ScrollToVerticalOffset((DataContext as VM).ScrollOffset);
        }

        private void OnClosing(object sender, CancelEventArgs e)
        {
            (DataContext as VM).ScrollOffset = _scroll.VerticalOffset;
        }
    }

    public class VM
    {
        public double ScrollOffset { get; set; }
    }
}

Usage:

private void OnOpenOpenTestWindow(object sender, RoutedEventArgs e)
{
    TestWindow testWindow = new TestWindow();
    testWindow.DataContext = _vm;
    testWindow.Show();
}

private VM _vm = new VM();
like image 114
Wallstreet Programmer Avatar answered Sep 18 '22 06:09

Wallstreet Programmer