I'm trying to create a ListBox with a decently robust DataTemplate. The problem is, performance is unimaginably slow. On my home computer - about 2.5 years old, it takes about 4-6 seconds to bind 80 rows. On my work computer (64 bit / dual core) the time is down to about 2.5 seconds, but still - seems really slow (and 150 rows take about 4-5 seconds)
All data are pure POCO, with randomly generated data. There are absolutely no services anywhere in this app (yet). The random generation of the data is not taking any time at all -I'm (crudely) doing a MessageBox.Show after data is created, right before the ObservableCollection is updated. (I even tried binding to a plain old List - even slower). Also, I've tried it on both Chrome and IE.
Ok, here's the code, if I left anything out, let me know. Like I said, it's a robust DataTemplate, but I thought that was the point of SL / WPF - that they could do cool stuff like this. I sure hope I'm doing something wrong - these are child-sized amount of Data I'm passing.
EDIT - just to put the answer up top, there's no reason you would ever tell a ListBox to use a StackPanel as the ItemsPanelTemplate - it displays items stacked vertically by default, but, not only is specify a StackPanel like this superfluous, it also completely destroys performance. I deleted the ItemsPanelTemplate, and it worked beautifully.
<ListBox ItemsSource="{Binding Path=BookSource_oc}" ItemTemplate="{StaticResource BookDataTemplateMedium}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" HorizontalAlignment="Stretch">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Margin="2" HorizontalAlignment="Stretch" x:Name="stackPanelItemsPanel">
</StackPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
from app.XAML:
<DataTemplate x:Key="BookDataTemplateMedium">
<Border CornerRadius="3" BorderThickness="2" BorderBrush="Black" Background="White">
<Grid Margin="3">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="140"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- removing this just to be sure it's not cause of bad perf <Image Grid.Column="0" Stretch="None" VerticalAlignment="Center" HorizontalAlignment="Left" Source="{Binding MediumImgURI}" Margin="7,0,0,0"/>-->
<StackPanel HorizontalAlignment="Left" Grid.Column="1" Margin="5,0,10,0">
<TextBlock FontWeight="Bold" TextTrimming="WordEllipsis" Foreground="Black" ToolTipService.ToolTip="{Binding CurrentBook.Title}" Text="{Binding CurrentBook.Title}"/>
<Grid Margin="0,10,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"></ColumnDefinition>
<ColumnDefinition Width="270"></ColumnDefinition>
<ColumnDefinition Width="270"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="150"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Grid.Column="0">
<local:vwAmazonReviewsRightToLeft></local:vwAmazonReviewsRightToLeft>
<local:vwPublisherInfoWithDateLeftToRight Margin="0,5,0,0"></local:vwPublisherInfoWithDateLeftToRight>
<local:vwPagesInfo></local:vwPagesInfo>
<StackPanel Orientation="Horizontal">
<TextBlock>Is Read </TextBlock>
<Image Margin="8,0,0,0" Stretch="None" Source="{Binding IsReadImgUri, Mode=OneWay}"></Image>
</StackPanel>
<HyperlinkButton Margin="0,5,0,0" NavigateUri="http://www.google.com" Content="View at Amazon"/>
</StackPanel>
<ListBox Grid.Column="1" Margin="0,2,0,0" ScrollViewer.HorizontalScrollBarVisibility="Disabled" VerticalAlignment="Top" BorderThickness="0" ItemsSource="{Binding CurrentBook.Subjects}" ItemTemplate="{StaticResource dataTemplateSubjectsLB}" />
<ListBox Grid.Column="2" Margin="10,2,0,0" ScrollViewer.HorizontalScrollBarVisibility="Disabled" VerticalAlignment="Top" BorderThickness="0" ItemsSource="{Binding CurrentBook.Authors}" ItemTemplate="{StaticResource dataTemplateAuthorsLB}" />
</Grid>
</StackPanel>
</Grid>
</Border>
</DataTemplate>
<DataTemplate x:Key="dataTemplateSubjectsLB">
<StackPanel>
<StackPanel Orientation="Horizontal">
<Image Source="Img/Bullets/B开发者_如何学运维ullet_Purple.png"></Image>
<TextBlock ToolTipService.ToolTip="{Binding Name}" Text="{Binding Name}"></TextBlock>
</StackPanel>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="dataTemplateAuthorsLB">
<StackPanel>
<StackPanel Orientation="Horizontal">
<Image Source="Img/Bullets/Bullet_Red.png"/>
<TextBlock ToolTipService.ToolTip="{Binding Name}" Text="{Binding Name}"/>
</StackPanel>
</StackPanel>
</DataTemplate>
You've changed default VirtualPanel to StackPanel. For better performance I recommend use default ItemsPanel.
These are two of the most common reasons for a bad performance:
- Layouts that are difficult to compute (which is most likely the case in your example). Try setting fixed widths and heights and avoid stretches.
- Graphics-Effects like DropShadow which are rendered in Software: Maybe a component like the Amazon-View uses them
You can always use Performance-Tools like Perforator from the Wpf Performance Suite to dig into the issue. It'll help you find the bottleneck for sure!
精彩评论