Multiple Storyboards or Animations that share the same timeline? - wpf

I have a a bunch of WPF UserControls that internally trigger some animations upon user interactions. All animations have repeatbehavior = "true" and all animations have the same duration. Now I would like synchronize all those animations on one timeline so they are fading in and out in sync. No matter when the user triggerd the animations. For example if the animations all last 3 secs and the user triggers the 2nd animation 1.5 secs after the first, I still want the animations reach their maximum at the same time.
Maybe I can define a global time line in a global resource dictionary that all animations that are defined somewhere in the UserControls can use? Preferably XAML only.

Simply add all of your animations to a single TimelineCollection. Then add that TimelineCollection to your Storyboard.Children. Then they will all fire simultaneously.

XAML: impossible (as far as I know)
code: CompositionTarget.Rendering

Maybe my post can help you http://translate.google.it/translate?js=n&prev=_t&hl=it&ie=UTF-8&layout=2&eotf=1&sl=it&tl=en&u=http%3A%2F%2Fblogs.ugidotnet.org%2Fleonardo%2Farchive%2F2011%2F01%2F08%2Fsincronizziamo-le-animazioni-con-wpf.aspx&act=url (is in Italian and link is of Google Translate)

Related

Silverlight Storyboard starts very slow

I need help, I have an application in Silverlight. The first page has many controls such as "Buttons, Calendars & Images" and it makes my storyboard start very slowly.
When you click an event to run the storyboard that starts very slow. I imagine this is due the large number of controls I have on my site.
How can I make my storyboard not start so slow?
There seems to be an extra delay in the storyboard system firing up the first time. This is made worse of the page loading has a large number of controls.
If you make sure your animation contains some padding at the start, before anything changes, it may help reduce the visible jarring.
If you have a specific example you care to share (Xaml etc) I would be happy to try some options on it.

Starting a Storyboard From A Storyboard

Is this possible in expression blend?
What i am looking for is to start a storyboard, then at second 2 i would like to start another storyboard.
Why am I looking for this? So I can re-use storyboards and 'pieces' of larger storyboards. Seems like it would be the most OO I can get from storyboards.
Thanks!
Storyboards are not supposed to be OO, they are animation and timeline tools. If you want to create custom and controlled animations, I would advice that you research about the CompositeTarget.Rendering event and read about animations and easing. You can use IEasingFunction to select the easing your custom animations would use.
A different option would be to use the Storyboard.Completed event to find out when a storyboard is finished so that you can start another one, but if you decide to go this way you have to be very careful about memory leaks related with event hooks.

Tweak WPF application performance which hosts hundreds of similar controls

We just ported our WinForms application to WPF.
However, performance decreased dramatically.
We have a User Interface which consists of about 200 UserControl.
Each UserControl is defined by a DataGrid (= 10 columns and 3-15 rows) as well as a Panel which hosts about 10 Buttons.
They are all hosted in a ScrollViewer.
(Please don't recommend to change the UI. I don't have any influence on that. The customer wants to be able to scroll to any of those UserControls.)
Since we ported the whole application to WPF the startup time increased by 100%. Using WinForms we experienced startup times of 15sec whereas now, we are struggeling with 30s.
Do you have any recommandations or ideas how to improve the loading time of a UI which consists of identical UserControl where simply each UserControl is bound to a different ViewModel? (Maybe some fast cloning of the UserControl instances or sth similar?)
I am using static Resources whereever possible.
I avoid Grids and Auto Sizing whereever possible.
Hope someone can share some thoughts on that one.
Thanks,
TH
First find out what is responsible for the time.
Maybe it's the controls, and maybe not. Often it's data structure.
I use the random-pause method.
My final solution is a custom Virtual Panel which supports items of dynamic height.
See http://rhnatiuk.wordpress.com/2006/12/13/implementing-a-virtualized-panel-in-wpf/ on how to create virtual panels.
My UserControls support two states:
- Initial
- Loaded
When the application is in idle the virtual Panel asks the Controls to change to the "Loaded" state. This loads the expensive UserControl.
Like that everything is lazy loaded and as soon as the user stops scrolling the visible items are loaded.
Maybe that helps others that are in the same sitaution.
TH
Try only to create the controls which are visible at the time, use lazy loading.
Maybe SnapsToDevicePixels=true can also help a little bit.
Guys, I thought about the following implementation. If anyone has concerns please let me know:
I will implement my own virtualizing "StackPanel" which supports smooth scrolling.
For the moment we assume that the height of my UserControls is fixed. One page could possibly hold 5 UserControls.
I will then go ahead and cache the preceding as well as the proceeding page:
In memory I will always hold 15 UserControls.
The content of the ScrollViewer is a Canvas.
Locations of my UserControls are adjusted by setting Canvas.Top.
Let's say the current situation is the following:
User has scrolled to page 2.
That means UserControl 5-9 is visible. Now the user scrolls down.
As soon as UserControl 5 becomes invisible I take the UC of the top (in this case UserControl 0), change its ViewModel and adjust its Canvas.Top so that it now is the Control which is at the End of the ControlCollection.
If the user scrolls any further I take UC 1, change its ViewModel and adjust its Canvas.Top.
And so on.
Furthermore I will set Canvas.Height manually so that the ScrollViewer represents the ScrollBars in a correct way.
I hope my explanation is understandable :)
What do you think?
BR,
TH
I remember reading something about how each instance of a UserControl loads the resource dictionary. So if you have as many of these as you describe it can take a while to load those.
Unfortunately I can't find the link I remember, but here is one that might help:
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/c9b6aa9f-5a97-428c-8009-5cda432b820c
Another thing to try is to not use UserControls and instead use a DataTemplate to build your datagrids and buttons. Or make a custom control template for the datagrid that includes the buttons. Either one might be faster.
Hope this helps.

Dynamic animations, Commands and separation of concerns

Scenario: I have a (numeric) textbox, a button, and a label. When the button is clicked I'd like the label to "animate" to the numeric value in the textbox (like a spinning dial)
Given:
a) that animations in storyboards cannot have databindings (because they are not FrameworkElements)
b) the lack of triggers in Silverlight
What is the best, and with least coupling of the view model to the view's storyboard, way to update the target animation value and start the animation when the button is clicked?
Note: The scenario is conceptual, so don't concentrate on the specifics of 'animating' numbers or anything
If your goal is strictly to reduce the code-behind in the view I think that an attached behaviour on the Label would work for this. The attached behaviour on the label would expose the number to be animated to and when this number changes an animation (in code) would be run to animate from the old value to the new value.
One drawback is that your animation is now in code, unless you store a templated (just has fake values to start with) version of it in a resource file somewhere where you can load it as needed and replace the templated values.
This article from Josh Smith seems to be the authority on Attached Behaviours;
http://joshsmithonwpf.wordpress.com/2008/08/30/introduction-to-attached-behaviors/
I recently had to solve a similar problem in an MVVM application. My problem was that I needed to animate a container's height from zero to auto. Since Auto is a dynamic value I recognized that the animation (or storyboard) would need to be built (or manipulated) on demand. The solution that I put in place involved using view code-behind to update and fire the animation.
This isn't the most MVVM-friendly approach; however, animations in WPF can be tricky in XAML. Since this solution is really just a workaround for a XAML limitation it seems okay to tie the code directly to the view. Likewise, if the views were mocked then there would be no framework elements to animate, so it really wouldn't make sense to place this code on the VM side.
Does anybody have a better approach?

WPF Newbie question

I'm trying to learn WPF animations and am currently confused by quite a few things:
I used tools like processing, where you have a simple method which is called n times per minute, where n is the frame rate.
The way to do animations in WPF is to modify a property. If i use for example DoubleAnimation then a double is increased as the animation proceeds. But this is not exactly what I want. I want that in every cycle some properties are increased, some are modified by random and some are modified by user interaction. How can I do this in WPF?
What is also confusing me is the fact that WPF supports multiple animations at the same time. How does this work? Is there a thread for every animation or just one for all animations.
I used gdi with c# some time ago. I even could use multiple threads for drawing; As far as I remember I just had to insert all the drawing commands in some queue and then windows took care of them.. I have no idea how this is handled with WPF.
On a basic level, WPF animations are just the same as any other kind of animation: internally a timer ticks and some properties are modified which lead to a different picture when drawn to the screen.
WPF does all the leg work for you to be able to specify animations relative to wall-clock time, like "move that box at 3mm per second to the left". For more complex scenarios you might want to code up your own Animation, see the Custom Animation Overview article on the MSDN.
Regarding threading, WPF works the same as GDI: There is one Thread that handles all the interaction with the WPF model and you can only talk to WPF Controls if you're running on this thread. You can use the Dispatcher to "send" code to this thread if you are free threading. Actual drawing to DirectX is done in a separate thread, but that is of no concern to casual users of the API.
You can run several animations at the same time by putting them into a StoryBoard.
You can use the animation's BeginTime to get one animation to start after another.
You can use the key frames version (DoubleAnimationUsingKeyFrames) or the path version (DoubleAnimationUsingPath) to create complex non-linear animations.

Resources