我使用嵌套的 ItemsControl 来显示分层数据。问题是即使数据很少,这也非常慢。它还完全阻塞 UI 线程,直到加载数据。我在这里做错了什么?
生成演示数据并将其绑定到 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>