Я пытаюсь расположить Adorner в зависимости от размеров родителя украшенного элемента. Например, у меня есть текстовое поле. Я хочу украсить это текстовое поле, чтобы оно выглядело примерно так:
как нужно разместить украшения http://img707.imageshack.us/img707/9840/fig1.png
Текстовое поле помещается в объект Canvas и, если на нем достаточно свободного места, поместите рекламный элемент (полупрозрачный квадрат с закругленными углами) в линию с нижним краем текстового поля. Adorner инициируется, когда пользователь нажимает на текстовое поле.
В настоящее время холст и его содержимое (текстовое поле) размещаются в форме WinForms, поэтому WPF обрабатывается элементом управления ElementHost.
Но когда я запускаю свой код, при первом щелчке по текстовому полю на нем отображается выравниватель, выровненный по верхнему краю текстового поля (см. Рисунок ниже). После этого он правильно позиционирует себя (как на рисунке выше) Кто-нибудь знает, почему это может быть?
как украсил позиции http://img14.imageshack.us/img14/4766/fig2v.png
Я вставил код для этого ниже:
TextBoxAdorner.cs - это логика украшения
public class TextBoxAdorner : Adorner
{
private TextBox _adornedElement;
private VisualCollection _visualChildren;
private Rectangle _shape;
private Canvas _container;
private Canvas _parentCanvas;
public TextBoxAdorner(UIElement adornedElement, Canvas parentCanvas)
: base(adornedElement)
{
_adornedElement = (TextBox)adornedElement;
_parentCanvas = parentCanvas;
_visualChildren = new VisualCollection(this);
_container = new Canvas();
_shape = new Rectangle();
_shape.Width = 100;
_shape.Height = 80;
_shape.Fill = Brushes.Blue;
_shape.Opacity = 0.5;
_container.Children.Add(_shape);
_visualChildren.Add(_container);
}
protected override Size ArrangeOverride(Size finalSize)
{
Point location = GetLocation();
_container.Arrange(new Rect(location, finalSize));
return finalSize;
}
private Point GetLocation()
{
if (_parentCanvas == null)
return new Point(0, 0);
Point translate;
double xloc = 0, yloc = _shape.Height - _adornedElement.ActualHeight;
if (yloc < 0) // textbox is bigger than the shape
yloc = 0;
else
{
translate = this.TranslatePoint(new Point(0, -yloc), _parentCanvas);
// coordinate is beyond the position of the parent canvas
if (translate.Y < 0) // this is true the first time it's run
yloc = 0;
else
yloc = -yloc;
}
translate = this.TranslatePoint(new Point(_shape.Width, 0), _parentCanvas);
// textbox is in right edge of the canvas
if (translate.X > _parentCanvas.ActualWidth)
{
double pos = translate.X - _parentCanvas.ActualWidth;
translate = this.TranslatePoint(new Point(-pos,0), _parentCanvas);
if (translate.X < 0)
xloc = 0;
else
xloc = translate.X;
}
return new Point(xloc, yloc);
}
protected override Size MeasureOverride(Size constraint)
{
Size myConstraint = new Size(_shape.Width, _shape.Height);
_container.Measure(myConstraint);
return _container.DesiredSize;
}
protected override Visual GetVisualChild(int index)
{
return _visualChildren[index];
}
protected override int VisualChildrenCount
{
get
{
return _visualChildren.Count;
}
}
}