Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 如何高效地实现ScrollViewer后台网格?_Wpf_Itemscontrol_Scrollviewer - Fatal编程技术网

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

Wpf 如何高效地实现ScrollViewer后台网格?,wpf,itemscontrol,scrollviewer,Wpf,Itemscontrol,Scrollviewer,我目前正在开发一个应用程序,根据时间轴上的时间戳显示数据项。以下屏幕截图为您提供了一个想法: (来源:) 时间线每十毫秒包含一行索引。它使用画布在正确的位置呈现数据项,使用StackPanel显示索引行 你在电影中看到的正是我想要实现的。但是,为了显示索引行,我目前正在填充一个TimeSpan对象列表,每个对象递增10毫秒,以获得完整的数据集持续时间。该列表显示在ItemsControl中,其中包含一个items数据模板,该模板绘制一条白线、一个黑框和文本 可以想象,从性能的角度来看,这可能是

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


(来源:)

时间线每十毫秒包含一行索引。它使用画布在正确的位置呈现数据项,使用StackPanel显示索引行

你在电影中看到的正是我想要实现的。但是,为了显示索引行,我目前正在填充一个TimeSpan对象列表,每个对象递增10毫秒,以获得完整的数据集持续时间。该列表显示在ItemsControl中,其中包含一个items数据模板,该模板绘制一条白线、一个黑框和文本

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

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

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

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


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

欢迎提出任何意见

问候,,
Daniel

听起来您可能需要明确地实施虚拟化

请记住,您可能希望将标记集中在一起(如在可能的情况下重用相同的元素),因为创建/销毁标记可能会在垃圾收集器尝试清理所有这些对象时导致严重的垃圾收集器抖动


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

我最后采用的方法似乎非常有效,而且没有任何虚拟化:

索引标记的列表是恒定的,但会根据标记宽度的当前时间模数进行渲染转换。这会使ScrollViewer背景随着鼠标移动,并突然跳回原始位置(当值通过模数操作“环绕”时,会发生这种情况)


剩下要做的就是恰好在那个时刻更新标记的标签。这种方法工作得非常好,以至于用户无法察觉标签的跳跃。

问题是,问题列表是使用VirtualzingStackPanel实现的,但VSP无法虚拟化,因为它不是re的直接子对象因此,即使我自己实现,虚拟化也不会发生。
<ScrollViewer x:Name="timelineScroller">
  <Grid>
    <ItemsControl x:Name="IndexMarkers" ItemsSource="{Binding IndexMarkers}" />
    <ItemsControl x:Name="TimelineList" ItemsSource="{Binding Lines}" />
  </Grid>
</ScrollViewer>