ListBox 将 DataTemplate 项绑定到 ItemsPanel Canvas.Left/Top
我有一个带有 Canvas ItemsPanel 的列表框。此列表中的项目为 LabeledArrows:
LabeledArrow 只是一个视图模型类(非可视),它公开 Start_X 等属性、Start_Y(箭头开始)、End_X、End_Y(箭头)和 Box_X、Box_Y(框位置) 显示了 LabeledArrow 的 ListBoxItem 数据模板下面。
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>
I have a ListBox with a Canvas ItemsPanel. Items in this list are LabeledArrows:
LabeledArrow is just a view model class (non visual) that exposes properties like Start_X, Start_Y (arrow start), End_X, End_Y (arrow head) and Box_X, Box_Y (box possition) The ListBoxItem DataTemplate for the LabeledArrow is shown below.
The binding of ArrowLine X1, Y1, x2, Y2 to LabeledArrow Start_X, Start_Y etc properties works fine because ArrowLine has exposed coordinate properties (X1 etc). The box however is just TextBlock so I have to somehow set Canvas.Top and Canvas.Left attatched properties to possition it - but the binding as its shown below doesn't work.
Any ideas? Do I need to resort to wrapping LabeledArrow up as a 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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您在 TextBox 上设置了附加属性
Canvas.Left
和Canvas.Top
,但 TextBox 的父级是 Grid。附加属性有时用于告诉 Control 的父级如何布局该元素。例如,Canvas、Grid 和 DockPanel 就是这样做的。您想要的是在项目容器上设置这两个属性,该容器是Canvas
的直接子级。容器使用 DataTemplate 来显示其内容。为此,请将其添加到您的列表框中
You set the attached properties
Canvas.Left
andCanvas.Top
on your TextBox, but the parent of the TextBox is a Grid. Attached properties are sometimes used to tell the parent of the Control how to layout this element. Canvas, Grid and DockPanel do that for example. What you want is set both properties on the item container, which is the direct child of theCanvas
. The container uses the DataTemplate to display its content.To do that add this to your ListBox
只是一个疯狂的猜测...
LabledArrow
子项包裹在Canvas
中而不是Grid
TextBlock< 处设置坐标/code> 相对于本地
Canvas
减去...Box_X
和Start_X
和Box_Y
和开始_Y
(使用多重绑定和转换器来做到这一点)
我认为它将被安装到您渴望的坐标处的相对画布上......不是吗?
Just a wild guess...
LabledArrow
children in aCanvas
instead ofGrid
TextBlock
relative to that localCanvas
by subtracting...Box_X
andStart_X
andBox_Y
andStart_Y
(using multibinding and a converter to do so)
I think it will be mounted to a relative canvas at the coordinates you aspire... isnt it?