Мне нужно что-то, чтобы получить позицию суб-вспомогательного элемента относительно контейнера. 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 только для улучшения удобочитаемости)
Если вы реализуете свой контейнер с прикрепленными свойствами зависимостей для расположения дочерних элементов (например, панель Canvas, которая, кажется, случай согласно предоставленному коду), то вы можете привязать к изменениям этого свойства зависимостей, используя DependencyPropertyDescriptor.
DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty(Canvas.TopProperty, typeof(Canvas));
dpd.AddValueChanged(canvas1, new EventHandler(topChangedCallback));
Я предлагаю использовать решение kek444 с настраиваемой компоновкой, если это возможно. Однако, если это не применимо, вот еще один вопрос, который я нашел во время подсказок kek444 googling.
Событие UIElement.LayoutUpdated запускается всякий раз, когда что-то на макете изменяется. Он реагирует на движение, изменение размера, добавление/удаление элементов и что-то еще. Он не только срабатывает, если элемент затронут, на котором зарегистрировано событие, но также, если затронут какой-либо другой элемент, использующий тот же поток отправки. В результате он срабатывает очень часто, поэтому его использование может иметь довольно большое влияние на производительность.
См. также запись в блоге Dave Relyea. Stackoverflow не позволяет мне отправлять две ссылки, поэтому просто зайдите в Google для "События макета - SizeChanged и LayoutUpdated".
Я написал статью о проекте кода о привязке данных к позиции элемента 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