2010-01-05 6 views
5

Sto provando a posizionare un dispositivo di decorazione in base alle dimensioni del genitore dell'elemento ornato. Ad esempio, ho una casella di testo. Voglio adornare questo campo testo in modo che appaia qualcosa di simile:Posizionatore di ornamenti relativo alle dimensioni del genitore in WPF

how the adorner needs to be placed http://img707.imageshack.us/img707/9840/fig1.png

una casella di testo viene inserito in un oggetto tela e se c'è abbastanza spazio disponibile quindi inserire l'adorner (quadrato arrotondato semi trasparente) in linea con il bordo inferiore della casella di testo. L'adorner viene avviato quando l'utente fa clic sulla casella di testo.

Attualmente la tela e il suo contenuto (la casella di testo) sono ospitati in un modulo WinForms, quindi il controllo WPF viene gestito dal controllo ElementHost.

Ma quando eseguo il mio codice, quando si fa clic sulla casella di testo per la prima volta, viene visualizzato l'ornamento allineato al bordo superiore della casella di testo (vedere la figura seguente). Dopo di ciò si posiziona correttamente (come nella figura sopra) Qualcuno sa perché potrebbe essere?

how adorner is positions http://img14.imageshack.us/img14/4766/fig2v.png

ho incollato il codice per questo qui sotto:

TextBoxAdorner.cs - questa logica l'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; 
     } 
    } 
} 

risposta

0

La posizione di un Adorner è rispetto all'elemento addorno. Se si desidera che sia nella parte superiore dell'oggetto, il valore di yloc dovrebbe essere negativo. Tuttavia, il codice che hai riguarda anche i confini della tela. Se non c'è abbastanza spazio per il rettangolo sopra, lo metterebbe sotto. Cercando di posizionare il TextBox un po 'più in basso nella tela.