ListBox 将 DataTemplate 项绑定到 ItemsPanel Canvas.Left/Top

发布于 2024-12-08 09:55:56 字数 1221 浏览 0 评论 0原文

我有一个带有 Canvas ItemsPanel 的列表框。此列表中的项目为 LabeledArrows:Labeled arrow example

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:Labeled arrow example

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

咋地 2024-12-15 09:55:56

您在 TextBox 上设置了附加属性 Canvas.LeftCanvas.Top,但 TextBox 的父级是 Grid。附加属性有时用于告诉 Control 的父级如何布局该元素。例如,Canvas、Grid 和 DockPanel 就是这样做的。您想要的是在项目容器上设置这两个属性,该容器是 Canvas 的直接子级。容器使用 DataTemplate 来显示其内容。

为此,请将其添加到您的列表框中

<ListBox.ItemContainerStyle>
    <Style>
        <Setter Property="Canvas.Left" Value="{Binding Path=Box_X}"/>
        <Setter Property="Canvas.Top" Value="{Binding Path=Box_Y}"/>
    </Style>
</ListBox.ItemContainerStyle>

You set the attached properties Canvas.Left and Canvas.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 the Canvas. The container uses the DataTemplate to display its content.

To do that add this to your 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>
秉烛思 2024-12-15 09:55:56

只是一个疯狂的猜测...

  1. 您可以将您的 LabledArrow 子项包裹在 Canvas 中而不是 Grid
  2. 然后在 TextBlock< 处设置坐标/code> 相对于本地 Canvas 减去... Box_XStart_XBox_Y开始_Y
    (使用多重绑定和转换器来做到这一点)

我认为它将被安装到您渴望的坐标处的相对画布上......不是吗?

Just a wild guess...

  1. You could wrap your LabledArrow children in a Canvas instead of Grid
  2. Then make your coordinates at TextBlock relative to that local Canvas by subtracting... Box_X and Start_X and Box_Y and Start_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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文