2011-12-31 24 views
3

我有一個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方法是如何工作的,但我擔心,它是否定虛擬化的性能提升。另一個猜測是,要滾動到列表中的位置,它必須找到對象而不是跳到索引。

所以我的問題是:我如何有一個列表視圖更新非常快,大量的條目可以滾動到底部而不會放慢一切?

+0

在Windows 8.1 ListView中有一個ScrollIntoView-Method。但是,如你所擔心的那樣,它速度很慢。我也會對高性能解決方案感興趣。 – Amenti 2014-05-10 11:26:28

回答

1

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

每當ListBox項目被修改時,請致電listBox.SuspendLayout(),並在插入/刪除/修改項目後使用listBox.ResumeLayout()。我相信這會解決你的問題。

此外,如果您的ListBox將有很多項目;我建議使用DoubleBufferedListBox這將有助於控制更新非常順利。