Usar objetos DrawingVisual
Actualización: noviembre 2007
En este tema se proporciona información general sobre cómo utilizar los objetos DrawingVisual en la capa visual de WPF.
Este tema contiene las secciones siguientes.
Objeto DrawingVisual
Contenedor host de DrawingVisual
Crear objetos DrawingVisual
Crear invalidaciones para miembros de FrameworkElement
Proporcionar compatibilidad con las pruebas de posicionamiento
Temas relacionados
Objeto DrawingVisual
DrawingVisual es una clase de dibujo ligera que se utiliza para representar formas, imágenes o texto. Esta clase se considera ligera porque no proporciona administración del diseño ni control de eventos, lo que mejora su rendimiento. Por esta razón, los dibujos son idóneos para fondos e imágenes prediseñadas.
Contenedor host de DrawingVisual
A fin de usar los objetos DrawingVisual, debe crear un contenedor host para ellos. El objeto contenedor host se debe derivar de la clase FrameworkElement, que proporciona el diseño y la compatibilidad con el control de eventos que la clase DrawingVisual no tiene. El objeto contenedor host no muestra ninguna propiedad visible, puesto que su finalidad principal es contener objetos secundarios. Sin embargo, la propiedad Visibility del contenedor host debe estar establecida en Visible; de lo contrario, ninguno de sus elementos secundarios estará visible.
Cuando se crea un objeto contenedor host para objetos visuales, es preciso almacenar las referencias a objeto visuales en VisualCollection. Utilice el método Add para agregar un objeto visual al contenedor host. En el ejemplo siguiente, se crea un objeto contenedor host y se agregan tres objetos visuales a su colección 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);
}
Nota
Para obtener el ejemplo de código completo del que se ha extraído el ejemplo de código anterior, vea Ejemplo Hit Test Using DrawingVisuals.
Crear objetos DrawingVisual
Cuando se crea un objeto DrawingVisual, éste no tiene contenido de dibujo. Puede agregar contenidos de texto, gráficos o imágenes recuperando el objeto DrawingContext del objeto y dibujando en él. Para devolver un contexto de dibujo (DrawingContext), se llama al método RenderOpen de un objeto DrawingVisual.
Para dibujar un rectángulo en DrawingContext, utilice el método DrawRectangle del objeto DrawingContext. Existen métodos similares para dibujar otros tipos de contenido. Cuando haya terminado de dibujar contenido en DrawingContext, llame al método Close para cerrar el DrawingContext y conservar el contenido.
En el ejemplo siguiente, se crea un objeto DrawingVisual y se dibuja un rectángulo en 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;
}
Crear invalidaciones para miembros de FrameworkElement
El objeto contenedor host es responsable de administrar su colección de objetos visuales. Para ello, el contenedor host debe implementar invalidaciones de miembros para la clase FrameworkElement derivada.
En la lista siguiente se describen los dos miembros que se deben invalidar:
GetVisualChild: devuelve un elemento secundario en el índice especificado de la colección de elementos secundarios.
VisualChildrenCount: obtiene el número de elementos secundarios visuales de este elemento.
En el ejemplo siguiente, se implementan invalidaciones para los dos miembros 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];
}
Proporcionar compatibilidad con las pruebas de posicionamiento
El objeto contenedor host puede proporcionar control de eventos aunque no muestre ninguna propiedad visible. Sin embargo, su propiedad Visibility debe estar establecida en Visible. Esto permite crear una rutina de control de eventos para el contenedor host capaz de interceptar los eventos del mouse, tales como soltar el botón primario. A continuación, la rutina de control de eventos puede implementar pruebas de posicionamiento invocando el método HitTest. El parámetro HitTestResultCallback del método hace referencia a un procedimiento definido por el usuario que puede utilizar para determinar la acción resultante de una prueba de posicionamiento.
En el ejemplo siguiente, se implementa la compatibilidad con las pruebas de posicionamiento del objeto contenedor host y sus elementos secundarios.
// 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;
}
Vea también
Conceptos
Información general sobre la representación de gráficos en Windows Presentation Foundation
Realizar pruebas de posicionamiento en la capa visual