虚拟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方法是如何工作的,但我担心它会否定虚拟化的性能提升。我的另一种猜测是,要滚动到列表中的某个位置,它必须找到对象,而不仅仅是跳到索引。

所以我的问题是:我如何有一个列表视图,更新得非常快,有很多条目,可以滚动到底部,而不会减慢一切?

虚拟ListView与自动滚动性能(慢)

使用listBox.ScrollIntoView(lastItem)更新每个条目插入/删除/修改操作的ListBox控件。

每当ListBox项被修改时,调用listBox.SuspendLayout(),插入/删除/修改项后使用listBox.ResumeLayout()。我相信这会解决你的问题。

同样,如果你的ListBox将有很多项目;我建议使用DoubleBufferedListBox,这将有助于控件的更新非常顺利。