WPF和MVVM:在重新加载时保存ScrollViewer位置和设置

mik*_*ike 4 c# wpf mvvm

我有一个StackPannel的ScrollViewer.用户希望保存的ScrollViewer中的位置,所以当应用程序被重新加载他们的数据StackPannel将展示他们之前所查看的项目.它与选择的项目(如果有的话)无关,仅与ScrollViewer相对于StackPannel项目的部分有关.所以,如果StackPannel有50个项目和ScrollViewer中滚动,使项目StackPannel 20-25是可见的,我需要重新加载应用程序和向下滚动到该位置没有选择项目.此外,我正在使用MVVM,我也希望通过ViewModel代码设置ScrollViewer位置.

Wal*_*mer 5

下面的示例将在VM中存储滚动偏移量,并在窗口(TestWindow)打开时加载它.您还应该存储和加载窗口大小,因为它很可能也会影响滚动偏移.如果您愿意,可以将TestWindow中的代码移动到附加的行为类.

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>
Run Code Online (Sandbox Code Playgroud)

代码背后:

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; }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

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

private VM _vm = new VM();
Run Code Online (Sandbox Code Playgroud)