ListBox, привязывающий элемент DataTemplate к ItemsPanel Canvas.Left / Top - PullRequest
2 голосов
/ 05 октября 2011

У меня есть ListBox с панелью Canvas Items. Элементы в этом списке обозначены метками: Labeled arrow example

LabeledArrow - это просто класс модели представления (не визуальный), который предоставляет такие свойства, как Start_X, Start_Y (начало стрелки), End_X, End_Y (головка стрелки) и Box_X, Box_Y (возможность поля). Ниже приведен шаблон DataBempItem ListBoxItem для LabeledArrow. .
Привязка свойств ArrowLine X1, Y1, x2, Y2 к свойствам LabeledArrow Start_X, Start_Y и т. Д. Работает нормально, поскольку ArrowLine имеет открытые свойства координат (X1 и т. Д.). Однако это всего лишь TextBlock, поэтому мне нужно каким-то образом установить привязанные свойства Canvas.Top и Canvas.Left, но привязка, как показано ниже, не работает.
Есть идеи? Нужно ли прибегать к упаковке 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>

Ответы [ 2 ]

2 голосов
/ 05 октября 2011

Вы устанавливаете вложенные свойства Canvas.Left и Canvas.Top в TextBox, но родительским элементом 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>
0 голосов
/ 05 октября 2011

Просто дикая догадка ...

  1. Вы могли бы обернуть своих LabledArrow детей в Canvas вместо Grid
  2. Затем установите свои координаты на TextBlock относительно этого локального Canvas путем вычитания ... Box_X и Start_X и Box_Y и Start_Y (для этого используется мультисвязывание и преобразователь)

Я думаю, этобудет установлен на относительный холст в координатах, к которым вы стремитесь ... не так ли?

...