我有一个带有Canvas ItemsPanel的ListBox。此列表中的项目为LabeledArrows:
LabeledArrow只是一个视图模型类(非可视化),它暴露了Start_X,Start_Y(箭头开始),End_X,End_Y(箭头)和Box_X,Box_Y(box possition)等属性LabeledArrow的ListBoxItem DataTemplate如下所示。
ArrowLine X1,Y1,x2,Y2与LabeledArrow Start_X,Start_Y等属性的绑定工作正常,因为ArrowLine具有公开的坐标属性(X1等)。然而,这个盒子只是TextBlock,所以我必须以某种方式设置Canvas.Top和Canvas.Left附加属性才能实现它 - 但是如下所示的绑定不起作用。
有任何想法吗? 我是否需要将LabeledArrow包装为UserControl?
<ListBox.Resources>
<DataTemplate DataType="{x:Type tp:LabledArrow}">
<Grid>
<tp:ArrowLine Stroke="Red" StrokeThickness="2"
X1="{Binding Path=Start_X}" Y1="{Binding Path=Start_Y}"
X2="{Binding Path=End_X}" Y2="{Binding Path=End_Y}" />
<TextBlock Text="{Binding Path=Value}"
**Canvas.Left="{Binding Path=Box_X}"
Canvas.Top="{Binding Path=Box_Y}"** />
</Grid>
</DataTemplate>
</ListBox.Resources>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<Canvas IsItemsHost="True" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
答案 0 :(得分:2)
您在TextBox上设置附加属性Canvas.Left
和Canvas.Top
,但TextBox的父级是Grid。附加属性有时用于告诉控件的父级如何布局此元素。例如,Canvas,Grid和DockPanel就是这样做的。你想要的是在项容器上设置两个属性,它是Canvas
的直接子项。容器使用DataTemplate显示其内容。
为此,请将此添加到ListBox
<ListBox.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Left" Value="{Binding Path=Box_X}"/>
<Setter Property="Canvas.Top" Value="{Binding Path=Box_Y}"/>
</Style>
</ListBox.ItemContainerStyle>
答案 1 :(得分:0)
只是猜测......
LabledArrow
个孩子包裹在Canvas
而不是Grid
TextBlock
和Canvas
以及Box_X
和Start_X
,将您的坐标设为Box_Y
相对于当地Start_Y
的坐标
(使用多重绑定和转换器来执行此操作)我认为它将被安装在你渴望的坐标上的相对画布上......不是吗?