Role of the Visual Object

Provides support for:

  • Output display
    • Rendering the persisted, serialzied drawing content of a visual.
  • Transformations
  • Clipping
  • Hit testing
    • Detemining whether a coordinate or geometry is contained within the bounds of a visual.
  • Bounding box calculations

Not include support for non-rendering features:

  • Event handling
  • Layout
  • Styles
  • Data binding
  • Globalization

시각적 개체 클래스 계층 구조

DrawingVisual Class

A lightweight drawing class that is used to render shapes, images, or text.

It does not provide layout or event handling, which improves its runtime performance.

Ideal for backgrounds and clip art.

 

Viewport3DVisual class

 

ContainerVisual class

Used as a container for a collection of Visual Objects.

Drawing Content in Visual Objects

Drawing Content at the Visual Layer

You never directly instantiate a DrawingContext;

you can, however, acquire a drawing context from certain methods, such as:

  • DrawingOpen.Open
  • DrawingVisual.RenderOpen
// Create a DrawingVisual that contains a rectangle.
private DrawingVisual CreateDrawingVisualRectangle()
{
    var dv = new DrawingVisual();
 
    // Retrieve the DrawingContext in order to create new drawing content.
    DrawingContext dc = dv.RenderOpen();
 
    // Create a rectangle and draw it in the DrawingContext.
    Rect rect = new Rect(new Point(160, 100), new Size(320, 80));
    dc.DrawRectangle(Brushes.LightBlue, (System.Windows.Media.Pen)null, rect);
 
    // Persist the drawing content.
    dc.Close();
 
    return dv;
}

Enumerating Drawing Content at the Visual Layer

public void RetrieveDrawing(Visual v)
{
    DrawingGroup dg = VisualTreeHelper.GetDrawing(v);
    EnumDrawingGroup(dg);
}
 
// Enumerate the drawings in the DrawingGroup.
public void EnumDrawingGroup(DrawingGroup dg)
{
    DrawingCollection dc = dg.Children;
 
    // Enumerate the drawings in the DrawingCollection.
    foreach (Drawing drawing in dc)
    {
        // If the drawing is a DrawingGroup, call the function recursively.
        if (drawing is DrawingGroup group)
        {
            EnumDrawingGroup(group);
        }
        else if (drawing is GeometryDrawing)
        {
            // Perform action based on drawing type.  
        }
        else if (drawing is ImageDrawing)
        {
            // Perform action based on drawing type.
        }
        else if (drawing is GlyphRunDrawing)
        {
            // Perform action based on drawing type.
        }
        else if (drawing is VideoDrawing)
        {
            // Perform action based on drawing type.
        }
    }
}

 

How Visual Objects are Used to Build Controls

 

Visual Tree

 

Visual Rendering Behavior

 

VisualTreeHelper Class

 

Hit Testing

 

Enumerating the Visual Tree

// Enumerate all the descendants of the visual object.
static public void EnumVisual(Visual myVisual)
{
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(myVisual); ++i)
    {
        // Retrieve child visual at specified index value.
        var childVisual = VisualTreeHelper.GetChild(myVisual, i) as Visual;
 
        // Do processing of the child visual object.
 
        // Enumerate children of the child visual object.
        EnumVisual(childVisual);
    }
}
// Returns the cached bounding box rectangle for the the specified Visual.
Rect rcBounds = VisualTreeHelper.GetContentBounds(myVisual);
 
// Return the bounding rectangle of the parent visual object and all of its descendants.
Rect rcBounds = VisualTreeHelper.GetDescendantBounds(parentVisual);

 

'.NET > WPF' 카테고리의 다른 글

WPF CustomControl  (0) 2021.08.15
Adorner  (0) 2021.08.15
Routed Event  (0) 2021.08.15
ScrollViewer Tips  (0) 2021.08.15
Save Canvas as an Image  (0) 2021.08.15

+ Recent posts