如何在水平包装中排列WPF项目,以便它们基于每个项目中的任意垂直点排列?
我试图在WPF中创建一个视图,但很难弄清楚如何设置它。以下是我试图构建的内容:如何在水平包装中排列WPF项目,以便它们基于每个项目中的任意垂直点排列?,wpf,listview,mvvm,wrappanel,Wpf,Listview,Mvvm,Wrappanel,我试图在WPF中创建一个视图,但很难弄清楚如何设置它。以下是我试图构建的内容: My ViewModel公开了一个名为Items的IEnumerable属性 每个项目都是时间轴上的一个事件,每个项目都实现ITimelineItem 每个项目的ViewModel都有自己的数据模板来显示它 我想显示时间线上由一条线连接的所有项目。我认为ListView中的WrapPanel可以很好地解决这个问题 但是,每个项目的高度将根据其显示的信息而有所不同。有些项目将在线条上有图形对象(如圆形或菱形或其他),
- My ViewModel公开了一个名为Items的IEnumerable属性
- 每个项目都是时间轴上的一个事件,每个项目都实现ITimelineItem
- 每个项目的ViewModel都有自己的数据模板来显示它
- 我想显示时间线上由一条线连接的所有项目。我认为ListView中的WrapPanel可以很好地解决这个问题
- 但是,每个项目的高度将根据其显示的信息而有所不同。有些项目将在线条上有图形对象(如圆形或菱形或其他),有些项目在线条上方或下方有注释
编辑:我倾向于用从画布继承的自定义面板替换WrapPanel,并覆盖MeasureOverride和ArrangeOverride方法。理想的解决方案可能是使用装饰器。在AdornerLayer上,面板上的每个项目都有一个自定义的Adorner(在DataTemplate中定义)。您将能够检索每个项目的尺寸标注和位置(装饰器的边界框)。在AdornerLayer上,您还可以在这些边界框之间绘制线。 使用此解决方案,您可以按任意方式(使用任意面板)布局项目,并且项目仍将与线连接 很久以前,我将这种方法用于图形可视化工具。可以以任何方式布局的任意元素所在的节点。与线连接的项目 要使所有项目完全对齐,可以使用画布作为ItemTemplate中的根面板。画布可以是0x0单位大。然后围绕画布排列元素。画布成为您的参考点。行顶部的所有内容都将获得负画布。顶部值。
另一种方法是使用负边距,该边距与围绕线条的顶部和底部控件的高度绑定。使用IValueConverter(高度*-1)反转高度。理想的解决方案可能是使用装饰器。在AdornerLayer上,面板上的每个项目都有一个自定义的Adorner(在DataTemplate中定义)。您将能够检索每个项目的尺寸标注和位置(装饰器的边界框)。在AdornerLayer上,您还可以在这些边界框之间绘制线。 使用此解决方案,您可以按任意方式(使用任意面板)布局项目,并且项目仍将与线连接 很久以前,我将这种方法用于图形可视化工具。可以以任何方式布局的任意元素所在的节点。与线连接的项目 要使所有项目完全对齐,可以使用画布作为ItemTemplate中的根面板。画布可以是0x0单位大。然后围绕画布排列元素。画布成为您的参考点。行顶部的所有内容都将获得负画布。顶部值。
另一种方法是使用负边距,该边距与围绕线条的顶部和底部控件的高度绑定。使用IValueConverter(高度*-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>
这不会解决您的问题,但我打赌它会简化问题:
尝试定义如下所示的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>
这绝对是一个有用的解决方案。谢谢但是我仍然在寻找一种方法来安排这些项目,这样它们就可以在它们应该在的地方排成一行。所有的线条都是水平和笔直的,所以需要移动来补偿。装饰也解决了我的拖放视觉指示器问题!谢谢你教我新东西!我更新了我的帖子,提出了一个解决你的问题的建议。这绝对是一个很有用的解决办法。谢谢但是我仍然在寻找一种方法来安排这些项目,这样它们就可以在它们应该在的地方排成一行。所有的线条都是水平和笔直的,所以需要移动来补偿。装饰也解决了我的拖放视觉指示器问题!谢谢你教我新东西!我更新了我的帖子,提出了一个解决你的问题的建议。有趣的想法。。。谢谢它限制了一些东西,因为所有的图形都必须是相同的大小(在中间),所以如果一个使用的图形是两倍大,那么同一行中其他图形上的所有注释都不会正好对着图形。例如,如果一个项目只有一个大的图形,没有注释怎么办?正如我所说,这比我想象的要严格一些,但这是一个有趣的方法。实际上,你可以做中间的