如何有效地实现ScrollViewer后台网格?

时间:2011-04-13 13:45:32

标签: wpf itemscontrol scrollviewer

我目前正在开发一个应用程序,它根据时间轴上的时间戳显示数据项。以下屏幕截图给出了一个想法:

Screenshot http://www.antiserum.ch/Screenshot.png

时间轴每十毫秒包含索引行。它使用Canvas在正确的位置渲染数据项,使用StackPanel显示索引线。

你在sceenshot中看到的正是我想要达到的目标。但是,为了显示索引行,我当前正在填充TimeSpan对象列表,每个对象增加10ms,以获得完整的数据集持续时间。该列表显示在ItemsControl中,其中包含绘制白线,黑框和文本的项目数据模板。

您可以想象,从性能的角度来看,这可能是最糟糕的方法,因为ItemsControl只包含1000个元素,只有10秒的数据。

所以我的问题是,如何有效地绘制索引标记?

我已经考虑使用VirtualizingStackPanel来显示TimeSpan项目。这不是一个选项,因为ScrollViewer不直接包含索引列表。在这种情况下,虚拟化似乎不起作用。

为了澄清,这里是我的xaml代码的片段(我删除了模板和样式代码):

<ScrollViewer x:Name="timelineScroller">
  <Grid>
    <ItemsControl x:Name="IndexMarkers" ItemsSource="{Binding IndexMarkers}" />
    <ItemsControl x:Name="TimelineList" ItemsSource="{Binding Lines}" />
  </Grid>
</ScrollViewer>

一种可能的解决方案可能是将ScrollViewer子类化,并在渲染时将索引线和文本绘制到ScrollViewer的背景中。这应该是有效的,因为它只能渲染实际可见的线条。但是,我没有找到有关如何实现此类渲染自定义的信息。

任何想法都表示赞赏。

此致 丹尼尔

2 个答案:

答案 0 :(得分:1)

我最终采用的方法似乎运行良好,没有任何虚拟化:

索引标记列表是常量,但是根据标记宽度的当前时间得到RenderTransform-ed。这使得ScrollViewer背景随着鼠标移动,并突然跳回到原始位置(这种情况恰好在模数操作“缠绕”值时发生。

剩下要做的就是在那个时刻更新标记的标签。这种方法非常有效,因此用户无法感知到标签的跳跃。

答案 1 :(得分:0)

听起来你可能需要明确地实现Virtualization。

请记住,您可能希望汇集标记(因为在可能的情况下重用相同的元素,因为创建/销毁标记可能会导致一些严重的垃圾收集器在尝试清理所有这些对象时发生颠簸。

如果你使用了Canvas,你基本上可以在代码中修改画布的子画面以显示你想要它的元素(指定它们的坐标)。