CreateGraphics equivalent in wpf

So, I used winForms.CreateGraphics to draw various things, from lines to boxes to images. It was very fast and responsive.

I am trying to learn WPF in C #

I found that WPF allows me to “add” rectangular objects to the canvas, which will display them correctly. HOWEVER, I draw hundreds of thousands of rectangles at times, and the drawing speed can become extremely slow, and the user interface becomes less fast when I move even one of the rectangles.

Painting directly on an element in winForms was not very fast, but it was consistent, no matter how much I drew.

Is there a similar solution for this in WPF?

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

+6
source share
4 answers

You will need to create a control that overrides OnRender and makes your drawing there. It’s not possible for you to draw another control, but the control can draw itself.

Also, keep in mind that WPF uses saved graphics , so if you change anything, you need to invalidate the visual as needed.

EDIT:

Sort of:

 public class MyControl : Control { public MyControl() { this.Rects = new ObservableCollection<Rect>(); // TODO: attach to CollectionChanged to know when to invalidate visual } public ObservableCollection<Rect> Rects { get; private set; } protected override void OnRender(DrawingContext dc) { SolidColorBrush mySolidColorBrush = new SolidColorBrush(); mySolidColorBrush.Color = Colors.LimeGreen; Pen myPen = new Pen(Brushes.Blue, 10); foreach (Rect rect in this.Rects) dc.DrawRectangle(mySolidColorBrush, myPen, rect); } } 
+2
source

WPF uses a different model for graphical manipulations than WinForms.

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

With WPF, you do not control the pixels on the screen. DirectDraw is this. DirectDraw is a vector layout engine. You do not draw pixels. You define vector shapes (or visual effects). The concept of a RETAINED shape or rectangle, even after the image is displayed on the screen. When you add a new rectangle that overlaps the others, ALL OTHER RECTANGLES ARE NECESSARY TO BE AN IMAGE. This probably slows down. This does not happen when using WinForms.

You can improve WPF performance a bit by overriding OnRender. You can cut the overhead of a Rectangle object and directly provide visual effects. However, you still do not draw pixels on the screen. You define the forms that DirectDraw uses to render the image. In this regard, the name OnRender may be a little misleading.

I am sure that you can find many tricks to improve the performance of your application in WPF. There are still ways to draw pixels - but this is a kind of victory over the WPF point.

What are thousands of rectangles for?

+4
source

As said, WPF uses the saved graphical methodology, so you actually create 100,000 Rectangle objects in memory and then draw them all. The slowdown is probably due to garbage collection and problems with shared memory.

Besides overriding the OnRender method, here are a few things you might want to look at.

  • Drawing rectangles for an image in the background stream using the GDI methods that you are familiar with and then writing the result to WPF WriteableBitmap

  • Use D3DImage and use hardware acceleration. To do this, you need to know the DirectX (or Direct2D) libraries. If you are interested in this approach, I would suggest looking at SlimDx.

+2
source

The problem is that WPF cannot display 1000 objects of graphic objects, but that you create and add elements too far from the hierarchy of WPF objects. He still uses the GPU for all the graphics work.

You should add objects as close as possible to the "Visual" class, as soon as you start adding objects based on the last "UIElement", you ask WPF to track user clicks, hangs, etc. for each object, not just draw it.

+2
source

Source: https://habr.com/ru/post/887862/


All Articles