When using MVVM we are disposing view (while viewmodel persists).
My question is how to restore ListView state when creating new view as close as possible to one when view was disposed?
ScrollIntoView works only partially. I can only scroll to a single item and it can be on top or bottom, there is no control of where item will appears in the view.
I have multi-selection (and horizontal scroll-bar, but this is rather unimportant) and someone may select several items and perhaps scroll further (without changing selection).
Ideally binding ScrollViewer of ListView properties to viewmodel would do, but I am afraid to fall under XY problem asking for that directly (not sure if this is even applicable). Moreover this seems to me to be a very common thing for wpf, but perhaps I fail to formulate google query properly as I can't find related ListView+ScrollViewer+MVVM combo.
Is this possible?
I have problems with ScrollIntoView and data-templates (MVVM) with rather ugly workarounds. Restoring ListView state with ScrollIntoView sounds wrong. There should be another way. Today google leads me to my own unanswered question.
I am looking for a solution to restore ListView state. Consider following as mcve:
public class ViewModel
{
public class Item
{
public string Text { get; set; }
public bool IsSelected { get; set; }
public static implicit operator Item(string text) => new Item() { Text = text };
}
public ObservableCollection<Item> Items { get; } = new ObservableCollection<Item>
{
"Item 1",
"Item 2",
"Item 3 long enough to use horizontal scroll",
"Item 4",
"Item 5",
new Item {Text = "Item 6", IsSelected = true }, // select something
"Item 7",
"Item 8",
"Item 9",
};
}
public partial class MainWindow : Window
{
ViewModel _vm = new ViewModel();
public MainWindow()
{
InitializeComponent();
}
void Button_Click(object sender, RoutedEventArgs e) => DataContext = DataContext == null ? _vm : null;
}
xaml:
<StackPanel>
<ContentControl Content="{Binding}">
<ContentControl.Resources>
<DataTemplate DataType="{x:Type local:ViewModel}">
<ListView Width="100" Height="100" ItemsSource="{Binding Items}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Text}" />
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="IsSelected" Value="{Binding IsSelected}" />
</Style>
</ListView.ItemContainerStyle>
</ListView>
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
<Button Content="Click"
Click="Button_Click" />
</StackPanel>
This is a window with ContentControl which content is bound to DataContext (toggled by button to be either null or ViewModel instance).
I've added IsSelected support (try to select some items, hiding/showing ListView will restore that).
The aim is: show ListView, scroll (it's 100x100 size, so that content is bigger) vertically and/or horizontally, click button to hide, click button to show and at this time ListView should restore its state (namely position of ScrollViewer).