2010-01-05 9 views
5

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; 
     } 
    } 
} 

Respuesta

0

La posición de un Adorner es con respecto al elemento adornada. Si desea que esté en la parte superior de su objeto, el valor de yloc debe ser negativo. Sin embargo, el código también tiene en cuenta los límites del lienzo. Si no hay suficiente lugar para el rectángulo de arriba, lo pondría debajo. Tratando de colocar el TextBox un poco más abajo en el lienzo.

Cuestiones relacionadas