N
N
Nikolai Bogdanov2019-04-02 12:28:46
WPF
Nikolai Bogdanov, 2019-04-02 12:28:46

How to add many (more than a thousand) objects to a WrapPanel (WPF)?

I am writing a program that analyzes a file and, in accordance with its content, draws a map, as in the figure:
5ca3290bd30a2588489155.png
Can you tell me, colleagues, how to do this the fastest, which objects to add and how?
I tried two options: with System.Windows.Media.DrawingImage and System.Windows.Shapes.Rectangle. But they are equally bad, because you need to create a monstrous amount of them (although in fact there are only a few types of squares) and then add this monstrous amount to the WrapPanel. The slowest method in this case is Map.Children.Add(image), which is executed in a loop (the objects themselves are created relatively quickly in large quantities).
Maybe there is a way out of this situation?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
C
cyber_roach, 2019-04-10
@cyber_roach

First: don't use wrappanel.
Canvas is better for this purpose, but it's likely to be more productive to write your own layout panel. here the main rule is to redraw the positions of elements as rarely as possible.
https://docs.microsoft.com/en-us/dotnet/framework/...
Next, the object itself, again, you probably don't need all the features of the Shapes class, and judging by the screen, all elements are one-sized. it will be more efficient to create a new element based on the base frameworkelement with a given set of properties (color from enum and size)
If the elements are not always displayed completely on the screen but with a scroll, then virtualization is immediately here (draw only what is visible).
Further addition. elements to the panel.
I advise you to simply hack the system, adding not one at a time, but just a hundred or two, or if the number of elements is known in advance, immediately form them all (bind the collection) at the loading stage. Just make them invisible in the background color, then simply change the state of the desired element to the desired color by index during the process (if any). Working with collections is more productive than any For c Children.Add.
Most likely, the option I described will significantly speed up the process, but it will devour a lot of RAM and processor time, there is only one solution - to rasterize!
You can fill all the elements or part of it with just a texture (for example, divide the map area into squares or stripes)
The algorithm here is simple - draw the elements (better part) - "take a picture" - the resulting Image - paste it on the desired area
In general, pure hardcore is precisely to form squares not with elements but a group of images.
This will reduce the cost of rendering by several orders of magnitude, but not everyone can write such code, especially if the squares are not static (change color state) at runtime or interactive is required (a tooltip or clicking on a square, for example), but everything is possible, we even rasterize animations were done, the most difficult thing is to develop the correct algorithm.
The simplest one that comes to mind is to draw the entire area as a texture, draw 10-100 new elements on top of the Canvas in the right place, and then rasterize the entire area with new elements into a common texture by deleting these elements and drawing a new batch. As a result, in general, you get just an image that weighs nothing and does not eat the processor.
I would also study the source codes for Telerik, for example, they have many similar controls with the output of millions of objects. (for example, points on graphs).

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question