Skip to content

WPF: What is the best way to achieve continuous rendering? #16

Open

Description

@trmcnealy

Remove the Timer from the "MainWindow" and replace it with.

private void Checkbox1_Checked(object     sender, RoutedEventArgs e) => CompositionTarget.Rendering += CompositionTarget_Rendering;
private void Checkbox1_Unchecked(object   sender, RoutedEventArgs e) => CompositionTarget.Rendering -= CompositionTarget_Rendering;
private void CompositionTarget_Rendering(object? sender, EventArgs e)
{
    SkElement1.InvalidateVisual();
}

Activity

  1. swharden commented on Jun 24, 2022

    @swharden
    Owner

    Hi @trmcnealy,

    Thanks for this suggestion! I'm not very familiar with the pros and cons of using CompositionTarget.Rendering vs a timer for drawing graphics. A quick search advises timers are superior for limiting frame rate or implementing physics simulations where models should progress at a standard rate. This may favor the use of timers since many of the other projects on https://swharden.com/csdv/ (e.g., boids) would benefit from a constant speed.

    EDIT: A more extensive search reveals some people recommend the opposite!

    This discussion is worth including on the page though, so I'll create a new page comparing/contrasting these methods and link to it from all the relevant WPF pages.

    Note that the web page being referenced is

    which references project code that lives here:

    public partial class MainWindow : Window
    {
    readonly DispatcherTimer Timer1 = new();
    public MainWindow()
    {
    InitializeComponent();
    Timer1.Interval = System.TimeSpan.FromMilliseconds(10);
    Timer1.Tick += Timer1_Tick;
    }
    private void SKElement_PaintSurface(object sender, SkiaSharp.Views.Desktop.SKPaintSurfaceEventArgs e)
    {
    ICanvas canvas = new SkiaCanvas() { Canvas = e.Surface.Canvas };
    canvas.FillColor = Colors.Navy;
    canvas.FillRectangle(0, 0, (float)SkElement1.ActualWidth, (float)SkElement1.ActualHeight);
    canvas.StrokeColor = Colors.White.WithAlpha(.5f);
    canvas.StrokeSize = 2;
    for (int i = 0; i < 100; i++)
    {
    float x = Random.Shared.Next((int)SkElement1.ActualWidth);
    float y = Random.Shared.Next((int)SkElement1.ActualHeight);
    float r = Random.Shared.Next(5, 50);
    canvas.DrawCircle(x, y, r);
    }
    }
    private void SKElement_SizeChanged(object sender, SizeChangedEventArgs e) => SkElement1.InvalidateVisual();
    private void Button_Click(object sender, RoutedEventArgs e) => SkElement1.InvalidateVisual();
    private void Timer1_Tick(object? sender, System.EventArgs e) => SkElement1.InvalidateVisual();
    private void Checkbox1_Checked(object sender, RoutedEventArgs e) => Timer1.Start();
    private void Checkbox1_Unchecked(object sender, RoutedEventArgs e) => Timer1.Stop();
    }

    It sounds like CompositionTarget.Rendering is an event that fires at the rate of vsync (usually 60 Hz) and this topic is discussed on several pages:

  2. changed the title [-][Suggestion] (projects\maui-graphics\QuickstartWpf)[/-] [+]WPF: What is the best way to achieve continuous rendering?[/+] on Jun 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions