Wpf Animation Best Practices [closed] - wpf

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I am looking for any best practices or guidelines regarding animation in WPF. Especially information regarding performance considerations.

After I have gained a bit more experience in this field since I have asked the question, I will answer this myself. My experience comes from working on the WPF mind mapping application NovaMind - We have done lots of animations lately for our Presenter feature in NovaMind Platinum :-)
The MSDN section on Optimizing WPF Application Performance has some useful information about general considerations when writing WPF apps:
http://msdn.microsoft.com/en-us/library/aa970683.aspx
Here are some bits which I have found especially useful and are related to animation:
The CompositionTarget.Rendering event causes WPF to continuously animate. If you use this event, detach it at every opportunity.
When you use a Brush to set the Fill or Stroke of an element, it is better to set the Brush.Opacity value rather than the setting the element's Opacity property. Modifying an element's Opacity property can cause WPF to create a temporary surface.
You may be able to update a Transform rather than replacing it as the value of a RenderTransform property. This is particularly true in scenarios that involve animation. By updating an existing Transform, you avoid initiating an unnecessary layout calculation.
Here is what I have learned through trial and error:
Say, you have a couple of elements with a Effect such as the BlurEffect applied. It is way faster to apply the effect to the container of these elements rather than the elements themselves. Even though the effect is hardware accelerated, WPF doesn't seem to be good at handling a number of small items with effects. - If you don't want the same blur radius and cannot group them in a container with the effect applied, it is actually faster to render the element to a bitmap (in software) and then animate the bitmap around (if that is possible). Having effects (or opacity for that matter) on objects quickly kills performance when animating.
Setting the opacity on the brush rather than the element (as mentioned further above) makes a huge performance difference when animating objects.
Keep the number of visuals down. Animating a large number of particles is difficult, even with the above tips. In this case you may need to revert to WriteableBitmap instead.
I have also heard that it is faster to render many little objects by overriding OnRender in the container and then rendering them using the drawingContext rather than adding them to the visual tree directly. In practice this didn't make any difference in my scenario (when rendering around 300 ellipse geometries) but it might be helpful in some scenarios. The theory sounds solid.
Finally, I have found the animation classes built into WPF way too cumbersome and had much more fun and success using the underdog of animation libraries: Artefact Animator. Seriously, give it a try. (it is also available for Silverlight) It is what animating (in code) should have been like.
All is not rainbows and unicorns though. I still find it impossible to create truly fluid animations when running full screen in higher resolutions. More on that in my question How to know why an animation stutters? - I would appreciate any input on that.
cheers, good luck and if you have something cool to show, let me know :)

Related

What's the use of WPF's DataBinding? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I know the whole point behind it, but at the end of the day, the only thing provided is a clean code, am I right?
The problem:
To perform a data bind, you'll have to do some stuff in code behind (set a dependency property), which sometimes may be clear, and sometimes not. Then you'll have to find out how the hell to access the values from your dependency property (the object you're trying to use). Then, ok, you spent some time deciding that you'll access it through ElementName or Ancestor or whatever (because you'll have to find out by yourself how this works, Microsoft's documentation on that is pretty lame, it's not straight forward).
Then, ok, you spent some time and now your data binding is working, except that is not. Because the class of the object you're binding to must implement INotifyPropertyChanged. Just that. Or not, because you'll have to assure that an event (OnPropertyChanged) must be triggered in order to update the values on your interface ... by sending as an argument a string containing THE NAME OF THE EFFING PROPERTY. That's as lame as JSF's way to access values (obliging the developer to have getters and setters exactly the way they want). An also, if you're building your software in layers, forget, you'll have to implement INotifyPropertyChange every-effing-where.
I'm writing this because I want to know if:
I'm doing everything wrong and that's why I don't get the point.
Is there a better solution to deal with this kind of stuff?
Am I the only one who thinks that it doesn't make any sense?
Before anyone asks: Yes, I understand that the event makes "some" sense, because there must be a way to know that the object changed. But I don't see much difference of using that or just calling an Update method every time I do anything in the interface. I hope you guys don't think I'm stupid for posting this ... I'm a pretty new programmer (3 years since my graduation began and 2 years working experience), but the lack of a better way to do that kind of stuff doesn't look like, for instance, Microsoft's ASP.NET MVC, which just works magically. I'm not asking for everything to be easy, just asking for a better documentation, and, I don't know, an easier (by easier I mean more straight-forward) way to do something that you're supposed to do when using the framework, something that is considered elegant.
I like turtles. I also love data binding. I recommend reading up on the MVVM pattern... it uses data binding to make it easy for you to run unit tests and keep your code organized/clean. Be sure to look at how the "DataContext" property is used in MVVM.
P.S. I don't think that using the name of the effing property in OnNotifyProperty is lame at all. What else would you use without adding dependencies or unneeded complexity?
P.P.S. Clean code is a very big effing deal.
That it is hard to learn does not change that it is a powerful technique, this covers about most of your rant.
You can resolve the property name from a lambda expression if you have an aversion to strings. The code for an extension method that does that is floating around somewhere on SO.
If you don't want to implement it everywhere implement it in one base-class.
If you want magic use an MVVM framework that does that. Caliburn for example hooks up controls and methods/properties without writing any binding code.
Bindings decouple components.

Rendering Thread still slow after Virtualization

At a high level my application is applying about 5 different DataTemplates to a set of ListBoxItems based on their type. These items are laid out on a canvas at specific x, y points. I implemented virtualization on my ListBox and it did not seem to improve the time it takes to complete the rendering thread's processes. It still takes about 8-12 seconds for the UI to be completely loaded and usable by the user. I thought virtualization would help fix this problem but after looking around it looks like it only helps process scrolling large amounts of data. Am I correct in this assumption and does anyone else have any other tips for improving the rendering thread. This is the only problem I am having and then my project is complete. Thanks StackOverflow!
Virtualisation means that only the items you have visible are created, then dynamically destroyed/new items created as you scroll. The alternative is all UI controls are created for all items at once.
It sounds like you have bigger problems with the rest of the app. Do you perform all loading operations on a background thread? Is the UI control tree very complex indeed? Are you displaying 100s or 1,000s of items?
We also had a lot of trouble with performance in WPF. Best way is of course to profile your application. We use ANTS Performance profiler for that, but any .NET profiler will do. We got a huge performance hit, because of the lookup of our XAML Resources. Thats the advice i can give you:
Try to minimize all resources in XAML. But not only that, also try to minimize the amount of XAML files you have. One thing you can try is to defere the loading of complex parts of your DataTemplate. Similiar to what happens when you load a JPEG in a browser, first you will see a pixelated image which will be finer after it finished loading the JPEG. To accomplish that, use a simpler DataTemplate at first and then if this is visible only load the complex template on demand or after a while.
But without more information of your specific problem, we can only guess. This is an old question of mine about a similiar subject, maybe this will help aswell.
Yes, ListBox virtualization is for scrolling. When you have a large number of items in a ListBox, enabling virtualization will make only the visible items (+ a few extra items for scrolling) render, and scrolling the ListBox replaces the data in the rendered items instead of rendering new items.
If you were to post some code, perhaps we could assist you with some performance tweaks

Is excessive nesting of WPF layout panels (e.g. Grid) computationally expensive?

folks
I have heard from a coworker that I - as a designer using Microsoft Expression Blend - should avoid using excessive nesting of panel elements, because they are computationally expensive.
For example, I tend to create the mainwindow with header and custom statusbar with grid, and then take the top panel and put a grid inside it, and if I have a message inside a rectangle on the already gridded top panel I create yet another grid, etc.
As a very layout-oriented disigner (who wants to use every screen most efficiently whatever the screen dimensions are) I know this is the best way to do it considering absolute control and flexibility, which prevent the window to resize in "unpredictable" ways ;oP
BUT...
...this friend of mine said that, if you have, say, five grids nested inside one another, if you pass the mouse over them, you generate five mouse events, which is costly.
Also, if you have too many calculations due to the too many containers asking for children sizes before the actual rendering, it can also be costly.
I had some previous experience with PyGtk, and I must say I used A LOT o layout panels for all my scripts, and even the resizing of windows never seemed to me to be specially costly, except when I had some complex canvas drawing needed to be recalculated.
Does anyone have any experience or know anything about it?
Thanks a lot for reading
There's no straight-forward answer to this, but obviously the more elements you have participating in layout, the longer the measure and arrange phases are going to take for the window. Depending on which features of which Panel types you use it could be more or less costly, but for sure the more you use the more overhead there will be during the layout calculations. You can learn more about how the layout system works by reading that entire MSDN article.
In the end this is something that, unless you've gone crazy, will not often be an issue. To find out if it is causing problems for your app I suggest using the WPF Performance Suite to do some performance testing.
Wouldn't worry about it that much, i for one did not have problems with it so far. Apply some common sense, what panels are needed in which case? Do you really need yet another panel to achieve your goal or not?
The MSDN article on this issue might be of interest since it explains a few things which are not straightforward: Optimizing Performance: Layout and Design

Ways to improve WPF UI rendering speed

In case a screen of a WPF application contains lots of primitive controls, its rendering becomes sluggish. What are the recommended ways to improve the responsiveness of a WPF application in such a case, apart from adding fewer controls and using more powerful videocard?
Is there a way to somehow use offscreen buffering or something like that?
Our team was faced with problems of rendering performance. In our case we have about 400 transport units and we should render chart of every unit with a lot of details (text labels, special marks, different geometries etc.).
In first our implementations we splitted each chart into primitives and composed whole unit's chart via Binding. It was very sad expirience. UI reaction was extremely slow.
So we decided to create one UI element per each unit, and render chart with DrawingContext. Although this was much better in performance aspect, we spent about one month improving rendering.
Some advices:
Cache everything. Brushes, Colors, Geometries, Formatted Texts, Glyphs. (For example we have two classes: RenderTools and TextCache. Rendering process of each unit addresses to shared instance of both classes. So if two charts have the same text, its preparation is executed just once.)
Freeze Freezable, if you are planning to use it for a long time. Especially geometries. Complex unfreezed geometries execute HitTest extremely slow.
Choose the fastest ways of rendering of each primitive. For example, there is about 6 ways of text rendering, but the fastest is DrawingContext.DrawGlyphs.
Use profiler to discover hot spots. For example, in our project we had geometries cache and rendered appropriate of them on demand. It seemed to be, that no improvements are possible. But one day we thought what if we will render geometries one time and cache ready visuals? In our case such approach happened acceptable. Our unit's chart has just several states. When data of chart is changed, we rebuild DrawingVisual for each state and put them into cache.
Of course, this way needs some investments, it's dull and boring work, but result is awesome.
By the way: when we turned on WPF caching option (you could find link in answers), our app hung up.
I've had the same perf issue with a heavily customized datagrid since one year, and My conclusion is:
there is basically nothing you can do
on your side (without affecting your
app, i.e.: having fewer controls or
using only default styles)
The link mentioned by Jens is great but useless in your case.
The "Optimizing WPF Application Performance" link provided by NVM is almost equally useless in my experience: it just appeals to common sense and I am confident you won't learn anything extraordinary either reading. Except one thing maybe: I must say this link taught me to put as much as I can in my app's resources. Because WPF does not reinstanciate anything you put in resource, it simply reuses the same resource over and over. So put as much as you can in there (styles, brushes, templates, fonts...)
all in all, there is simply no way to make things go faster in WPF just by checking an option or turning off an other. You can just pray MS rework their rendering layer in the near future to optimize it and in the meantime, try to reduce your need for effects, customized controls and so on...
Have a look at the new (.NET 4.0) caching option. (See here.)
I have met a similar problem and want to share my thoughts and founds. The original problem is caused by a virtualized list box that displays about 25 complex controls (a grid with a text block and a few buttons inside displaying some paths )
To research the issue I used the VisualStudio Application Timeline that allows to how much time it takes to render each control and PerfView to find out what actually WPF is doing to render each control.
By default it took about 12ms to render each item. It is rather long if you need to update the list dynamically.
It is difficult to use PerfView to analyse what heppens inside since WPF renders item in the parent-child hierarchy, but I got the common understanding about internall processes.
WPF does following to render each item in the list:
Parse template using XAML reader. As far as I can see the XAML parsing is the biggest issue.
Apply styles
Apply bindings
It does not take a lot of time to apply styles and bindings.
I did following to improve performance:
Each button has its own template and it takes a lot of time to render it. I replaced Buttons with Borders. It takes about 4-5ms to render each item after that.
Move all element settings to styles. About 3ms.
Create a custom item control with a single grid in the template. I create all child elements in code and apply styles using TryFindResources method. About 2ms in the result.
After all these changes, performance looks fine but still most time is spent on loding the ListControl.Item template and the custom control template.
4. The last step: replace a ListControl with Canvas and Scrollbar controls. Now all items are created at runtime and position is calculated manually using the MeasureOverride and ArrangeOverride methods. Now it takes <1ms to render each item from which 0.5ms is spent on TextBlock rendering.
I still use styles and bindings since they do not affect performance a lot when data is changed. You can imagine that this is not a WPF solution. But I fave a few similar lists in the application and it is possible not to use templates at all.

Performance of DrawingVisual vs Canvas.OnRender for lots of constantly changing shapes

I'm working on a game-like app which has up to a thousand shapes (ellipses and lines) that constantly change at 60fps. Having read an excellent article on rendering many moving shapes, I implemented this using a custom Canvas descendant that overrides OnRender to do the drawing via a DrawingContext. The performance is quite reasonable, although the CPU usage stays high.
However, the article suggests that the most efficient approach for constantly moving shapes is to use lots of DrawingVisual instances instead of OnRender. Unfortunately though it doesn't explain why that should be faster for this scenario.
Changing the implementation in this way is not a small effort, so I'd like to understand the reasons and whether they are applicable to me before deciding to make the switch. Why could the DrawingVisual approach result in lower CPU usage than the OnRender approach in this scenario?
From Pro WPF in C# 2008:
The problem posed by these
applications isn't the complexity of
the art, but the sheer number of
individual graphic elements. Even if
you replace your Path elements with
lighter weight Geometry objects, the
overhead will still hamper the
application's performance. The WPF
solution for this sort of situation is
to use the lower-level visual layer
model. The basic idea is that you
define each graphical element as a
Visual object, which is an extremely
lightweight ingredient that has less
overhead than a Geometry object or a
Path object.
What it boils down to is that every single one of those ellipses and lines you're creating is a separate FrameworkElement; that means it supports not only hit testing, but also layout, input, focus, events, styles, data-binding, resources, and animation. That's a pretty heavy-weight object for what you're trying to do! The Visual object skips all of that and inherits directly from DependencyObject. It still provides support for hit-testing, coordinate transformation, and bounding-box calculations, but none of the other stuff that the shapes support. It's far more lightweight and would probably improve your performance immensely.
EDIT:
Ok, I misread your question the first time around.
In the case that you are using OnRender, it really depends how you are creating the visuals and displaying them. If you are using a DrawingContext and adding all of the visuals to a single element, this is no different than using the DrawingVisual approach. If you were creating a separate element for each Visual created, then this would be a problem. It seems to me that you are doing things the right way.
Everyone in the answers got it wrong. The question is whether rendering shapes directly in the drawing context is faster than creating DrawingVisual. The answer is obviously 'yes'. Functions such as DrawLine, DrawEllipse, DrawRectangle etc. do not create any UI Element. DrawingVisual is much slower because it does create a UI Element, although a lightweight one. The confusion in the answers is because people simply copy/paste the DrawingVisual performs better than distinct UIElement shapes statement from MSDN.
I thought Petzold explains in this paragraph;
The ScatterPlotVisual class works by
creating a DrawingVisual object for
each DataPoint. When the properties of
a DataPoint object change, the class
only needs to alter the DrawingVisual
associated with that DataPoint.
Which builds on an earlier explanation;
Whenever the ItemsSource property
changes, or the collection changes, or
a property of the DataPoint objects in
the collection changes,
ScatterPlotRender calls
InvalidateVisual. This generates a
call to OnRender, which draws the
entire scatter plot.
Is this what your asking about?
By the way, this is a fairly recent high-performance WPF tutorial, many tens of thousands of points in that plot, it is 3D rendered and animated also (even uses mouse input to drive some of the transforms).
In my tests however (panning animations), I notice no difference in speed. I would say that using a host element for many drawing visuals is a bit faster. This approach where you build your visual tree with many visuals gives you more control. Moreover, when you want to do a complex hit testing, the filtering process is faster because you can skip entire "branches" of visuals

Resources