WPF Speed Load Time of Expanding a Specific TreeView Element - wpf

I have been trying to find out specific ways of improving the load times of a treeview element that contains 1500 flat nodes. At the moment it takes over 15 seconds to expand a single node.
I have tried the suggestions regarding virtualisation but its my understanding that virtualisation basically avoids loading and rendering elements that cannot be seen. Correct?
If so, what happens when you expand an element where there are 1500 items within that single expansion, does it not then need to load those 1500 items?
It seems obviously, if I split up my TreeView so that each time 10 elements were added, it added another folder. So you couldn't view the whole treeview at once. This is NOT really an option for me.
So is there a way of possibly background loading the tree element add, so that I can display the treeview even while its loading items?
This is the only solution I can think of but I have yet to come across a way of being able to update the UI and not be blocking at the same time.
Thanks

Virtualization is the logical way to go.
Math is your friend here:
Let's, for the sake of argument, assume that 1 node takes up an insanely small 5 vertical pixels. A screen with a height of 7500 pixels would be able to show all 1500 nodes.
Cutting the number in half to 750 nodes would still require a height of 3750 pixels.
If we take a more reasonable height for one node, I think the default is 19, a decent 4K monitor would be able to show around 200 of them.
I'm currently running on a 1920x1200 monitor, with scaling at 100% (strangely called "smaller"). Explorer, with the ribbon collapsed, shows me 43 items. 2000 pixels would give me around 73 items in view. And the items in Explorer are pretty much as small as I would want them to be without going blind.
Bottom line: You're unlikely to run in to the problems with virtualization.

For anybody coming across this question. Ensure you haven't wrapped (or even have a scrollviewer) in the same grid as your treeview.
It completely disables virtualisation without warning.

Related

Silverlight Optimization

I have an application written in Silverlight 5, which requires optimization.
Application contains a TreeView, each element of the tree contains about 25 editbox controls with background image. The tree has an average of about 50 elements, which makes ~ 1250 edit controls. The problem is that it scrolls the tree or select editboxs very very slowly, even if only 5-6 elements are visible.
I think virtualization in this case will not help because the problem is in the drawing of visible elements.
Does anyone have any idea how to optimize?
Can't post image becouse of my low score but one TreeView Item looks like:
Floor 4 (0xAA03) |EB|EB|EB|EB|EB|EB|EB|EB|EB|EB|EB|EB|EB|EB|EB|EB|EB|EB|EB|EB|EB|EB (25)
where EB is EditBox in form of rectangle with image background and text for room number. Editboxs are created dynamic.
Thank you in advance.
Ok, it's difficult to give a qualified answer. But let's have a try. I think your statement virtualization won't help is not fully true, but it doesn't seem to be the main problem.
An educated guess is, that you're using DropShadows or OpacityMasks which are a real performance killer. If it's like that please remove them and tell me the result. Otherwise I'm running out of ideas, sorry.

Silverlight (wp7)

Being new to silverlight I'm struggling to 'get going' with the following.
Basically I wish to create some form of grid like control (custom or user?).
The idea is similar to that of a planner. Along the top are times (set intervals). Downwards are subjects. Then over the grid like background rectangles (or something) indicate when the subject is planned for.
The actual design of the above is not the issue. i.e. a grid with ractangles overlaid. But my issue is I wish this grid to be scrolled up and down (with bounds fixing the top and bottom when the subject lines start and end). And also the grid to be scrolled left and right (with bounds fixing how far left and right it can scroll, current time & 3 days into future).
Based on the above needs, I don't wish to create a control which is very large, and just dragged into view (unless this is the only way?) but instead show the grid at a current time and when dragged dynamically load the next few hours worth of content, possibly with a few hours buffer.
The appearance I am seeking is it looking like it is one massive control, but truely its not, its dynamic.
Does this make sense? Am I worrying about nothing? Should I create a massive grid well into the future and then just handle the load of data dynamically over the top? Its just my concern if I want a grid 3 month into the future this would be massive and a waste of memory.
I'm struggling to find examples on the net, but feel this maybe to do with me not knowing what to search for. This isn't about getting a detailed answer and someone doing it for me, but instead about guidance pointing me in the right direction.
Many thanks
About the up-down scroll: you can simply put a grid containing your data in a ScrollViewer control - this will handle all the scrolling for you. Another solution would be using a listbox control - this is better if you use MVVM. You can bind it to a data source and set as data template a custom control.
For the left-right scroll. I'm thinking you could use gestures for this. Like - catch left-to-right and right-to-left flicks and change the data in your grid / listbox according to the gesture's direction. You could also place two buttons at the top of the grid to handle scrolling from one day to the other (just like in the calendar controls: gestures + buttons).

How to know why an animation stutters?

I have a few fairly simple animations (moving text around, moving ellipses etc.) and running in full screen (1920x1080 minus the task bar) the WPF Performance Suite reports a good framerate around 50 FPS throughout the animation. Dirty Rect Addition is somewhere around 300 rect/s, the SW frames are between 0 and 4 and the HW frames are between 3 and 5. Video memory usage is around 80 MB.
Problem is that the animations stutters every other half second. It is definitely not fluid :-(
My machine is a new Dell laptop XPS 15 with the GeForce GT 435 with 2GB memory. - The drivers are up to date. (The same behavior occurs on my netbook (in full screen) as well so I don't think it is hardware related.)
If I make the window smaller the stutter goes away.
The stutter occurs with the simplest of animations - even with just a couple of elements but adding more elements certainly makes it more noticeable.
How can I find out what causes this stutter?
When I think of it, I have not actually seen any WPF animations which run smoothly in full screen. Is this even possible?
Have you tried to set a lower "max frame rate" to the animation?
<Storyboard Timeline.DesiredFrameRate="10">
<!-- ....blah blah blah -->
</Storyboard>
If your animation is causing massive recalculation of child or parent elements, changing the DesiredFrameRate will have a cascading effect on the number of calculations made by the system.
Also, check out the "Remarks" section of this link. It explains why/when you should use it.
If setting a lower frame rate fixes your stuttering, then you need to consider simplifying your XAML to limit the amount of recalculation needed at every frame of your animation (limiting the number of child or parent objects resized - or affected in any way - by every frames/changes made by the animation.
You might want to also check out the "WPF Performance Suite". It is an awesome set of tools to determine what exactly is going on in your WPF app, seeing which parts of your window are being repainted and when, and the CPU usage of each of your XAML elements!
Hope this helps!
Patrick,
I have no answers. All I can do is provide some solidarity. I'm trying to animate an ItemsControl. The concept is pretty simple, really. I've got a ListView and in the ListView I have a GridView. I want the items in the GridView to to smoothly go from one row to another row as the underlying list is sorted so that, for example, a sorted list will stay sorted as the values in the list change.
I've noticed this: animation on moderately complex controls is a CPU hog. The stuttering I'm pretty sure is simply related to the CPU being maxed out (I noticed you didn't provide the CPU graph on your dump above). Keep the CPU around 50% and the animation appears smooth, above 75% and you get these stutters.
Still working on the problem, but I think it goes deeper than my code.
Don
I had a similar issue where it was stuttering, nothing really major it just looked like little stutters here and there while I ran the program. On a hunch, I shut down Google Chrome while it was running and that fixed it,the scrolling became completely smooth...
So my advice would be if you have any internet browsers open check to see if closing them out fixes the problem.

Evenly distibuted scatterViewItems that dont overlap

I have an app that creates a variable number of ScatterviewItems based on which tagged object is placed on the surface table.
The ScatterViewItems are added programatically to the ScatterView based on info looked up in a DB
The Scatterview does a good job of displaying this info
However, I would like them to be
evenly distributed across the table and
not have any items overlapping
Any ideas how to do that?
Sounds like you need collision detection.
There's two parts to this problem: detection and resolution. Detection is seeing if any item's bounding intersects with any other item's bounding. If the items are retangular or circular this is pretty straightforeward. It can get complex if you're dealing with other geometries.
Resoltion is what to do once you've detected a collision. Google will help you find the myriad algorithms for this. Here's a couple links to stackoverflow discussions: WPF: Collision Detection with Rotated Squares, Applying Coefficient of Restitution in a collision resolution method, Best way to detect collision between sprites?.
You can implement collision to work so that items bound off of each other as they scatter. Depending on the number of items, this might cause so much collision that the items don't scatter well. If this happens, just run the collision detection one items have stopped moving.
UniformGrid ?
You can also create your own panel by iheriting from Panel.
You will find some uber-valuable info in the Dr. WPF ItemsControl How-To series : http://drwpf.com/blog/itemscontrol-a-to-z/
That's a must-read, period.
ScatterViewItem has properties Center and Orientation which you can use to programmatically position items. If you know the size of each item you should be able to use these properties to position them in whichever way is ideal for your situation. By hooking into the Loaded event of each and checking ActualWidth/ActualHeight, you can get the dimensions. If you can use a fixed initial size for all of your SVIs, that's even easier.
You could lay them out by calculating a simple grid (plus some randomness to make it look more natural), or you may be looking for what's called a "force directed layout", which gives each object a repellent force relative to its size. After a while the elements will naturally be evenly spaced from one another, though they may still overlap if they run out of room. I haven't seen a WPF example of this, but see flare.prefused.org/demo (layout > force) for what I mean in Flash.

WPF Virtualizing a Canvas

We have a series of rectangles produced inside a Canvas and they are nested in this order ScrollView>Canvas>VirtualizingStackPanel>Rectangles in the XAML.
There seems to be little information on Microsoft about under what senarios Virtualization is supported, and in cases where it isn't no error is thrown, it merely treats it like a standard StackPanel.
Given that our view has roughly 60 rectangles on the screen at any one time out of a total of about 800 on the whole canvas the loading times of about 5 minutes are unacceptably slow.
We have already tryed removing the ScrollView to no effect ( other than removing the scroll bars the performance didn't improve), and removing some of the other nesting elements, the net effect seems to be either nothing is displayed, or its displayed but still slow.
The best solution I've found so far a sample piece of free ware code VirtualizedCanvas but its very very limited and doesn't support anything nested inside it, infact the only input it takes is a collection of UI Elements.
This solution basically ignores the databinding and requires a you to pass a completed Canvas back to it, this renders all our existing code and converters pretty useless, and would be major rework to implement.
Is there a way to simply clip the Virtualize the Canvas to only draw our 60 on screen items?

Resources