2012-04-03 5 views
19

Adorner를 비정상적으로 사용하려고합니다. RichTextBox에 마우스를 올리면 그 위에 Adorner (아래 그림 참조)가 나타나 Adorner에 포함 된 ListBox에 문자열 목록을 추가 할 수 있습니다. 장식 된 요소에 포함 된 구절에 "태그"(Flickr à la)를 추가하는 데 사용됩니다.컨트롤이있는 WPF adorner

adorner diagram

첫째이도 가능하다?

Adorner의 대부분의 예제는 모양 그리기와 같은 사소한 작업을 수행하기 위해 Adorner의 OnRender 메서드를 재정의하는 방법을 보여줍니다. Adorner의 회색 테두리를 만드는 직사각형 세트를 렌더링하는 데 사용할 수있었습니다. Adorner가 표시된 동안 추가되는 텍스트가 추가되어 RichTextBox의 높이가 증가하면 자동으로 크기가 조정됩니다.

protected override void OnRender(DrawingContext drawingContext) 
{ 
    SolidColorBrush grayBrush = new SolidColorBrush(); 
    grayBrush.Color = Color.FromRgb(153, 153, 153); 

    // left 
    drawingContext.DrawRectangle(grayBrush, null, new System.Windows.Rect(1, 1, 5, ActualHeight)); 
    // right 
    drawingContext.DrawRectangle(grayBrush, null, new System.Windows.Rect(ActualWidth - 6, 1, 5, ActualHeight)); 
    //bottom 
    drawingContext.DrawRectangle(grayBrush, null, new System.Windows.Rect(1, ActualHeight, ActualWidth - 2, 5)); 

    // for reasons unimportant to this example the top gray bar is rendered as part of the RichTextBox 

} 

그러나 컨트롤을 추가하는 것은 약간 문제가 있습니다. 일반적으로 WPF의 애도자는 XAML 대신 코드에 자식 컨트롤을 추가해야합니다. DrawingContext adorner - possible to draw stackpanel?에 설명 된 기술을 사용하여 Adorner의 이니셜 라이저 내에서 아무런 문제없이 하위 컨트롤 (예 : TextBox)을 Adorner에 추가하는 방법을 배웠습니다.

그러나 문제는 Adorner 내에서 이러한 컨트롤을 배치하는 것입니다.

회색 배경의 격자를 만들어서 Adorner 하단에 배치 할 수 있다면 좋을 것입니다. 태그가 추가 될 때 Grid의 크기가 변하는 것을 기반으로 Adorner의 자동 크기 조정과 같은 것들이 자동적으로 일어날 것이라고 나는 희망한다. 이 가능 가정 요컨대

는 누구나 아마도를 RichTextBox으로 크기를 조정할 필요가있다 Adorner 하단 (하기가 상대적 Adorner 이내에 하부 태그 관리 영역 를 생성 및 위치 지정하는 방법을 추천 할 콘텐츠 크기 조정)?

답변

38

Huzah! Ghenadie Tanasiev의 도움으로 답변을 얻었습니다.

WPF의 대부분의 컨트롤과 달리, adorners에는 자식 요소 (예 : 추가하려는 컨트롤)를 할당하는 기본 방법이 없습니다. adorners에 아무 것도 추가하지 않으면 해당 OnRender 메서드를 재정의하고 DrawingContext 안에 전달되는 내용을 그릴 수 있습니다. 솔직하게 말하면 이것은 아마 장식자를위한 유스 케이스의 99 % (객체 주변에 드래그 핸들을 만드는 것과 같은 것)에 맞지만, 적절한 컨트롤을 내 Adorner에 추가해야했습니다.

이 작업을 수행하는 트릭은 VisualCollection을 만들고 컬렉션 생성자로 전달하여 adorner를 소유자로 설정하는 것입니다.

이것은 모두 포괄적으로 this blog article에 설명되어 있습니다. 불행히도 Ghenadie의 안내 덕분에 VisualCollection을 검색 할 때까지 내 Google 검색에서이 기사를 표시하지 않았습니다.

이 기사에서 언급하지는 않았지만 adorner의 OnRender 메서드에서 VisualCollection 기술과 드로잉을 결합 할 수 있습니다. OnRender를 사용하여 위에 나와있는 다이어그램에 설명 된 옆면과 위쪽 테두리를 얻은 다음 VisualCollection을 사용하여 컨트롤을 배치하고 만듭니다. 실제로 수있는 방법을 마련하려고 몇 시간 동안이 방법으로 주변에 바이올린을했다

public class AdornerContentPresenter : Adorner 
{ 
    private VisualCollection _Visuals; 
    private ContentPresenter _ContentPresenter; 

    public AdornerContentPresenter(UIElement adornedElement) 
    : base(adornedElement) 
    { 
    _Visuals = new VisualCollection(this); 
    _ContentPresenter = new ContentPresenter(); 
    _Visuals.Add(_ContentPresenter); 
    } 

    public AdornerContentPresenter(UIElement adornedElement, Visual content) 
    : this(adornedElement) 
    { Content = content; } 

    protected override Size MeasureOverride(Size constraint) 
    { 
    _ContentPresenter.Measure(constraint); 
    return _ContentPresenter.DesiredSize; 
    } 

    protected override Size ArrangeOverride(Size finalSize) 
    { 
    _ContentPresenter.Arrange(new Rect(0, 0, 
     finalSize.Width, finalSize.Height)); 
    return _ContentPresenter.RenderSize; 
    } 

    protected override Visual GetVisualChild(int index) 
    { return _Visuals[index]; } 

    protected override int VisualChildrenCount 
    { get { return _Visuals.Count; } } 

    public object Content 
    { 
    get { return _ContentPresenter.Content; } 
    set { _ContentPresenter.Content = value; } 
    } 
} 
+1

http://social.msdn.microsoft.com/Forums/en-US/ 참조하십시오. wpf/thread/81eca7d5-88d7-477a-8cdb-cfb9e8b75379/ –

+0

잘 알려지지 않았습니다. – Basic

3

손이 더러울 필요는 없습니다. 이전에 사용했던 this CodeProject article을 살펴보십시오. 그것은 당신이 바인딩을 수행 XAML에 adorners을 정의 할 수 있습니다

+0

: 편집

: 그것은 더 이상 사용할 수 없기 때문에 여기가 언급 한 블로그 게시물에서 소스 코드입니다 위에 설명 된 위치 지정을 구현할 수 있지만 CodeProject 예제의 코드가 내가하고 싶은 것을 수용하기에 충분히 견고하다고는 생각하지 않습니다. 예를 들어, 내가 장식 한 요소의 경계에 작성한 모든 adorner를 클리핑하고 있습니다. (매우 이상한 점은, ad-node의 z-index가 항상 위에 있다고 가정 할 때입니다.) AdornedControl.AdornerContent 아래에있는 요소의 높이를 장식 된 요소의 ActualHeight에 바인딩하는 것과 같은 테스트를 시도했지만 이렇게하지 못했습니다 (자동으로). –

+0

예, 클리핑을했는데, 나는 그것이 장식 된 요소가 아닌 레이아웃에 클립하는 것을 발견했습니다. 당신의 문제에 관해서는 또 다른 표정이 있습니다. –

+0

Je vous remercie, Baboon. :) 나는 오늘 오후에 그 일을 계속 지키고 배운 것을보고 할 것입니다. –

관련 문제