equivalent CreateGraphics in wpf

ohmusama picture ohmusama · May 11, 2011 · Viewed 9.8k times · Source

So, I've used winForms .CreateGraphics to draw a variety of different things, from lines to boxes to images. It was very snappy and responsive.

I am trying to learn WPF in C#

I found that WPF allows me to "add" rectangle objects to a canvas which will display them properly. HOWEVER, I am drawing hundreds of thousands of rectangles at times, and the draw rate can become exceedingly slow, and the UI becomes less snappy when I move even 1 of the rectangles.

Painting directly onto an element in winForms was not very fast, but it was consistent regardless of how much I painted.

Is there a similar solution to doing this in WPF?

I tried adding a linq to System.Drawing, which gave me a Graphics object, but none of the wpf elements i tried have the .CreateGraphics() method.

Answer

Scott picture Scott · May 11, 2011

WPF uses a different model for graphics manipulation than WinForms.

With WinForms, you are able to directly edit the pixels on the screen. The concept of your rectangle is lost after the pixels are drawn. Drawing pixels is a very fast operation.

With WPF, you are not controlling the pixels on the screen. DirectDraw is. DirectDraw is a vector-based compositing engine. You do not draw pixels. You define vector shapes (or visuals). The concept of a shape, or a rectangle, is RETAINED, even after the image is rendered to the screen. When you add a new rectangle which overlaps the others, ALL OTHER RECTANGLES NEED TO BE REDRAWN. This is likely where your performance is slowing down. This does not happen when using WinForms.

You can improve the performance of WPF a bit by overriding OnRender. You can cut out the overhead of the Rectangle object and directly provide the visuals. However, you are still not drawing pixels to the screen. You are defining shapes that DirectDraw uses to render the image. In this regard, the OnRender name may be a bit misleading.

I am sure you can find plenty of tricks to improve performance of your application in WPF. There are ways to still paint pixels - but that is kinda defeating the point of WPF.

What are you doing that requires thousands of rectangles?