Estoy tratando de colocar un Adorner según las dimensiones del elemento principal del elemento adornado. Por ejemplo, tengo un cuadro de texto. Quiero adornar el campo respectivo por lo que se ve algo como esto:Adorneador de posición relativo a las dimensiones de los padres en WPF
how the adorner needs to be placed http://img707.imageshack.us/img707/9840/fig1.png
Un cuadro de texto se coloca en un objeto de tela y si hay suficiente espacio disponible a continuación, colocar el embellecedor (cuadrado redondeado semi transparente) en línea con las el borde inferior del cuadro de texto. El adorner se inicia cuando el usuario hace clic en el cuadro de texto.
Actualmente, el lienzo y su contenido (el cuadro de texto) se alojan en un formulario de WinForms, por lo que el WPF se maneja mediante el control ElementHost.
Pero cuando ejecuto mi código, cuando se hace clic en el cuadro de texto por primera vez, muestra el adorno alineado con el borde superior del cuadro de texto (ver figura a continuación). Después de eso, se posiciona correctamente (como la figura anterior) ¿Alguien sabe por qué podría ser esto?
how adorner is positions http://img14.imageshack.us/img14/4766/fig2v.png
He pegado el código para este continuación:
TextBoxAdorner.cs - esta lógica la adorner
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;
}
}
}