Nasıl yapılır: CompositionTarget Kullanarak Çerçeve Aralığı Başına İşleme

WPF animasyon altyapısı, çerçeve tabanlı animasyon oluşturmak için birçok özellik sağlar. Ancak, çerçeve başına işleme üzerinde daha ayrıntılı denetime ihtiyacınız olan uygulama senaryoları vardır. CompositionTargetNesnesi, çerçeve başına geri çağırma temelinde özel animasyonlar oluşturma olanağı sağlar.

CompositionTarget , uygulamanızın çizildiği görüntü yüzeyini temsil eden bir statik sınıftır. RenderingOlay, uygulamanın sahneyi her çizililişinde tetiklenir. İşleme çerçeve oranı, sahnenin saniye başına çizilme sayısıdır.

Not

Kullanarak tüm kod örnekleri için CompositionTarget bkz. CompositionTarget.

Örnek

Bu Rendering olay WPF işleme işlemi sırasında ateşlenir. Aşağıdaki örnek, EventHandler üzerinde statik metoda bir temsilciyi nasıl kaydedeceğinizi gösterir RenderingCompositionTarget .

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

İşleme olay işleyicisi yönteminizi özel çizim içeriği oluşturmak için kullanabilirsiniz. Bu olay işleyicisi yöntemi çerçeve başına bir kez çağırılır. WPF, görsel ağaçtaki kalıcı işleme verilerini bileşim sahne grafiğine her sıraladığında olay işleyicisi yönteminiz çağırılır. Ayrıca, görsel ağaçtaki değişiklikler kompozisyon sahneyi grafiğinde güncelleştirmelere zorlmaya zorlandıysanız olay işleyicisi yönteminiz de çağırılır. Olay işleyicisi yönteminizin düzen hesaplandıktan sonra çağrıldığını unutmayın. Bununla birlikte, olay işleyicisi yönteminizin düzeninde değişiklik yapabilirsiniz. Bu, düzenin işlemeden önce daha fazla hesaplanacaktır.

Aşağıdaki örnek, bir olay işleyicisi yönteminde nasıl özel çizim sağlayakullanabileceğinizi gösterir CompositionTarget . Bu durumda, öğesinin arka plan rengi, Canvas farenin koordinat konumuna göre bir renk değeri ile çizilir. Fareyi içinde taşırsanız Canvas , arka plan rengi değişir. Ayrıca, ortalama kare hızı geçerli geçen süreye ve işlenen çerçevelerin toplam sayısına göre hesaplanır.

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

Özel çiziminizin farklı bilgisayarlarda farklı hızlarda çalıştığını fark edebilirsiniz. Bunun nedeni, özel çiziminizde kare hızına bağımsız değildir. Çalıştırdığınız sisteme ve bu sistemin iş yüküne bağlı olarak, Rendering olay saniyede farklı sayıda kez çağrılabilir. WPF uygulaması çalıştıran bir cihazın grafik donanım yeteneğini ve performansını belirleme hakkında bilgi için bkz. grafik Işleme katmanları.

Olay başlatıldıktan sonra bir işleme temsilcisini ekleme veya kaldırma EventHandler , olayın başlatılması bitinceye kadar gecikecek. Bu, MulticastDelegate ortak dil çalışma zamanında (CLR), tabanlı olayların işlenme ile tutarlıdır. Ayrıca, işleme olaylarının belirli bir sırada çağrılması garanti edilmez. EventHandlerBelirli bir siparişi kullanan birden fazla temsilcileriniz varsa, tek bir Rendering olayı kaydetmeniz ve temsilcileri doğru sırada kendiniz de çoğullamalısınız.

Ayrıca bkz.