嵌套ItemsControl的大量性能问题 [英] Massive performance issue with nested ItemsControl
本文介绍了嵌套ItemsControl的大量性能问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我使用嵌套的ItemsControl来显示分层数据.问题是,即使只有很少的数据,这也非常慢.它还会完全阻塞UI-Thread,直到加载数据为止.我在这里做错什么了?
I use a nested ItemsControl to display hierarchical data. Problem is that this is terribly slow even with little data. Its also blocking the UI-Thread completely until data is loaded. What am I doing wrong here?
用于生成演示数据并将其绑定到ItemsControl的代码:
Code to generate Demo-Data and bind it to the 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>
推荐答案
将以下属性添加到所有ItemsControl
(root和嵌套属性)中:
Add the following property to all your ItemsControl
s (root and nested ones):
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
这篇关于嵌套ItemsControl的大量性能问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文