はじめに
WPF で DrawingContext を利用した描画処理を実装している時に、次の画面再描画時に纏めて処理を実行したいことがありました。
所謂 JavaScript の Window.requestAnimationFrame 的なことを WPF でしたいというお話です。
確認時のバージョン情報
- 
.NET: 8.0.204
CompositionTarget.Rendering
方法: CompositionTarget を使用したフレームの間隔ごとの描画 - WPF .NET Framework | Microsoft Learn
CompositionTargetは、アプリケーションが描画される表示サーフェイスを表す静的クラスです。
アプリケーションのシーンが描画されるたびにRenderingイベントが発生します。
レンダリングフレームレートは、1 秒あたりのシーンの描画回数です。
WPF には描画プロセス中に実行される CompositionTarget.Rendering イベントがあるようです。
JavaScript の Window.requestAnimationFrame とは異なり、描画フレーム毎に実行されるイベントですが、コードによっては 1 度だけ実行されるようにすることもできそうです。
コード例
下記コードは、次の画面再描画時に 1 度だけ処理を実行するよう要求する RequestRendering メソッドを記述してみた例です。
ちなみに CompositionTarget は静的クラスのため、WPF アプリケーション内であれば何処でも記述できます。
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
namespace Sandbox;
public partial class MainWindow : Window {
    public MainWindow() => this.InitializeComponent();
    private bool _isRenderingRequested;
    // 次の画面再描画時で処理実行を要求します。
    protected void RequestRendering() {
        if(this._isRenderingRequested) { return; }
        void OnRendering(object? sender, EventArgs e) {
            // 再描画時に実行したい適当な処理:
            Console.WriteLine("rendering.");
            CompositionTarget.Rendering -= OnRendering;
            this._isRenderingRequested = false;
        }
        this._isRenderingRequested = true;
        CompositionTarget.Rendering += OnRendering;
    }
    protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) {
        base.OnMouseLeftButtonDown(e);
        // 画面再描画までに連続で要求しても、処理は 1 度だけ実行されます。
        this.RequestRendering();
        this.RequestRendering();
        this.RequestRendering();
        Console.WriteLine("requested.");
    }
}
おわりに
こんなことをせずに XAML だけで解決できるならそれに越したことはないです(個人的な感想)。