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