Compartir a través de


Cómo hacerlo: Renderizar en un intervalo por cada fotograma mediante CompositionTarget

El motor de animación de WPF proporciona muchas características para crear animaciones basadas en fotogramas. Sin embargo, hay escenarios de aplicación en los que se necesita un control más preciso sobre la representación por fotograma. El CompositionTarget objeto proporciona la capacidad de crear animaciones personalizadas basadas en una devolución de llamada por fotograma.

CompositionTarget es una clase estática que representa la superficie de visualización en la que se dibuja la aplicación. El Rendering evento se genera cada vez que se dibuja la escena de la aplicación. La tasa de fotogramas es el número de veces que se representa la escena por segundo.

Nota:

Para obtener un ejemplo de código completo mediante CompositionTarget, consulte Uso del ejemplo CompositionTarget.

Ejemplo

El evento Rendering se desencadena durante el proceso de renderización de WPF. El siguiente ejemplo muestra cómo registrar un delegado EventHandler en el método estático Rendering de CompositionTarget.

// Add an event handler to update canvas background color just before it is rendered.
CompositionTarget.Rendering += UpdateColor;
' Add an event handler to update canvas background color just before it is rendered.
AddHandler CompositionTarget.Rendering, AddressOf UpdateColor

Puede usar el método de controlador de eventos de representación para crear contenido de dibujo personalizado. Este método de controlador de eventos se llama una vez por fotograma. Cada vez que WPF organiza los datos de representación persistentes en el árbol visual hacia el gráfico de escenas de composición, se invoca el método del controlador de eventos. Además, si los cambios en el árbol visual fuerzan actualizaciones en el gráfico de composición de la escena, también se llama al método del manejador de eventos. Tenga en cuenta que su método controlador de eventos se llama después de que se haya calculado la disposición. Sin embargo, puede modificar el diseño en el método del controlador de eventos, lo que significa que el diseño se calculará una vez más antes de la representación.

En el ejemplo siguiente se muestra cómo puede proporcionar un dibujo personalizado en un CompositionTarget método de controlador de eventos. En este caso, el color de fondo de Canvas se dibuja con un valor de color basado en la posición de coordenada del mouse. Si mueve el mouse dentro de Canvas, cambia su color de fondo. Además, se calcula la velocidad media de fotogramas, en función del tiempo transcurrido actual y del número total de fotogramas representados.

// Called just before frame is rendered to allow custom drawing.
protected void UpdateColor(object sender, EventArgs e)
{
    if (_frameCounter++ == 0)
    {
        // Starting timing.
        _stopwatch.Start();
    }

    // Determine frame rate in fps (frames per second).
    long frameRate = (long)(_frameCounter / this._stopwatch.Elapsed.TotalSeconds);
    if (frameRate > 0)
    {
        // Update elapsed time, number of frames, and frame rate.
        myStopwatchLabel.Content = _stopwatch.Elapsed.ToString();
        myFrameCounterLabel.Content = _frameCounter.ToString();
        myFrameRateLabel.Content = frameRate.ToString();
    }

    // Update the background of the canvas by converting MouseMove info to RGB info.
    byte redColor = (byte)(_pt.X / 3.0);
    byte blueColor = (byte)(_pt.Y / 2.0);
    myCanvas.Background = new SolidColorBrush(Color.FromRgb(redColor, 0x0, blueColor));
}
' Called just before frame is rendered to allow custom drawing.
Protected Sub UpdateColor(ByVal sender As Object, ByVal e As EventArgs)

    If _frameCounter = 0 Then
        ' Starting timing.
        _stopwatch.Start()
    End If
    _frameCounter = _frameCounter + 1

    ' Determine frame rate in fps (frames per second).
    Dim frameRate As Long = CLng(Fix(_frameCounter / Me._stopwatch.Elapsed.TotalSeconds))
    If frameRate > 0 Then
        ' Update elapsed time, number of frames, and frame rate.
        myStopwatchLabel.Content = _stopwatch.Elapsed.ToString()
        myFrameCounterLabel.Content = _frameCounter.ToString()
        myFrameRateLabel.Content = frameRate.ToString()
    End If

    ' Update the background of the canvas by converting MouseMove info to RGB info.
    Dim redColor As Byte = CByte(_pt.X / 3.0)
    Dim blueColor As Byte = CByte(_pt.Y / 2.0)
    myCanvas.Background = New SolidColorBrush(Color.FromRgb(redColor, &H0, blueColor))
End Sub

Es posible que descubra que el dibujo personalizado se ejecuta a diferentes velocidades en diferentes equipos. Esto se debe a que el dibujo personalizado no es independiente de la velocidad de fotogramas. Dependiendo del sistema que esté ejecutando y de la carga de trabajo de ese sistema, el Rendering evento puede llamarse un número diferente de veces por segundo. Para obtener información sobre cómo determinar la funcionalidad y el rendimiento del hardware gráfico para un dispositivo que ejecuta una aplicación WPF, consulte Niveles de representación de gráficos.

Agregar o quitar un delegado de representación EventHandler mientras se activa el evento se retrasará hasta que finalice la activación del evento. Esto es coherente con la forma MulticastDelegateen que se controlan los eventos basados en Common Language Runtime (CLR). Tenga en cuenta que no se garantiza que los eventos de representación se ejecuten en un orden específico. Si tiene varios EventHandler delegados que dependen de un orden determinado, debe registrar un solo Rendering evento y multiplexar los delegados en el orden correcto.

Consulte también