views:

904

answers:

4

I have an animation in WPF that is jerky, my WPF form is layed out as follows:

a 1280x800 Window contains a 2400x7** grid, seperated into 3 columns.

  • Column 1 is * width
  • Column 2 is 148 width
  • Column 3 is * width

This allows me to, using an animation, chage the grid's margin to ~-1000 on the left side to bring the left column off screen, move the middle column to the far right, and then pan the right most column on screen (think of it like a 2 page panning design.)

This is all great, but my screen components animate at different speeds when i slide them left/right, is there a way to essentially double buffer my entire drawing space and pan it all together? or is this against the spirit of WPF.

XAML is available here.

A: 

I have used the code from here. He uses gridlength instead of margin. Worked well.

Klerk
+3  A: 

I've checked your code and can verify the funny transition. However, the animation lags only when going to the right.

When I replaced your WebBrowser with a colored Border, the lag was gone.

So the conclusion would be that the issue here is the slow rendering of an outside hosted visual. The WebBrowser is an interop ui element, inheriting from HwndHost.

So it's definetly nothing to do with XAML, I think you're stuck with the performance as it is.

kek444
okay, i'm fine with hearing this! I didn't really expect a web control ^_^
Firoso
I changed it to an elipse and still saw the Lag :-/
Firoso
Well, it IS a rather large element to be drawing point-by-point, right? try a border with a radius instead. Try to replace either side with any option. As I said, it's not the xaml, wpf rendering can get a bit slow.
kek444
hence my asking if there is some way to "double buffer" the rendering process...
Firoso
Well, wpf is DirectX powered, it should be double buffered automatically.
kek444
+1  A: 

Simple buffering wouldn't help with this problem, because it seems that lags are not in graphics, but rather in logic behind updating properties of different elements during animation. Following should help though:

  • On button click, render whole grid to RenderTargetBitmap.
  • Paint resulting image (RenderTargetBitmap inherits from BitmapSource) on some rectangle over the grid.
  • Hide the actual grid.
  • Animate bitmap, move hidden grid to the new position
  • Show grid
  • Hide bitmap

As for spirit of WPF, it can be called necessary evil. You can notice how text rendering in WPF itself changes during scrolling, for example - using RenderTargetBitmap is no worse.

Disclaimer: I didn't try to reproduce problem nor read the XAML, but the method above naturally avoids all problems with vector graphics or hosted elements.

ima
This is a very good answer, although not exactly what I wanted to hear, it still answers my question, plus stateful locking of display elements by rendering to a cached bitmap isn't exactly out of the question, as windows it's self does this quite a bit in win 7 for thumbnails.
Firoso
+1  A: 

Another approach to investigate:

Instead of storyboard in XAML, use

CompositionTarget.Rendering

event for animation (change value for animated property based on elapsed time). Possibly, finish event handler with

thatBigGrid.UpdateLayout();

Margin is a property that affects layout. When Margin of the Grid is changed during animation, Arrange function will be queued, executed, and inside Arrange position of each of Grid child element will be updated in a loop. If rendering for the next frame starts in the middle of this process, some elements will displayed in new positions, some in the old - resulting in jerky looks.

If that's what really happens, solution is manually controlling Rendering event and ensuring that layout is fully updated before drawing.

ima
could you go into more detail about what is going on here for the benefit of myself and others?
Firoso
Updated
ima