장식 된 요소의 부모 치수에 따라 Adorner를 배치하려고합니다. 예를 들어, 텍스트 상자가 있습니다. 나는 이런 식으로 뭔가 보이는 있도록이 텍스트 상자를 장식 할 : 텍스트 상자가 캔버스 객체에 배치됩니다WPF의 상위 차원에 상대적인 위치 지정 adorner
how the adorner needs to be placed http://img707.imageshack.us/img707/9840/fig1.png
을 충분한 공간을 사용할 수있는 경우 다음 줄의 adorner (반 투명 둥근 사각형)와 배치 텍스트 상자의 아래쪽 가장자리 사용자가 텍스트 상자를 클릭하면 adorner가 시작됩니다.
현재 캔버스와 그 내용 (텍스트 상자)은 WinForms 형식으로 호스팅되어 있으므로 WPF는 ElementHost 컨트롤로 처리됩니다.
그러나 코드를 실행할 때 텍스트 상자를 처음 클릭 할 때 텍스트 상자의 위쪽 가장자리에 정렬 된 adorner가 표시됩니다 (아래 그림 참조). 그 후 그것은 위의 그림과 같이 올바르게 위치를 잡습니다. 왜 이것이 그럴지 알 수 있습니까?
how adorner is positions http://img14.imageshack.us/img14/4766/fig2v.png
나는 아래이에 대한 코드를 붙여 넣은 :
TextBoxAdorner.cs - 이것을 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;
}
}
}