WPF i MVVM: Zapisz pozycję ScrollViewer i ustaw ją przy ponownym załadowaniu


Mam ScrollViewer dla StackPannel. Użytkownicy chcą zachować pozycję ScrollViewer, więc gdy aplikacja zostanie ponownie załadowana z ich danymi, StackPannel pokaże elementy, które przeglądali wcześniej. Nie ma to nic wspólnego z tym, które elementy zostały wybrane, jeśli w ogóle, tylko mikstura ScrollViewer w stosunku do elementów StackPannel.
Tak więc, jeśli StackPannel ma 50 elementów, a ScrollViewer przewija się tak, że 20-25 elementów z StackPannel jest widocznych, muszę ponownie załadować aplikację i przewinąć w dół do tej pozycji bez wybierania elementu.
Ponadto używam MVVM i chciałbym ustawić pozycję ScrollViewer za pomocą kodu ViewModel.
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Poniższy przykład zapisze przesunięcie przewijania w maszynie wirtualnej i załaduje go po otwarciu (TestWindow). Powinieneś także zapisać i załadować rozmiar okna, ponieważ najprawdopodobniej wpłynie to również na przesunięcie przewijania. Jeśli chcesz, możesz przenieść kod w TestWindow do dołączonej klasy zachowania.
XAML:
<Window x:Class="ScrollTest.TestWindow"
xmlns="[url=http://schemas.microsoft.com/winfx/2006/xaml/presentation"]http://schemas.microsoft.com/w ... ot%3B[/url]
xmlns:x="[url=http://schemas.microsoft.com/winfx/2006/xaml"]http://schemas.microsoft.com/winfx/2006/xaml"[/url]
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>

Na kod:
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; }
}
}

Za pomocą:
private void OnOpenOpenTestWindow(object sender, RoutedEventArgs e)
{
TestWindow testWindow = new TestWindow();
testWindow.DataContext = _vm;
testWindow.Show();
}private VM _vm = new VM();
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Możesz również ustawić pozycję ScrollViewer, wywołując
ScrollToVerticalOffset.
contentScrollViewer.ScrollToVerticalOffset(50);
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Czy rozważałeś użycie właściwości ScrollViewer.ScrollInfo? Zawiera elementy reprezentujące przesunięcie każdego paska przewijania (

HorizontalOffset
http://msdn.microsoft.com/en-u ... .aspx
,

VerticalOffset
http://msdn.microsoft.com/en-u ... t.aspx), do którego możesz spróbować przyciągnąć. Jednak nie jestem pewien, czy są to właściwości zależności.
Inną opcją jest znalezienie rzeczywistych kontrolek
ScrollBar
w drzewie wizualnym i powiązanie ich z właściwością
Position
każdego z nich.

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się