具有AutoScroll性能的虚拟ListView(慢)

时间:2011-12-31 19:02:34

标签: c# performance xaml listview

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

所以我的问题是:如何让列表视图快速更新,并且可以滚动到底部而不会减慢所有内容的大量条目?

1 个答案:

答案 0 :(得分:1)

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

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

此外,如果您的ListBox将包含大量项目;我建议使用DoubleBufferedListBox,这将有助于控件更新非常流畅。