我想减少然后重新填充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时,滚动属性和选择将被清除。
答案 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);
希望这有助于。