可怕的Silverlight表现——ListBox

3
我试图创建一个带有相当强大的DataTemplate的ListBox,但是性能极其慢。在我家里的电脑上(约2.5年前),绑定80行需要大约4-6秒的时间。在我的工作电脑上(64位/双核心),时间缩短到约2.5秒,但仍然非常慢(150行需要大约4-5秒)。
所有数据都是纯POCO,具有随机生成的数据。这个应用程序中没有任何服务(尚未)。数据的随机生成根本不需要任何时间 - 在ObservableCollection更新之前,我(粗略地)使用MessageBox.Show来显示数据。(我甚至尝试过绑定到一个普通的List - 更慢了)。此外,我已经在Chrome和IE上尝试过了。
好的,这是代码,如果我忘记了什么,请告诉我。正如我所说,这是一个强大的DataTemplate,但我认为这就是SL / WPF的重点 - 它们可以做这样酷的东西。我真的希望我做错了什么 - 我传递的是孩子大小的数据量。
编辑 - 为了把答案放在最上面,你永远不会告诉一个ListBox使用StackPanel作为ItemsPanelTemplate的原因 - 它默认垂直堆叠项目,但指定一个StackPanel是多余的,也会完全破坏性能。我删除了ItemsPanelTemplate,它运行得非常好。
<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>

来自 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/Bullet_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>

看起来最后那两个ListBox是罪魁祸首 - 有没有一种方法可以显示这些嵌套列表,使SL不会出错? - Adam Rackis
你尝试过对它们设置固定的宽度和高度吗? - Falcon
是的,还有第二列的固定宽度在顶部 def。 - Adam Rackis
2个回答

2

您已将默认的VirtualPanel更改为StackPanel。为了获得更好的性能,我建议使用默认的ItemsPanel。


1

以下是性能不佳的两个最常见原因:

  • 难以计算的布局(这很可能是您的情况)。尝试设置固定的宽度和高度,避免拉伸。
  • 图形效果,如DropShadow,是在软件中渲染的:可能像Amazon-View这样的组件使用了它们。

您可以随时使用性能工具,例如Wpf Performance Suite中的Perforator来深入了解问题。它一定会帮助您找到瓶颈!


好像最后那两个listBox是Silverlight卡住的原因。我把它们移除了,程序就跑得飞快。我甚至试过把它们上面的所有模板都删掉,只显示类名,但速度还是一样慢。由于Silverlight似乎不喜欢在一个ListBox中嵌套另一个ListBox,有没有其他方法可以实现我想要的效果呢?(我还给它们添加了固定宽度,但仍然无济于事) - Adam Rackis
此外,那个性能工具似乎只适用于WPF - 是否有Silverlight版本?这对我现在没有帮助,因为我认为我已经找到了问题所在,但以后可能会派上用场。 - Adam Rackis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接