虚拟ListView与自动滚动性能(慢)
本文关键字:性能 滚动 ListView 虚拟 | 更新日期: 2023-09-27 18:19:06
我有一个listview绑定到一个字符串的可观察集合。这个集合被添加到非常快(时间长达30分钟)。我补充说,在没有启用虚拟化的情况下,它运行得非常慢,但它很棒。然而,在添加了一个扩展程序,使列表自动滚动到底部之后,它又变得非常慢。,我有listview如下:
<ListView Background="Transparent"
ItemsSource="{
Binding Source={
StaticResource MyViewModel}
,Path=MyList}"
VirtualizingStackPanel.IsVirtualizing="True"
ScrollViewer.CanContentScroll="True"
ScrollViewer.VerticalScrollBarVisibility="Visible">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
滚动到最后,我使用一些扩展程序,我在网上找到:
/// <summary>
/// This method will be called when the AutoScrollToEnd
/// property was changed
/// </summary>
/// <param name="s">The sender (the ListBox)</param>
/// <param name="e">Some additional information</param>
public static void OnAutoScrollToEndChanged(
DependencyObject s
, DependencyPropertyChangedEventArgs e)
{
var listBox = s as ListBox;
var listBoxItems = listBox.Items;
var data = listBoxItems.SourceCollection as INotifyCollectionChanged;
var scrollToEndHandler =
new NotifyCollectionChangedEventHandler(
(s1, e1) =>
{
if (listBox.Items.Count > 0)
{
object lastItem = listBox.Items[
listBox.Items.Count - 1];
Action action = () =>
{
listBoxItems.MoveCurrentTo(lastItem);
listBox.ScrollIntoView(lastItem);
};
action.Invoke();
}
});
if ((bool)e.NewValue)
data.CollectionChanged += scrollToEndHandler;
else
data.CollectionChanged -= scrollToEndHandler;
}
我不知道ScrollIntoView方法是如何工作的,但我担心它会否定虚拟化的性能提升。我的另一种猜测是,要滚动到列表中的某个位置,它必须找到对象,而不仅仅是跳到索引。
所以我的问题是:我如何有一个列表视图,更新得非常快,有很多条目,可以滚动到底部,而不会减慢一切?
使用listBox.ScrollIntoView(lastItem)
更新每个条目插入/删除/修改操作的ListBox控件。
每当ListBox项被修改时,调用listBox.SuspendLayout()
,插入/删除/修改项后使用listBox.ResumeLayout()
。我相信这会解决你的问题。
同样,如果你的ListBox将有很多项目;我建议使用DoubleBufferedListBox,这将有助于控件的更新非常顺利。