【问题标题】:Getting UI virtualization working with ItemsControl in Silverlight在 Silverlight 中使用 ItemsControl 获得 UI 虚拟化
【发布时间】:2010-08-06 22:59:38
【问题描述】:

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

我有以下 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 中。

【问题讨论】:

    标签: silverlight silverlight-4.0


    【解决方案1】:

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

    1. 设置 ItemsPanelTemplate 为 你的 ItemsControl 到 虚拟化StackPanel。
    2. 在里面加入 ScrollViewer 为您的 ControlTemplate ItemsControl 而不是仅仅 把它包裹在外面。
    3. 确保 ItemsControl 具有固定高度,以便布局系统可以计算出填充视口所需的项目数。 (看起来您已经通过将 ItemsControl 放在 Grid 中来执行此操作 - 这将允许布局系统确定控件的分配高度)

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

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

    【讨论】:

    • 这就像史蒂夫的魅力一样。因此,您的解决方案与我尝试做的主要区别在于您使用 ItemsControl.Template 添加到 ScrollViewer,而我只是试图将 ScrollViewer 放在控件的外部。你能解释一下为什么你的工作有效,而我试图做的却没有吗?它可能会帮助我更好地理解解决方案。
    • 太好了,很高兴它对你有用。基本上发生的情况是,如果您在 ItemsControl 外部放置一个 ScrollViewer,那么布局引擎将呈现整个 ItemsControl - 它将为控件中的所有项目生成项目容器。 ScrollViewer 只是将视图限制在 ItemsControl 的一小部分,但包含所有项目的整个 ItemsControl 都存在于内存中。第二种方式,将 ScrollViewer 放在模板中,使 ItemsControl 能够限制它创建的项目容器的数量 - 它只会创建足够的空间来填充可用空间。
    • 您知道在模板中添加ScrollViewer 与直接在ItemsControl 上设置ScrollViewer.HorizontalScrollBarVisibilityScrollViewer.VerticalScrollBarVisibility 有什么区别吗?
    • 当我尝试应用数据模板时,此解决方案失败。
    猜你喜欢
    • 1970-01-01
    • 2011-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多