【问题标题】:ListBox VirtualizingStackPanel.VirtualizationMode="Recycling" is not working in Windows Phone 7.5ListBox VirtualizingStackPanel.VirtualizationMode="Recycling" 在 Windows Phone 7.5 中不起作用
【发布时间】:2012-12-20 14:19:19
【问题描述】:

我在正在开发的 Windows Phone 7.5 应用程序中遇到了一些性能问题。我有一个使用VirtualizationMode="Recycling"ListBox 和一个DataTemplate。除了性能不佳之外,它似乎工作正常。在进行一些性能分析时,我看到,当我滚动列表时,多达 62% 的 CPU 被用于创建我放在 DataTemplate 中的自定义用户控件的新实例。我理解VirtualizationMode="Recycling" 的全部意义在于重新使用ListBox 中的所有UIElements,而不需要创建新实例或处理旧实例,所以我希望这正是不应该发生的事情正在发生。

这里是相关的 XAML:

<ListBox ItemsSource="{Binding EpisodeRows}" toolkit:TiltEffect.SuppressTilt="True" Margin="12,0" VirtualizingStackPanel.VirtualizationMode="Recycling">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid VerticalAlignment="Top" Height="111" VirtualizingStackPanel.VirtualizationMode="Recycling" >
                <StackPanel Orientation="Horizontal" Visibility="{Binding TilesVisibility}">
                    <landerGame:LevelTileUserControl PartText="{Binding PartText_1}" ScoreText="{Binding ScoreText_1}" Star1Visibility="{Binding Star1Vi
                    <landerGame:LevelTileUserControl PartText="{Binding PartText_2}" ScoreText="{Binding ScoreText_2}" Star1Visibility="{Binding Star1Vi
                    <landerGame:LevelTileUserControl PartText="{Binding PartText_3}" ScoreText="{Binding ScoreText_3}" Star1Visibility="{Binding Star1Vi
                    <landerGame:LevelTileUserControl PartText="{Binding PartText_4}" ScoreText="{Binding ScoreText_4}" Star1Visibility="{Binding Star1Vi
                    <landerGame:LevelTileUserControl PartText="{Binding PartText_5}" ScoreText="{Binding ScoreText_5}" Star1Visibility="{Binding Star1Vi
                    <landerGame:LevelTileUserControl PartText="{Binding PartText_6}" ScoreText="{Binding ScoreText_6}" Star1Visibility="{Binding Star1Vi
                </StackPanel>
                <TextBlock VerticalAlignment="Top" Text="{Binding EpisodeTitleText}" Style="{StaticResource PhoneTextExtraLargeStyle}" Margin="0,0,0,5" 
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

这是我在滚动列表时的性能分析结果的屏幕截图:

列表如下所示(这是游戏的关卡选择):

我环顾四周,发现任何针对VirtualizationMode="Recycling" 的文章似乎都不起作用。在这一点上,任何见解都将不胜感激。

编辑:我已经上传了该项目的完整相关代码,任何人都想在这里亲自尝试一下:http://maketag.net/landerGame.rar

【问题讨论】:

  • 电话我忘了,但你是否必须声明 VirtualizingStackPanel.IsVirtualizing="True" 可能吗?
  • @ChrisW。我试了一下,但 IsVirtualizing 在 WP7 XAML 中不可设置 =(.
  • 哦,我想我看到了您的问题,放弃嵌套网格上的虚拟化,将其保留在列表框本身上。然后在列表框上设置一个固定的高度值。如果你不这样做,渲染引擎只是认为它有无限的空间,并且实际上不会调用虚拟化。这是我最近自己学到的东西,哈哈。那你应该很好,试一试。
  • @ChrisW 我试了一下,但不高兴 =(。仍然获得完全相同的缓慢性能和大量 CPU 时间用于在滚动时初始化新的 LevelTileUserControl 实例。不过感谢您的建议。
  • 只是想知道你为什么在这里使用 ListBox?似乎有更好的布局选项可以为您提供更好的性能。

标签: c# windows-phone-7 xaml windows-phone-7.1


【解决方案1】:

这很难测试,因为您没有提供有关用户控件的任何信息。

我建议不要使用ListBox,因为您在此处尝试模仿的行为实际上是WrapPanel

由于您向每个 ListBox 项目添加如此多的用户控件的方式,我猜它会导致性能下降。如果您切换到WrapPanel,然后绑定到您的项目集合,您可能会获得更好的性能,因为每个项目都将被虚拟化,而不必尝试一次虚拟化六个项目(这可能不起作用)。

编辑:查看您的代码,我认为您可以进行一些更改以提高性能。首先,去掉ListBox 并使用ItemsControl,如下所示:

<controls:Pivot Title="LANDER GAME">
    <!--Pivot item one-->
    <controls:PivotItem Header="Episodes">
        <ScrollViewer>
            <ItemsControl ItemsSource="{Binding EpisodeRows}" toolkit:TiltEffect.SuppressTilt="True" Margin="12,0">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Grid VerticalAlignment="Top" Height="111" >
                            <StackPanel Orientation="Horizontal" Visibility="{Binding TilesVisibility}">
                                ...
                            </StackPanel>
                            <TextBlock VerticalAlignment="Top" Text="{Binding EpisodeTitleText}" Style="{StaticResource PhoneTextExtraLargeStyle}" Margin="0,0,0,5" Visibility="{Binding TitleVisibility}" />
                        </Grid>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </ScrollViewer>
    </controls:PivotItem>

我要做的就是摆脱硬编码的PartText_1PartText_2 类型的变量。只需创建一个项目列表,并在您的其他项目控件中添加另一个 ItemsControl

只是去掉ListBox 让它变得更加流畅。我还删除了VirtualizingStackPanel.VirtualizationMode="Recycling",因为它在开始时会导致性能下降,一旦加载它看起来更流畅。

【讨论】:

  • 自定义 UserControl 本身就很简单。它只是在文本框的一些简单属性上公开属性,使它们可以在 DataTemplate 中进行数据绑定。它们内部没有以编程方式进行。我本可以将其中的 XAML 复制到 DataTemplate 中 6 次,但这似乎是个坏主意。包装面板中是否可以有间歇性标题?如果可以的话,我愿意试一试。我仍然很困惑为什么我的自定义 UserControl 根本无法正确回收。
  • 您是否有机会从您的代码中创建一个具有相同性能问题的简单示例?如果您发布该内容,则很容易对其进行故障排除。
  • 我在这里上传了整个解决方案的精简版:link。我在 Omnia 7 上看到了性能问题,在 wp7.5 模拟器(core duo 2.7ght)上不太明显,但仍然非常糟糕。我主要担心的是大量的 CPU 时间在我滚动时完全重新创建我所有的自定义用户控件,这似乎是一种可怕的浪费。尽管任何可以足够快地加快滚动速度的东西当然都很棒。如果我无法弄清楚这一点,我只需要简化列表并在每一行上使用更简单的 UI 元素。
  • 测试一下。如果您关闭回收,您似乎可以获得更好的性能,因为它不会不断创建您的用户控件的新实例。要去测试另一件事。
  • @Byrant。我周末没有上网,所以无法尽快回复。将ItemsControl 放入“ScollViewer”实际上会破坏任何类型的虚拟化,因为ItemsControl 最终将成为列表的全部高度,并认为它正在被完整呈现。我确实使用了来自here 的一些代码来让ItemsControl 工作,但它并没有提高性能,而且我在滚动时获得了相同的用户控件娱乐。关闭VirtualizationMode="Recycling"继续..
猜你喜欢
  • 2011-06-21
  • 1970-01-01
  • 1970-01-01
  • 2012-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多