2010-01-05 32 views
5

Tôi đang cố định vị trí một Hình bóng phụ thuộc vào kích thước của phần tử gốc của phần tử được tô điểm. Ví dụ, tôi có một hộp văn bản. Tôi muốn tô điểm cho khung này để nó trông giống như sau:Định vị quảng cáo tương đối so với kích thước của cha mẹ trong WPF

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

Một hộp được đặt trong một đối tượng canvas và nếu có đủ không gian có sẵn sau đó đặt adorner (bán trong suốt tròn vuông) phù hợp với cạnh dưới của hộp văn bản. Adorner được bắt đầu khi người dùng nhấp vào hộp văn bản.

Hiện tại canvas và nội dung của nó (hộp văn bản) được lưu trữ trong biểu mẫu WinForms - do đó WPF được xử lý bằng kiểm soát ElementHost.

Nhưng khi tôi chạy mã của mình, khi hộp văn bản được nhấp lần đầu tiên nó hiển thị đường viền được căn chỉnh với cạnh trên cùng của hộp văn bản (xem hình bên dưới). Sau đó, vị trí của nó chính xác (như hình trên) Có ai biết tại sao điều này có thể là?

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

Tôi đã dán mã này dưới đây:

TextBoxAdorner.cs - các adorner logic

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

Trả lời

0

Vị trí của một adorner là liên quan đến các yếu tố trang trí. Nếu bạn muốn nó ở trên cùng của đối tượng của bạn, giá trị của yloc phải âm. Tuy nhiên, mã bạn cũng có liên quan đến ranh giới của Canvas. Nếu không có đủ chỗ cho hình chữ nhật ở trên, nó sẽ đặt nó bên dưới. Cố gắng đặt TextBox thấp hơn một chút trong Canvas.

Các vấn đề liên quan