다음을 통해 공유


DrawingVisual 개체 사용

이 항목에서는 WPF 시각적 계층에서 DrawingVisual 개체를 사용하는 방법을 간략하게 설명합니다.

이 항목에는 다음 단원이 포함되어 있습니다.

  • DrawingVisual 개체

  • DrawingVisual 호스트 컨테이너

  • DrawingVisual 개체 만들기

  • FrameworkElement 멤버 재정의 만들기

  • 적중 테스트 지원

  • 관련 항목

DrawingVisual 개체

DrawingVisual은 도형, 이미지 또는 텍스트를 렌더링하는 데 사용되는 간단한 그리기 클래스입니다. 이 클래스는 성능을 향상시키는 레이아웃이나 이벤트 처리를 제공하지 않으므로 간단한 클래스로 간주됩니다. 이러한 이유 때문에 그리기는 배경 및 클립 아트에 적합합니다.

DrawingVisual 호스트 컨테이너

DrawingVisual 개체를 사용하려면 개체의 호스트 컨테이너를 만들어야 합니다. 호스트 컨테이너 개체는 DrawingVisual 클래스에서 지원하지 않는 레이아웃 및 이벤트 처리 기능을 지원하는 FrameworkElement 클래스에서 파생되어야 합니다. 호스트 컨테이너 개체의 기본 목적은 자식 개체를 포함하는 것이기 때문에 이 개체는 아무 속성도 표시하지 않습니다. 그러나 호스트 컨테이너의 Visibility 속성은 반드시 Visible로 설정되어야 합니다. 그렇지 않으면 자식 요소가 표시되지 않습니다.

시각적 개체의 호스트 컨테이너 개체를 만들 때 시각적 개체 참조는 VisualCollection에 저장해야 합니다. Add 메서드를 사용하여 시각적 개체를 호스트 컨테이너에 추가할 수 있습니다. 다음 예제에서는 호스트 컨테이너 개체를 만들고 해당 VisualCollection에 시각적 개체 세 개를 추가합니다.

    ' Create a host visual derived from the FrameworkElement class.
    ' This class provides layout, event handling, and container support for
    ' the child visual objects.
    Public Class MyVisualHost
        Inherits FrameworkElement
        ' Create a collection of child visual objects.
        Private _children As VisualCollection

        Public Sub New()
            _children = New VisualCollection(Me)
            _children.Add(CreateDrawingVisualRectangle())
            _children.Add(CreateDrawingVisualText())
            _children.Add(CreateDrawingVisualEllipses())

            ' Add the event handler for MouseLeftButtonUp.
            AddHandler MouseLeftButtonUp, AddressOf MyVisualHost_MouseLeftButtonUp
        End Sub
// Create a host visual derived from the FrameworkElement class.
// This class provides layout, event handling, and container support for
// the child visual objects.
public class MyVisualHost : FrameworkElement
{
    // Create a collection of child visual objects.
    private VisualCollection _children;

    public MyVisualHost()
    {
        _children = new VisualCollection(this);
        _children.Add(CreateDrawingVisualRectangle());
        _children.Add(CreateDrawingVisualText());
        _children.Add(CreateDrawingVisualEllipses());

        // Add the event handler for MouseLeftButtonUp.
        this.MouseLeftButtonUp += new System.Windows.Input.MouseButtonEventHandler(MyVisualHost_MouseLeftButtonUp);
    }
참고참고

앞의 코드 예제를 추출한 전체 코드 샘플을 보려면 Hit Test Using DrawingVisuals 샘플을 참조하십시오.

DrawingVisual 개체 만들기

DrawingVisual 개체를 만드는 경우 기본적으로 그리기 내용이 없는 개체가 생성됩니다. 개체의 DrawingContext를 검색하고 여기에 그림을 그려서 텍스트, 그래픽 또는 이미지 콘텐츠를 추가할 수 있습니다. DrawingVisual 개체의 RenderOpen 메서드를 호출하면 DrawingContext가 반환됩니다.

DrawingContext에 사각형을 그리려면 DrawingContext 개체의 DrawRectangle 메서드를 사용합니다. 다른 종류의 콘텐츠를 그릴 수 있는 이와 유사한 다른 메서드도 있습니다. DrawingContext에 콘텐츠 그리기를 마쳤으면 Close 메서드를 호출하여 DrawingContext를 닫고 콘텐츠를 유지합니다.

다음 예제에서는 DrawingVisual 개체를 만들고 해당 DrawingContext에 사각형을 그립니다.

        ' Create a DrawingVisual that contains a rectangle.
        Private Function CreateDrawingVisualRectangle() As DrawingVisual
            Dim drawingVisual As New DrawingVisual()

            ' Retrieve the DrawingContext in order to create new drawing content.
            Dim drawingContext As DrawingContext = drawingVisual.RenderOpen()

            ' Create a rectangle and draw it in the DrawingContext.
            Dim rect As New Rect(New Point(160, 100), New Size(320, 80))
            drawingContext.DrawRectangle(Brushes.LightBlue, CType(Nothing, Pen), rect)

            ' Persist the drawing content.
            drawingContext.Close()

            Return drawingVisual
        End Function
// Create a DrawingVisual that contains a rectangle.
private DrawingVisual CreateDrawingVisualRectangle()
{
    DrawingVisual drawingVisual = new DrawingVisual();

    // Retrieve the DrawingContext in order to create new drawing content.
    DrawingContext drawingContext = drawingVisual.RenderOpen();

    // Create a rectangle and draw it in the DrawingContext.
    Rect rect = new Rect(new System.Windows.Point(160, 100), new System.Windows.Size(320, 80));
    drawingContext.DrawRectangle(System.Windows.Media.Brushes.LightBlue, (System.Windows.Media.Pen)null, rect);

    // Persist the drawing content.
    drawingContext.Close();

    return drawingVisual;
}

FrameworkElement 멤버 재정의 만들기

호스트 컨테이너 개체는 시각적 개체 컬렉션을 관리합니다. 그러기 위해서는 호스트 컨테이너가 파생된 FrameworkElement 클래스의 멤버 재정의를 구현해야 합니다.

다음 목록에서는 재정의해야 하는 두 가지 멤버를 설명합니다.

  • GetVisualChild: 자식 요소 컬렉션에서 지정한 인덱스에 있는 자식을 반환합니다.

  • VisualChildrenCount: 이 요소에 포함된 시각적 자식 요소의 개수를 가져옵니다.

다음 예제에서는 두 가지 FrameworkElement 멤버의 재정의를 구현합니다.


        ' Provide a required override for the VisualChildrenCount property.
        Protected Overrides ReadOnly Property VisualChildrenCount() As Integer
            Get
                Return _children.Count
            End Get
        End Property

        ' Provide a required override for the GetVisualChild method.
        Protected Overrides Function GetVisualChild(ByVal index As Integer) As Visual
            If index < 0 OrElse index >= _children.Count Then
                Throw New ArgumentOutOfRangeException()
            End If

            Return _children(index)
        End Function


        // Provide a required override for the VisualChildrenCount property.
        protected override int VisualChildrenCount
        {
            get { return _children.Count; }
        }

        // Provide a required override for the GetVisualChild method.
        protected override Visual GetVisualChild(int index)
        {
            if (index < 0 || index >= _children.Count)
            {
                throw new ArgumentOutOfRangeException();
            }

            return _children[index];
        }

적중 테스트 지원

호스트 컨테이너 개체는 아무런 속성도 표시하지 않는 경우에도 이벤트 처리 기능을 제공할 수 있습니다. 단, 호스트 컨테이너 개체의 Visibility 속성은 Visible로 설정되어 있어야 합니다. 이를 통해 사용자는 왼쪽 마우스 단추 놓기와 같은 마우스 이벤트를 트래핑하는 이벤트 처리 루틴을 호스트 컨테이너에 만들 수 있습니다. 그런 후 HitTest 메서드를 호출하여 이 이벤트 처리 루틴을 통해 적중 테스트를 구현할 수 있습니다. 이 메서드의 HitTestResultCallback 매개 변수는 적중 테스트 결과에 따른 작업을 결정하는 데 사용할 수 있는 사용자 정의 프로시저를 참조합니다.

다음 예제에서는 호스트 컨테이너 개체와 해당 자식에 대해 적중 테스트 지원을 구현합니다.

        ' Capture the mouse event and hit test the coordinate point value against
        ' the child visual objects.
        Private Sub MyVisualHost_MouseLeftButtonUp(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
            ' Retreive the coordinates of the mouse button event.
            Dim pt As Point = e.GetPosition(CType(sender, UIElement))

            ' Initiate the hit test by setting up a hit test result callback method.
            VisualTreeHelper.HitTest(Me, Nothing, New HitTestResultCallback(AddressOf myCallback), New PointHitTestParameters(pt))
        End Sub

        ' If a child visual object is hit, toggle its opacity to visually indicate a hit.
        Public Function myCallback(ByVal result As HitTestResult) As HitTestResultBehavior
            If result.VisualHit.GetType() Is GetType(DrawingVisual) Then
                If (CType(result.VisualHit, DrawingVisual)).Opacity = 1.0 Then
                    CType(result.VisualHit, DrawingVisual).Opacity = 0.4
                Else
                    CType(result.VisualHit, DrawingVisual).Opacity = 1.0
                End If
            End If

            ' Stop the hit test enumeration of objects in the visual tree.
            Return HitTestResultBehavior.Stop
        End Function
// Capture the mouse event and hit test the coordinate point value against
// the child visual objects.
void MyVisualHost_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
    // Retreive the coordinates of the mouse button event.
    System.Windows.Point pt = e.GetPosition((UIElement)sender);

    // Initiate the hit test by setting up a hit test result callback method.
    VisualTreeHelper.HitTest(this, null, new HitTestResultCallback(myCallback), new PointHitTestParameters(pt));
}

// If a child visual object is hit, toggle its opacity to visually indicate a hit.
public HitTestResultBehavior myCallback(HitTestResult result)
{
    if (result.VisualHit.GetType() == typeof(DrawingVisual))
    {
        if (((DrawingVisual)result.VisualHit).Opacity == 1.0)
        {
            ((DrawingVisual)result.VisualHit).Opacity = 0.4;
        }
        else
        {
            ((DrawingVisual)result.VisualHit).Opacity = 1.0;
        }
    }

    // Stop the hit test enumeration of objects in the visual tree.
    return HitTestResultBehavior.Stop;
}

참고 항목

참조

DrawingVisual

HitTest

개념

WPF 그래픽 렌더링 개요

시각적 계층에서 적중 테스트