Partilhar via


Using DrawingVisual Objects

Este tópico fornece uma visão geral de como usar objetos DrawingVisual na camada visual WPF.

Este tópico contém as seguintes seções.

  • Objeto Visual de Desenho

  • Contêiner para Hospedagem de DrawingVisual

  • Criação de Objetos DrawingVisual

  • Criação de Substituições para Elementos FrameworkElement

  • Oferecimento de Suporte a Teste de Clique

  • Tópicos relacionados

Objeto DrawingVisual

A DrawingVisual é uma classe leve utilizada para renderizar formas, imagens ou texto. Esta classe é considerada leve porque não fornece layout ou manipulação de eventos, o que melhora o seu desempenho. Por este motivo, os desenhos são ideais para planos de fundo e clip art.

Contêiner para Hospedagem de DrawingVisual

Para poder usar objetos DrawingVisual, é necessário criar um contêiner para hospedá-los, denominado "contêiner host". O objeto contêiner host deve ser derivado da classe FrameworkElement, que fornece o suporte a layout e manipulação de eventos não fornecido pela classe DrawingVisual. O objeto contêiner host não exibe nenhuma propriedade visível, pois sua principal função é conter objetos filhos. No entanto, a propriedade Visibility do contêiner host deve ser definida como Visible; caso contrário, nenhum de seus elementos filho será visível.

Quando você cria um objeto contêiner para hospedagem de objetos visuais, é necessário armazenar as referências dos objetos visuais em um VisualCollection. Use o método Add para adicionar um objeto visual no contêiner host. No exemplo a seguir, cria-se um objeto contêiner host, e adiciona-se três objetos visuais a seu 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);
    }
ObservaçãoObservação:

Para obter a amostra de código completo do qual o exemplo de código anterior foi extraído, consulte Teste usando o exemplo de DrawingVisuals de visitas.

Criação de Objetos DrawingVisual

Quando você cria um objeto DrawingVisual, ele não possui nenhum conteúdo desenhado. Você pode adicionar conteúdo com texto, gráficos, ou imagens ao recuperar o DrawingContext do objeto para desenhar nele. Um DrawingContext é retornado ao chamar o método RenderOpen de um objeto DrawingVisual.

Para desenhar um retângulo no DrawingContext, use o método DrawRectangle do objeto DrawingContext. Existem métodos semelhantes para desenhar outros tipos de conteúdo. Quando você terminar de desenhar conteúdo no DrawingContext, chame o método Close para fechar o DrawingContext e fazer persistir o conteúdo.

No exemplo a seguir, cria-se um objeto DrawingVisual, e desenha-se um retângulo em seu 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;
}

Criação de Substituições para Elementos FrameworkElement

O objeto contêiner host é responsável pelo gerenciamento de sua coleção de objetos visuais. Isto requer que o contêiner host implemente substituição de membros para a classe FrameworkElement derivada.

A lista a seguir descreve os dois membros que você deve substituir:

  • GetVisualChild: Retorna um filho no índice especificado da coleção de elementos filhos.

  • VisualChildrenCount: Obtém o número de elementos filhos visuais dentro deste elemento.

No exemplo a seguir, implementa-se substituições para os dois membros de 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];
}

Oferecimento de Suporte a Teste de Clique

O objeto contêiner host pode fornecer manipulação de eventos mesmo que ele não exiba nenhuma propriedade visível—no entanto, sua propriedade Visibility deve ser definida como Visible. Isto permite que você crie uma rotina de manipulação de eventos para o contêiner host que pode capturar eventos de mouse, tais como o soltar do botão esquerdo do mouse. A rotina de manipulação de eventos pode, então, implementar o teste de clique ao invocar o método HitTest. O parâmetro HitTestResultCallback do método refere-se ao procedimento definido pelo usuário que você pode usar para determinar a ação que resulta de um teste de clique.

No exemplo a seguir, implementa-se suporte a teste de clique para o objeto contêiner host e seus filhos.

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

Consulte também

Conceitos

Visão Geral sobre Renderização de Gráficos do Windows Presentation Foundation

Hit Testing in the Visual Layer

Referência

DrawingVisual

HitTest