DrawingVisual 개체 사용

이 항목에서는 WPF 시각적 계층에서 DrawingVisual 개체를 사용하는 방법에 관한 개요를 제공합니다.

DrawingVisual 개체

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

DrawingVisual 호스트 컨테이너

사용 하기 위해 DrawingVisual 개체를 개체에 대 한 호스트 컨테이너를 만들어야 합니다. 호스트 컨테이너 개체는 DrawingVisual 클래스에 없는 레이아웃 및 이벤트 처리 지원을 제공하는 FrameworkElement 클래스에서 파생되어야 합니다. 호스트 컨테이너 개체는 주 목적이 자식 개체를 포함하는 것이므로 표시 가능한 속성을 표시하지 않습니다. 그러나 호스트 컨테이너의 Visibility 속성을 Visible로 설정해야 합니다. 그렇지 않으면 해당 자식 요소가 표시되지 않습니다.

시각적 개체에 대한 호스트 컨테이너 개체를 만들 때 VisualCollection에 시각적 개체 참조를 저장해야 합니다. Add 메서드를 사용하여 호스트 컨테이너에 시각적 개체를 추가합니다. 다음 예제에서는 호스트 컨테이너 개체가 만들어지고 3개의 시각적 개체가 해당 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 : 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);
    }
' 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

참고

위의 코드 예제가 발췌된 전체 코드 샘플을 보려면 DrawingVisuals를 사용하여 적중 테스트 샘플을 참조하세요.

DrawingVisual 개체 만들기

만들 때를 DrawingVisual 개체를 그리기 내용이 없습니다. 개체의 DrawingContext를 검색하고 끌어와서 텍스트, 그래픽 또는 이미지 콘텐츠를 추가할 수 있습니다. DrawingContextDrawingVisual 개체의 RenderOpen 메서드를 호출하여 반환됩니다.

사각형을 DrawingContext에 그리려면 DrawingContext 개체의 DrawRectangle 메서드를 사용합니다. 다른 형식의 콘텐츠를 그리기 위한 비슷한 메서드가 존재합니다. DrawingContext에 콘텐츠 그리기를 마치면 Close 메서드를 호출하여 DrawingContext를 닫고 콘텐츠를 유지합니다.

다음 예제에서는 DrawingVisual 개체가 만들어지고 해당 DrawingContext에 사각형이 그려집니다.

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

FrameworkElement 멤버에 대한 재정의 만들기

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

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

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

  • VisualChildrenCount: 이 요소 내 시각적 자식 요소의 수를 가져옵니다.

다음 예제에서는 두 FrameworkElement 멤버에 대한 재정의가 구현됩니다.


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


' 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

적중 테스트 지원 제공

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

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

// 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)
{
    // Retrieve 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;
}
' 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)
    ' Retrieve 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

참고 항목