2013-07-19 76 views
1

我使用嵌套的ItemsControl來顯示分層數據。問題在於,即使數據很少,這個速度也非常緩慢。它也完全阻塞UI線程,直到數據被加載。我在這裏做錯了什麼?嵌套ItemsControl的大量性能問題

代碼,以生成演示數據,並將其綁定到ItemsControl的:

private void SetupDemodata() 
    { 
     ObservableCollection<Folder> demoData = new ObservableCollection<Folder>(); 

     const int numberOfFolders = 1; 
     const int numberOfFiles = 1; 
     const int numberOfLines = 300; 

     Random randContentLength = new Random(); 


     for(int indexFolders = 0; indexFolders <= numberOfFolders; indexFolders++) 
     { 
      Folder newFolder = new Folder {FolderName = string.Format("DemoFolder {0}", indexFolders)}; 

      for(int indexFiles = 0; indexFiles <= numberOfFiles; indexFiles++) 
      { 
       File newFile = new File {FileName = string.Format("DemoFile {0} -> {1}", indexFolders, indexFiles)}; 


       for(int indexLines = 0; indexLines <= numberOfLines; indexLines++) 
       { 
        newFile.ContentLines.Add(new FileContentLine 
         { 
          LineContent = GetRandomString(randContentLength.Next(80)), 
          LineNumber = indexLines 
         }); 
       } 
       newFolder.Files.Add(newFile); 
      } 
      demoData.Add(newFolder); 
     } 

     this.icFolders.ItemsSource = demoData; 
    } 

    private static readonly Random random = new Random(); 
    private static string GetRandomString(int length) 
    { 
     length = Math.Max(length, 3); 
     byte[] bytes = new byte[length]; 
     random.NextBytes(bytes); 
     return Convert.ToBase64String(bytes).Substring(0, length); 
    } 

的車型:

public class Folder 
{ 
    public List<File> Files { get; set; } 
    public string FolderName { get; set; } 
    public Folder(){ this.Files = new List<File>();} 
} 

public class File 
{ 
    public List<FileContentLine> ContentLines { get; set; } 
    public string FileName { get; set; } 
    public File() { this.ContentLines = new List<FileContentLine>(); } 
} 

public class FileContentLine 
{ 
    public int LineNumber { get; set; } 
    public string LineContent { get; set; } 
} 

而XAML:

<Grid> 
    <ScrollViewer VerticalScrollBarVisibility="Auto"> 
     <Grid> 

      <Grid> 
       <ItemsControl Grid.Row="0" x:Name="icFolders" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" > 

        <!-- Folder --> 
        <ItemsControl.ItemTemplate> 
         <DataTemplate DataType="{x:Type local:Folder}"> 
          <Grid Margin="0"> 
           <Grid.RowDefinitions> 
            <RowDefinition Height="Auto"/> 
            <RowDefinition Height="Auto"/> 
            <RowDefinition Height="*"/> 
           </Grid.RowDefinitions> 
           <Border Grid.Row="0" BorderThickness="0,1,0,1" BorderBrush="#c5c5c5"> 
            <Grid Grid.Row="0" Style="{StaticResource styleGridGradient}"> 
             <Grid> 
              <Grid.ColumnDefinitions> 
               <ColumnDefinition Width="Auto" /> 
               <ColumnDefinition Width="*" /> 
               <ColumnDefinition Width="Auto" /> 
              </Grid.ColumnDefinitions> 
              <Label Grid.Column="0" Style="{StaticResource styleLabelBold}" Content="{Binding FolderName}" /> 
              <Label Grid.Column="2" Style="{StaticResource styleLabelBold}" Content="{Binding Files.Count}" /> 
             </Grid> 
            </Grid> 
           </Border> 
           <Border Grid.Row="1" BorderThickness="0,1,0,1" BorderBrush="#c5c5c5"> 
            <Grid Style="{StaticResource styleGridGradient}"> 
             <Label Foreground="#666666" 
             Margin="5,0,0,0" 
             HorizontalAlignment="Stretch" 
             Content="{Binding FolderName}" /> 
            </Grid> 
           </Border> 

           <!--Files --> 
           <ItemsControl Grid.Row="2" ItemsSource="{Binding Files}" > 
            <ItemsControl.ItemTemplate> 
             <DataTemplate DataType="{x:Type local:File}"> 
              <Grid Margin="0"> 
               <Grid.RowDefinitions> 
                <RowDefinition Height="Auto" /> 
                <RowDefinition Height="*" /> 
               </Grid.RowDefinitions> 
               <Border Grid.Row="0" BorderThickness="0,1,0,1" BorderBrush="#c5c5c5"> 
                <Grid Style="{StaticResource styleGridGradient}"> 
                 <Grid.ColumnDefinitions> 
                  <ColumnDefinition Width="*"/> 
                  <ColumnDefinition Width="Auto"/> 
                 </Grid.ColumnDefinitions> 

                 <Label Grid.Column="0" 
                  Foreground="#666666" 
                  Margin="5,0,0,0" 
                  VerticalContentAlignment="Center" 
                  VerticalAlignment="Center" 
                  Content="{Binding FileName}" /> 

                 <Button Grid.Column="1" Margin="5" MaxHeight="25" Content="Open File"/> 

                </Grid> 
               </Border> 

               <!-- Lines --> 
               <ItemsControl Grid.Row="1" ItemsSource="{Binding ContentLines}" Background="White"> 
                <ItemsControl.ItemTemplate> 
                 <DataTemplate DataType="{x:Type local:FileContentLine}"> 
                  <Grid Margin="0" Height="20"> 
                   <Grid.ColumnDefinitions> 
                    <ColumnDefinition Width="35" /> 
                    <ColumnDefinition Width="20" /> 
                    <ColumnDefinition Width="*" /> 
                   </Grid.ColumnDefinitions> 

                   <Border Grid.Column="0" BorderThickness="0,0,1,0" BorderBrush="#c5c5c5"> 
                    <ToggleButton> 
                     <Label Content="{Binding LineNumber}" /> 
                    </ToggleButton> 
                   </Border> 

                   <Border Grid.Column="2" BorderThickness="0,0,1,0" BorderBrush="#c5c5c5"> 
                    <Border Grid.Column="2" BorderThickness="0,1,0,1" BorderBrush="Red"> 
                     <Label Height="20" Content="+" HorizontalAlignment="Center" /> 
                    </Border> 
                   </Border> 

                   <Border Grid.Column="3" BorderThickness="0,1,0,1" BorderBrush="Gray"> 
                    <TextBox Height="20" IsReadOnly="True" 
                      VerticalAlignment="Center" 
                      VerticalContentAlignment="Center" 
                      Text="{Binding LineContent}" /> 
                   </Border> 
                  </Grid> 
                 </DataTemplate> 
                </ItemsControl.ItemTemplate> 
               </ItemsControl> 

              </Grid> 
             </DataTemplate> 
            </ItemsControl.ItemTemplate> 
           </ItemsControl> 

          </Grid> 
         </DataTemplate> 
        </ItemsControl.ItemTemplate> 
       </ItemsControl> 
      </Grid> 
     </Grid> 
    </ScrollViewer> 
</Grid> 
+0

閱讀在WPF – whoisthis

+0

虛擬化還認爲你是顯示您的分層數據可能要考慮一下懶加載以及 – whoisthis

+0

我知道虛擬化的,但我不知道如何在我的嵌套的情況下應用它。 – user1130329

回答

0

以下屬性添加到所有ItemsControl s(根和嵌套):

<ItemsControl.ItemsPanel> 
    <ItemsPanelTemplate> 
    <VirtualizingStackPanel/> 
    </ItemsPanelTemplate> 
</ItemsControl.ItemsPanel>