【问题标题】:Backup and restore state of ListBox ItemsSourceListBox ItemsSource 的备份和恢复状态
【发布时间】:2016-07-28 03:02:01
【问题描述】:

我想在保持 ListBox ItemsSource 之前的状态(即当前的水平和垂直滚动偏移量以及选择)的同时,先取消填充,然后再重新填充 ListBox。

这是我目前的代码:

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 时,滚动属性和选择被清除。

【问题讨论】:

    标签: c# wpf listbox


    【解决方案1】:

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

    由于 ListView 是从 ListBox 继承的,因此 ListView 中的 ListBox 的所有功能也将具有。

    适用于 Windows 8.1 及更高版本

    我为什么要推荐?因为ListView有ListViewPersistenceHelper可以帮你保存和获取ListView的Relative Scroll位置。

    参见Example 了解如何实现 ListViewPersistenceHelper

    对于您的选择,您可以在 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;
    

    现在,当您再次填充它时,分配滚动查看器的 ScrollToVerticalOffset 以便它可以返回到相同的位置。

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

    希望这会有所帮助。

    【讨论】:

    • 我正在使用 WPF,您的链接似乎适用于 Windows 应用程序(Windows 8 和 10)。我说的对吗?
    • 啊,我明白了。我正在编辑列表框本身的答案。
    • @Drarig29 这有帮助吗?或者您需要更多与该问题相关的信息吗?
    猜你喜欢
    • 1970-01-01
    • 2012-01-14
    • 2011-07-02
    • 2021-08-14
    • 2014-07-24
    • 2013-12-03
    • 2019-06-30
    • 2014-08-10
    • 1970-01-01
    相关资源
    最近更新 更多