在Silverlight中使用ItemsControl进行UI虚拟化

时间:2010-08-06 22:59:38

标签: silverlight silverlight-4.0

我正在尝试创建一个相当大的文本块的滚动列表。我希望有一个垂直滚动条来显示它们,如果它们溢出一定的大小,我希望它们显示省略号。我实际上所有这些工作都非常好。

我有以下Silverlight XAML:

<Grid x:Name="LayoutRoot" MaxWidth="500" MinWidth="100"
    MaxHeight="500" MinHeight="100">
    <Grid.DataContext>
        <app:MainPageViewModel/>
    </Grid.DataContext>
    <ScrollViewer>
    <ItemsControl ItemsSource="{Binding TextItems}" Margin="0,20,0,20">
        <ItemsControl.ItemTemplate><DataTemplate>
            <Border MaxHeight="175" Margin="0,0,0,18" CornerRadius="5">
                <TextBlock Margin="2" TextTrimming="WordEllipsis"
                     TextWrapping="Wrap" Text="{Binding}"/>
            </Border>
         </DataTemplate></ItemsControl.ItemTemplate>
    </ItemsControl>
    </ScrollViewer>
</Grid>

我的问题是这种布局不使用UI虚拟化,例如使用VirtualizingStackPanel。所以它很慢。将UI虚拟化纳入此布局的最佳方法是什么?我已经尝试了大约六种不同的方法,但没有任何方法可以做得很好。

我设法让它在ListBox中工作,因为它似乎支持虚拟化开箱即用。但是,我更喜欢使用ItemsControl,因为我不希望这些东西可以选择,而且我不希望ListBox附带的样式。

这在Silverlight 4中。

1 个答案:

答案 0 :(得分:15)

要完成这项工作,您需要做一些事情。

  1. 设置ItemsPanelTemplate 你的ItemsControl到了 VirtualizingStackPanel。
  2. 将ScrollViewer合并到里面 一个ControlTemplate为您的 ItemsControl而不仅仅是 把它包在外面。
  3. 确保ItemsControl具有固定高度,以便布局系统可以计算出填充视口所需的项目数。 (看起来你已经通过将ItemsControl放在网格中来实现这一点 - 这将允许布局系统确定控件的分配高度)
  4. 这是我能想到的最简单的例子:

        <ItemsControl ItemsSource="{Binding TextItems}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <VirtualizingStackPanel />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.Template>
                <ControlTemplate TargetType="ItemsControl">
                    <Border>
                        <ScrollViewer>
                            <ItemsPresenter/>
                        </ScrollViewer>
                    </Border>
                </ControlTemplate>
            </ItemsControl.Template>
        </ItemsControl>