0

我正在尝试在 WPF 中创建一个视图,并且很难弄清楚如何设置它。这是我正在尝试构建的内容:

  • 我的 ViewModel 公开了一个名为 Items 的 IEnumerable 属性
  • 每个项目都是时间轴上的一个事件,每个项目都实现了 ITimelineItem
  • 每个项目的 ViewModel 都有自己的 DataTemplate 来显示它
  • 我想显示由一条线连接的时间线上的所有项目。我认为 ListView 内的 WrapPanel 可以很好地解决这个问题。
  • 但是,每个项目的高度将根据其显示的信息而有所不同。有些项目将在行上具有图形对象(如圆形或菱形,或其他),有些项目在行上方或下方有注释。

所以对我来说似乎很复杂。似乎时间线上的每个项目都必须渲染自己的线段。没关系。但是项目顶部到行(以及项目底部到行)之间的距离可能会有所不同。如果一个项目的线从顶部向下 50 px,而下一个项目的线从顶部向下 100 px,则第一个项目需要 50 px 的填充,以便线段相加。

我想我可以解决这个问题,但是,如果这两个项目在 WrapPanel 的同一行上,我们只需要添加填充!假设有 5 个项目,屏幕上只有 3 个空间... WrapPanel 将把另外两个放在下一行。没关系,但这意味着只有前 3 个需要一起填充,最后 2 个需要一起填充。

这就是让我头疼的地方。我可以看看另一种方法吗?

编辑:我倾向于用继承自 Canvas 并覆盖 MeasureOverride 和 ArrangeOverride 方法的自定义面板替换 WrapPanel。

4

2 回答 2

2

理想的解决方案可能是使用 Adorners。在 AdornerLayer 上,您将为面板上的每个项目拥有一个自定义 Adorner(您在 DataTemplate 中定义它)。您将能够检索每个项目的尺寸和位置(装饰器的边界框)。同样在 AdornerLayer 上,您将在这些边界框之间绘制线条。使用此解决方案,您可以按您想要的任何方式布置您的项目(使用您想要的任何面板),并且这些项目仍将与线连接。

很久以前,我将这种方法用于图形可视化器。可以以任何方式布局的任意 UIElements 的节点。与线相连的项目。

要使所有项目完美对齐,您可以在 ItemTemplate 中使用 Canvas 作为根面板。画布可以是 0x0 单位大。然后,您将围绕该 Canvas 排列您的元素。画布成为您的参考点。行顶部的所有内容都将获得负 Canvas.Top 值。另一种方法是使用负边距,该负边距绑定到围绕该线的顶部和底部控件的高度。使用 IValueConverter (Height*-1) 反转高度。

于 2010-05-22T19:20:39.443 回答
1

这不会解决你的问题,但我敢打赌它会简化它:

尝试定义一个DataTemplate看起来像这样的:

<Grid>
   <Grid.RowDefinitions>
      <RowDefinition Height="Auto" SharedSizeGroup="Top"/>
      <RowDefinition Height="10"/>
      <RowDefinition Height="Auto" SharedSizeGroup="Bottom"/>
   </Grid.RowDefinitions>
   <ContentControl Grid.Row="0" Content="{Binding TopAnnotations}/>
   <Rectangle Fill="Black" Grid.Row="1" Margin="0,4,0,4"/>
   <ContentControl Grid.Row="1" Height="10" Content="{Binding GraphicObject}"/>
   <ContentControl Grid.Row="2" Content="{Binding BottomAnnotations}"/>
</Grid>  

现在创建一个ItemsControlItemsPanelTemplate为水平WrapPanel的,Grid.IsSharedSizeScope附加属性设置为 True。当然,您还需要为注释和图形对象属性包含的任何内容定义数据模板。

您仍然会遇到这样的问题,即当WrapPanel包裹中的项目时,时间线上方和下方的对象具有相同的填充,而不管它们实际需要多少适合它们的当前行WrapPanelWrapPanel因此,为了获得我认为您正在寻找的效果,您仍然必须使用 measure 和安排来胡闹 - 基本上,您将创建将这些项目放入StackPanel每个“行”上的东西,而不是创建单个,每个都是它自己的共享大小范围。但实际上测量和安排时间线项目的高度并不是您需要担心的事情。您只需要它们的宽度(以便您的逻辑可以确定何时换行)。将Grid负责为您计算高度。

于 2010-05-22T23:28:10.337 回答