2010-01-05 8 views
5

Ich versuche, einen Adorner abhängig von den Abmessungen des übergeordneten Elements des geschmückten Elements zu positionieren. Zum Beispiel habe ich ein Textfeld. Ich mag diese Textbox schmücken, so dass es so etwas wie folgt aussieht:Platzieren von Adornern relativ zu den Dimensionen des übergeordneten Elements in WPF

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

Eine Textbox in einem Canvas-Objekt platziert ist, und wenn es genügend Platz Platz zur Verfügung steht dann die adorner (halbtransparent abgerundetes Quadrat) im Einklang mit der untere Rand der Textbox. Der Adorner wird initiiert, wenn der Benutzer auf das Textfeld klickt.

Momentan wird die Zeichenfläche und ihr Inhalt (die Textbox) in einem WinForms-Formular gehostet - also wird die WPF vom ElementHost-Steuerelement gehandhabt.

Aber wenn ich meinen Code ausführe, wenn das Textfeld zum ersten Mal angeklickt wird, wird der Adorner am oberen Rand des Textfeldes angezeigt (siehe Abbildung unten). Danach positioniert es sich korrekt (wie die obige Abbildung) Weiß jemand, warum das so sein könnte?

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

Ich habe den Code für diesen unten eingefügt:

TextBoxAdorner.cs - das ist die Logik 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; 
     } 
    } 
} 

Antwort

0

Die Position eines Adorner ist relativ zum adorned Element. Wenn Sie möchten, dass es an der Spitze Ihres Objekts liegt, sollte der Wert yloc negativ sein. Der Code, den Sie haben, berücksichtigt jedoch auch die Grenzen des Canvas. Wenn für das obige Rechteck nicht genug Platz ist, würde es darunter liegen. Versuchen Sie, die TextBox im Canvas etwas tiefer zu platzieren.

Verwandte Themen