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

Wpf ListBox将DataTemplate项绑定到ItemsPanel Canvas.Left/Top,wpf,binding,datatemplate,Wpf,Binding,Datatemplate,我有一个带有帆布条带的列表框。此列表中的项目为标签行: LabeledArrow只是一个视图模型类(非可视),它公开了诸如Start_X、Start_Y(箭头开始)、End_X、End_Y(箭头)和Box_X、Box_Y(方框位置)等属性LabeledArrow的ListBoxItem数据模板如下所示。 将箭头X1、Y1、x2、Y2绑定到LabelDarrow Start_X、Start_Y等属性可以正常工作,因为箭头具有公开的坐标属性(X1等)。但是,该框只是文本块,因此我必须以某种方式将Ca

我有一个带有帆布条带的列表框。此列表中的项目为标签行:

LabeledArrow只是一个视图模型类(非可视),它公开了诸如Start_X、Start_Y(箭头开始)、End_X、End_Y(箭头)和Box_X、Box_Y(方框位置)等属性LabeledArrow的ListBoxItem数据模板如下所示。
将箭头X1、Y1、x2、Y2绑定到LabelDarrow Start_X、Start_Y等属性可以正常工作,因为箭头具有公开的坐标属性(X1等)。但是,该框只是文本块,因此我必须以某种方式将Canvas.Top和Canvas.Left附加属性设置为position-it-但是如下所示的绑定不起作用。
有什么想法吗是否需要将LabeledArrow包装为用户控件?

<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>

您可以在文本框上设置附加属性
Canvas.Left
Canvas.Top
,但文本框的父项是网格。附加属性有时用于告诉控件的父控件如何布局此元素。例如,Canvas、Grid和DockPanel就是这样做的。您需要在项目容器上设置这两个属性,该容器是
画布的直接子级。容器使用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>

只是一个猜测

  • 您可以将您的
    标签箭头
    子项包装在
    画布
    中,而不是
    网格
  • 然后通过减去<代码>方框X
  • 开始
    方框Y
    开始
    (使用多重绑定和转换器执行此操作)
    我想它会被安装在一个相对的画布上,坐标是你想要的。。。是吗?

    是的,文本框不是画布的直接子对象,这就是问题所在。但是,我不想使用样式来设置包装LabeledRow的整个ListBoxItem的Canvas.Top/Left,因为这会弄乱箭头部分的位置。如果我只是显示一个文本框,那就行了。你没有太多其他选择。当然,必须变换箭头位置,以考虑新的父位置。其他选项涉及更多的代码,可能更容易混淆。这是我能给你的唯一解决方案,事实上,它和我们在图表控件中使用的是一样的。好吧,经过一些考虑,我认为你是对的,这是最简单的解决方案。干杯(我查看了你们的文章:draft应用程序屏幕截图-看起来不错!)我认为你们的建议类似于dowhilefor,可能会起作用-但我现在有了一些工作,通过集合的grid/listboxitem来抵消箭头位置,所以我将使用它。干杯