代码之家  ›  专栏  ›  技术社区  ›  RationalGeek

获取在Silverlight中使用itemsControl的UI虚拟化

  •  6
  • RationalGeek  · 技术社区  · 14 年前

    我正在尝试创建一个相当大的文本块滚动列表。我希望有一个垂直滚动条来显示它们,如果它们溢出了某个大小,我希望它们显示一个省略号。我真的把这些工作做得很好。

    我有以下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虚拟化引入此布局的最佳方法是什么?我试过六种不同的方法,但没有一种能很好地解决问题。

    我设法在列表框中实现了这一点,因为它似乎支持开箱即用的虚拟化。但是,我更喜欢使用itemscontrol,因为我不希望这些东西是可选的,也不希望列表框附带的样式。

    这在Silverlight4中。

    1 回复  |  直到 12 年前
        1
  •  15
  •   Steve Willcock    14 年前

    你需要做一些事情才能使这项工作发挥作用。

    1. 为设置itemspanelTemplate 您的项目控制到 虚拟化跟踪面板。
    2. 在内部合并ScrollViewer 为您的 项控件而不是 把它包在外面。
    3. 确保itemscontrol具有固定的高度,以便布局系统可以计算出填充视区需要多少项。(看起来您已经通过将itemsControl放置在网格中完成了这项操作-这将允许布局系统确定控件的分配高度)

    下面是我能想到的最简单的例子:

        <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>