2011-12-31 2 views
3

관찰 가능한 문자열 모음에 바인딩 된 listview가 있습니다. 이 컬렉션은 매우 빠르게 추가됩니다 (최대 30 분의 시간 동안). 가상화를 사용하지 않고 매우 느리게 실행되고있었습니다. 그러나, 아래로 목록 자동 스크롤을했다 익스텐더를 추가 한 후, 다시 매우 느렸다 다음과 같이 내가 목록보기가 있습니다.AutoScroll 성능 (느림)으로 가상화 된 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가 있습니다. 그러나 당신이 두려워 하듯이 그것은 매우 느립니다. 나는 또한 performant 솔루션에 관심이있을 것이다. – Amenti

답변

1

listBox.ScrollIntoView(lastItem)을 사용하면 모든 항목 삽입/삭제/수정 작업에 대해 ListBox 컨트롤이 업데이트됩니다.

ListBox 항목이 수정 될 때마다 listBox.SuspendLayout()을 호출하고 항목을 삽입/삭제/수정 한 후에 listBox.ResumeLayout()을 사용하십시오. 나는 이것이 당신의 문제를 해결할 것이라고 믿습니다.

또한 ListBox에 많은 항목이있을 경우; DoubleBufferedListBox를 사용하면 컨트롤이 매우 부드럽게 업데이트하는 데 도움이됩니다.