2014-05-10 5 views
0

가상화가 활성화 된 ListBox을 생성하고 모든 항목 모양을 업데이트하면 매우 빠르게 작동합니다. 그러나 내가 천천히 ListBox의 모든 항목을 스크롤 한 다음 모든 항목 모양을 업데이트하는 데 많은 시간이 걸립니다. VirtualizingStackPanel은 뷰포트가 떨어질 때 아이템을 파괴하지 않기 때문에 생각합니다. 이 동작을 재현 할 수있는 간단한 응용 프로그램을 작성했습니다.VirtualizingStackPanel은 신선 할 때만 빠릅니다. 어떻게 해결할 수 있습니까?

코드 :

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     for(int i = 0; i < 5000; ++i) // creating 5k text boxes 
      MyList.Items.Add(new TextBox() { Text = CurrText }); 
    } 

    private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     GC.Collect(); 
     n = (n + 1) % 2; // switch 0 to 1 or 1 to 0 
     foreach (var item in MyList.Items) 
      ((TextBox)item).Text = CurrText; // set new text 
    } 

    static int n = 0; 
    string CurrText { get { return new string(n.ToString()[0], 50); } } 
} 

XAML :

<Window x:Class="VPanel.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="700" Width="525"> 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="5*"/> 
      <RowDefinition Height="*"/> 
     </Grid.RowDefinitions> 
     <ListBox Name="MyList" VirtualizingStackPanel.IsVirtualizing="True"/> 
     <Button Grid.Row="1" Content="UpdateText" Click="Button_Click"/> 
    </Grid> 
</Window> 

버튼 "UPDATETEXT"업데이트 모든 텍스트 상자의 텍스트를 클릭. 스크롤러를 드래그하여 끝까지 천천히 스크롤하면 "UpdateText"버튼이 큰 지연을 가지고 클릭합니다.

답변

0

TextBoxes을 수동으로 만들지 마십시오.

단어 "가상화"는 사용자 인터페이스의 일부는 (UI) 요소 항목이 화면에 표시되는 기초 데이터 아이템들의 큰 수에서 생성되는 기술을 지칭한다. 일부 요소 만 화면에 표시 될 때 많은 UI 요소를 생성하면 응용 프로그램의 성능에 부정적인 영향을 미칠 수 있습니다..

UI 항목을 수동으로 만들어 가상화하기에 너무 늦었습니다. 바인딩을 사용하면 필요할 때마다 ItemTemplate에서 TextBox을 만듭니다. 또한 현재 뷰에 없으면 TextBox.Text 값을 새로 고치지 않습니다. 그 대신 TextBoxesObservableCollection을 만들고 그에서 작동하도록 MainWindow을 변경하려면 다음을 수행 TextBoxes 목록 속성에 바인딩하는 XAML을

public partial class MainWindow : Window 
{ 
    private readonly ObservableCollection<string> _textBoxes = new ObservableCollection<string>(); 

    public ICollection<string> TextBoxes { get { return _textBoxes; } } 

    private int n = 0; 
    private string CurrText { get { return new string(n.ToString()[0], 50); } } 

    public MainWindow() 
    { 
     for (int i = 0; i < 5000; ++i) _textBoxes.Add(CurrText); 
     InitializeComponent(); 
     DataContext = this; 
    } 

    private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     n = (n + 1) % 2; // switch 0 to 1 or 1 to 0 
     for (int i = 0; i < _textBoxes.Count; i++) _textBoxes[i] = CurrText; 
    } 
} 

을 다음으로 변경

<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="5*"/> 
     <RowDefinition Height="*"/> 
    </Grid.RowDefinitions> 
    <ListBox ItemsSource="{Binding TextBoxes}"> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <TextBox Text="{Binding Path=., Mode=TwoWay}"/> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 
    <Button Grid.Row="1" Content="UpdateText" Click="Button_Click"/> 
</Grid>