Ответ 1
Huzah! С помощью Геннадий Танасиев, у меня есть ответ.
В отличие от большинства элементов управления в WPF, у adorners нет никакого готового способа назначения дочерних элементов (таких как элементы управления, которые я хотел добавить). Не добавляя ничего в adorners, вы можете только переопределить их метод OnRender
и нарисовать материал в DrawingContext
, который будет передан в него. Честно говоря, это подходит, вероятно, для 99% случаев использования для adorners (например, для создания элементов управления движением вокруг объекта), но мне нужно было добавить некоторые правильные элементы управления моему Adorner.
Трюк для этого заключается в создании VisualCollection
и установки вашего adorner в качестве его владельца, передав его в конструктор коллекции.
Все это описано довольно подробно в в этой статье в блоге. К сожалению, мои повторные поисковые запросы Google не превращали эту статью, пока я не знал, что нужно искать VisualCollection
, благодаря руководству Генади.
Это не упоминается в статье, но обратите внимание, что можно комбинировать технику VisualCollection вместе с рисованием в методе OnRender у adorner. Я использую OnRender для достижения боковых и верхних границ, описанных в диаграмме выше, и используя VisualCollection для размещения и создания элементов управления.
Изменить: вот исходный код из упомянутого сообщения в блоге, поскольку он больше не доступен:
public class AdornerContentPresenter : Adorner
{
private VisualCollection _Visuals;
private ContentPresenter _ContentPresenter;
public AdornerContentPresenter(UIElement adornedElement)
: base(adornedElement)
{
_Visuals = new VisualCollection(this);
_ContentPresenter = new ContentPresenter();
_Visuals.Add(_ContentPresenter);
}
public AdornerContentPresenter(UIElement adornedElement, Visual content)
: this(adornedElement)
{ Content = content; }
protected override Size MeasureOverride(Size constraint)
{
_ContentPresenter.Measure(constraint);
return _ContentPresenter.DesiredSize;
}
protected override Size ArrangeOverride(Size finalSize)
{
_ContentPresenter.Arrange(new Rect(0, 0,
finalSize.Width, finalSize.Height));
return _ContentPresenter.RenderSize;
}
protected override Visual GetVisualChild(int index)
{ return _Visuals[index]; }
protected override int VisualChildrenCount
{ get { return _Visuals.Count; } }
public object Content
{
get { return _ContentPresenter.Content; }
set { _ContentPresenter.Content = value; }
}
}