Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.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项目,以便它们基于每个项目中的任意垂直点排列?_Wpf_Listview_Mvvm_Wrappanel - Fatal编程技术网

如何在水平包装中排列WPF项目,以便它们基于每个项目中的任意垂直点排列?

如何在水平包装中排列WPF项目,以便它们基于每个项目中的任意垂直点排列?,wpf,listview,mvvm,wrappanel,Wpf,Listview,Mvvm,Wrappanel,我试图在WPF中创建一个视图,但很难弄清楚如何设置它。以下是我试图构建的内容: My ViewModel公开了一个名为Items的IEnumerable属性 每个项目都是时间轴上的一个事件,每个项目都实现ITimelineItem 每个项目的ViewModel都有自己的数据模板来显示它 我想显示时间线上由一条线连接的所有项目。我认为ListView中的WrapPanel可以很好地解决这个问题 但是,每个项目的高度将根据其显示的信息而有所不同。有些项目将在线条上有图形对象(如圆形或菱形或其他),

我试图在WPF中创建一个视图,但很难弄清楚如何设置它。以下是我试图构建的内容:

  • My ViewModel公开了一个名为Items的IEnumerable属性
  • 每个项目都是时间轴上的一个事件,每个项目都实现ITimelineItem
  • 每个项目的ViewModel都有自己的数据模板来显示它
  • 我想显示时间线上由一条线连接的所有项目。我认为ListView中的WrapPanel可以很好地解决这个问题
  • 但是,每个项目的高度将根据其显示的信息而有所不同。有些项目将在线条上有图形对象(如圆形或菱形或其他),有些项目在线条上方或下方有注释
所以我觉得很复杂。似乎时间线上的每个项目都必须呈现自己的线段。那很好。但是项目顶部到行(以及项目底部到行)之间的距离可能会有所不同。如果一个项目的行从顶部向下50 px,下一个项目的行从顶部向下100 px,那么第一个项目需要50 px的填充,以便线段相加

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

这就是让我头疼的原因。我还有别的办法吗


编辑:我倾向于用从画布继承的自定义面板替换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>  


这绝对是一个有用的解决方案。谢谢但是我仍然在寻找一种方法来安排这些项目,这样它们就可以在它们应该在的地方排成一行。所有的线条都是水平和笔直的,所以需要移动来补偿。装饰也解决了我的拖放视觉指示器问题!谢谢你教我新东西!我更新了我的帖子,提出了一个解决你的问题的建议。这绝对是一个很有用的解决办法。谢谢但是我仍然在寻找一种方法来安排这些项目,这样它们就可以在它们应该在的地方排成一行。所有的线条都是水平和笔直的,所以需要移动来补偿。装饰也解决了我的拖放视觉指示器问题!谢谢你教我新东西!我更新了我的帖子,提出了一个解决你的问题的建议。有趣的想法。。。谢谢它限制了一些东西,因为所有的图形都必须是相同的大小(在中间),所以如果一个使用的图形是两倍大,那么同一行中其他图形上的所有注释都不会正好对着图形。例如,如果一个项目只有一个大的图形,没有注释怎么办?正如我所说,这比我想象的要严格一些,但这是一个有趣的方法。实际上,你可以做中间的