Привязать к позиции элемента относительно родителя в WPF

2

Мне нужно что-то, чтобы получить позицию суб-вспомогательного элемента относительно контейнера. TransformToAncestor делает это. Тем не менее, элемент и подэлементы перемещаются, изменяют размер, их компоновку и т.д. Мне нужен способ сохранить актуальность позиции. Как событие, если что-нибудь случится, что повлияет на мою операцию TransformToAncestor. Или свойство зависимостей "AbsolutePosition", с которым я могу связываться.

Фон:

Я делаю вид редактора рабочего потока. Существуют "модули", которые имеют один или несколько портов и линий, которые соединяют модули с порта на порт.

Структура XAML выглядит следующим образом:

<Canvas>
  <Module Left="..." Top="..." Width="..." Height="...">
    <Grid><otherelement><somemorelayouting>
      <Port Name="a" />
      <Port Name="b" />
    </somemorelayouting></otherelement></Grid>
  </Module>
  <Module Left="..." Top="..." Width="..." Height="...">
    <differentsetoflayouts>
    <Port Name="c" />
    <Port Name="d" />
    </differentsetoflayouts>
  </Module>
  <Line startpoint="{binding source=a, path=abs_position}" endpoint="{binding source=c, path=abs_position}" />
</Canvas>

Линия соединяет порт a первого модуля с портом b второго. Конечные точки должны находиться в верхнем левом углу элемента порта (на данный момент). Это свойство "abs_position", используемое в этом примере, неудобно не существует (я использую start/endpoint здесь вместо X1, X2, Y1, Y2 только для улучшения удобочитаемости)

Теги:
wpf

3 ответа

2
Лучший ответ

Если вы реализуете свой контейнер с прикрепленными свойствами зависимостей для расположения дочерних элементов (например, панель Canvas, которая, кажется, случай согласно предоставленному коду), то вы можете привязать к изменениям этого свойства зависимостей, используя DependencyPropertyDescriptor.

DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty(Canvas.TopProperty, typeof(Canvas));

dpd.AddValueChanged(canvas1, new EventHandler(topChangedCallback));
  • 0
    Проблема в том, что Модуль представляет собой UserControl с довольно сложной внутренней структурой, использующей несколько вложенных контейнеров разного типа. Что еще хуже, часть этой структуры создается динамически. Мне нужно было бы добавить прослушиватели событий для каждого контейнера, каждый из которых использует другие свойства для позиционирования. Это будет работать, но вряд ли это хорошее решение. Я надеялся на решение, которое не оставит код XAML и C # загроможденным при регистрации / отмене регистрации событий.
  • 0
    Итак, почему вы спросили о свойстве DependencyProperty, с которым вы можете связываться?
Показать ещё 3 комментария
3

Я предлагаю использовать решение kek444 с настраиваемой компоновкой, если это возможно. Однако, если это не применимо, вот еще один вопрос, который я нашел во время подсказок kek444 googling.

Событие UIElement.LayoutUpdated запускается всякий раз, когда что-то на макете изменяется. Он реагирует на движение, изменение размера, добавление/удаление элементов и что-то еще. Он не только срабатывает, если элемент затронут, на котором зарегистрировано событие, но также, если затронут какой-либо другой элемент, использующий тот же поток отправки. В результате он срабатывает очень часто, поэтому его использование может иметь довольно большое влияние на производительность.

См. также запись в блоге Dave Relyea. Stackoverflow не позволяет мне отправлять две ссылки, поэтому просто зайдите в Google для "События макета - SizeChanged и LayoutUpdated".

0

Я написал статью о проекте кода о привязке данных к позиции элемента UI:

http://www.codeproject.com/Articles/139216/A-Simple-Technique-for-Data-binding-to-the-Positio

Редактор рабочего процесса также звучит так, как будто он похож на мое графическое и диаграммное управление под названием NetworkView:

http://www.codeproject.com/Articles/182683/NetworkView-A-WPF-custom-control-for-visualizing-a

Ещё вопросы

Сообщество Overcoder
Наверх
Меню