2010-01-05 7 views
5

Próbuję ustawić Adornera w zależności od wymiarów rodzica ozdobnego elementu. Na przykład mam pole tekstowe. Chcę zdobić tę tekstowe tak to wygląda mniej więcej tak:Pozycjonowanie adoratora w stosunku do wymiarów rodzica w WPF

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

Element textbox jest umieszczony w obiekcie płótnie, a jeśli nie ma wystarczająco dużo miejsca, a następnie umieścić adorner (semi przejrzysty zaokrąglony kwadrat) zgodnie z dolna krawędź pola tekstowego. Adorner jest inicjowany, gdy użytkownik kliknie pole tekstowe.

Obecnie płótno i jego zawartość (pole tekstowe) jest hostowane w formularzu WinForm - więc obsługa WPF jest obsługiwana za pomocą kontrolki ElementHost.

Ale kiedy uruchamiam mój kod, po pierwszym kliknięciu pola tekstowego wyświetla on adorner wyrównany do górnej krawędzi pola tekstowego (patrz rysunek poniżej). Następnie ustawia się poprawnie (jak na powyższym rysunku) Czy ktoś wie, dlaczego tak się dzieje?

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

I wklejony kod ten poniżej

TextBoxAdorner.cs - tego adorner logiki

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

Odpowiedz

0

Pozycja w Adorner jest w stosunku do elementów zdobiących. Jeśli chcesz, aby był na górze obiektu, wartość yloc powinna być ujemna. Jednak w kodzie są również granice płótna. Jeśli nie ma dość miejsca na powyższy prostokąt, umieściłby go poniżej. Próbuję umieścić TextBox trochę niżej na płótnie.

Powiązane problemy