ListBox ItemsSource的备份和恢复状态

时间:2016-07-27 16:32:49

标签: c# wpf listbox

我想减少然后重新填充ListBox,同时保持ListBox ItemsSource的前一个状态(也就是说当前的水平和垂直滚动偏移以及选择)。

这是我目前的代码:

ObservableCollection<string> items = new ObservableCollection<string>();

public MainWindow() {
    InitializeComponent();

    for (int i = 1; i < 25; i++) items.Add("");

    listBox.ItemsSource = items;
}

private void btnDepopulate_Click(object sender, RoutedEventArgs e) {
    //how to backup the state?
    listBox.ItemsSource = null;
}

private void btnRepopulate_Click(object sender, RoutedEventArgs e) {
    listBox.ItemsSource = items;
    //how to restore the state?
}

使用此代码,当我重新填充ListBox时,滚动属性和选择将被清除。

1 个答案:

答案 0 :(得分:2)

我强烈建议您将列表框更改为Listview。 Why?

由于ListView继承自ListBox,因此您将在ListView中具有ListBox的所有功能。

适用于Windows 8.1及更高版本

为什么我推荐?因为ListView具有ListViewPersistenceHelper,这将帮助您保存和检索ListView的相对滚动位置。

有关如何实现ListViewPersistenceHelper

的信息,请参阅此Example

对于您的选择,您可以在App.xaml中创建全局变量。

public int ListViewScrollSelectedIndex;

保存ListView的SelectedIndex。重新填充ListView时,可以将其设置为

ListView.SelectedIndex  = ListViewScrollSelectedIndex;

这应该解决这两个问题。

对于WPF

如果您想获取列表框的当前滚动位置,您需要先获得对其滚动查看器的访问权限。

以下是将为您提取滚动查看器的代码。

    private ScrollViewer GetObjectScrollViewer(DependencyObject dependencyObject)
    {
        if (dependencyObject is ScrollViewer)
            return dependencyObject as ScrollViewer;

        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject); i++)
        {
            var _scrollViewer = GetObjectScrollViewer(VisualTreeHelper.GetChild(dependencyObject, i));
            if (_scrollViewer != null) return _scrollViewer;
        }
        return null;
    }

ScrollViewer 有一个 VerticalOffset ,可以为您提供Scrollviewer的垂直位置。当你去减少ListBox时,将它保存为在App.xaml中创建的变量的双精度。

var _ListBoxScrollViewer = GetObjectScrollViewer(MyListBox);
ScrollPosition = _ListBoxScrollViewer.VerticalOffset;

现在当你再次填充它时,请指定scrollviewer的ScrollToVerticalOffset,以便它可以返回到相同的位置。

var _ListBoxScrollViewer = GetObjectScrollViewer(ListBox);
if (_ListBoxScrollViewer != null) _ListBoxScrollViewer.ScrollToVerticalOffset(ScrollPosition);

希望这有助于。