Moving-away animation in wpf usercontrol list - wpf

I'm creating a WPF program. I want to animate a list of usercontrols to be animated in such way that they seem to move away from the user. Imagine watching the road as cars move away from above them (a little higher than car's roof). I hope this was clear enough. I will try to add a video/GIF if it isn't.
I don't have much experience in WPF animation. Is there any built-in way to achieve this? I searched around but since I don't know what exactly this is called, I didn't have much success.

Silverlight has 3D projection transforms that you can animate, but not WPF unfortunately. You can still accomplish 3D projections though by writing your own animations, or by using 3rd party libraries (for example).

Related

WPF CustomControl design advice

I need to develope a WPF custom control to show the layout and connectivity of nodes in a wireless mesh network. The user needs to be able to drag the nodes around. The canvas should grown and Scrollbars should appear as required if elements get draged off the available space. The ability to zoom in/out might be required.
My first take on this is to use a ListBox derived CustomControl with a Canvas based ItemsPanelTemplate. To get things moving Im using Josh Smiths DragCanvas that allows UIElements children of the canvas to be dragged around. My "node" class is not currently UIElement derived (the DragCanvas is currently working with the ListBoxItems that wrap my nodes).
1. Is this a bacially sensible approach or should I be abonding the ListBox idea and going something lower level?
2. I have to overlay the inter node link lines - not currently sure how to go about this (as a UIElement class that is part of the ControlTemplate?)
3. A few people seem to be having a headache with scrolbars in Canvases - is this going to be an issue?
Any general or specific advice most appreciated.
Wow, not bad as a control!
I am doing something similar, but it is not so simple.
1) IMHO, the DragCanvas is a basic way to host+drag elements. Since you will have to host labels (nodes), arcs and labels again (arcs' weight), I think the DragCanvas would be harder than write a custom control by yourself.
Not everything comes easy with templating: sometime is much better the "old" approach winforms-like, or even a hybrid way.
2) As stated, I'd create a Canvas-derived panel, which will host several UIElements (labels, arcs, etc). All of them should be governed by a model+viewmodel. That's a bit harder at the beginning, but it will give you a lot of satisfaction and flexibility in the future.
3) I don't think the Canvas will give you any headache! A Canvas full of elements has always a size of zero. That leads "headaches" for those trying to add a scrollviewer.
Instead, the Canvas-derived class (above) should override the MeasureOverride method, so that its size will fit any of the hosted objects. However, it is a bit annoying the fact you cannot use negative coordinates (it will cause scrolling problems).
It's hard to describe in few lines all the work behind a similar "editor". The task isn't easy, and the problems are many.
Hope it helps, anyway.
Cheers

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

WPF - Creating simple controls to be used on a Canvas

I'm developing a simple WPF UI for image post-processing.
I'd like to create a draggable WPF control to be used on a Canvas which would look roughly like this:
http://img32.imageshack.us/img32/884/photoeditor.png http://img32.imageshack.us/img32/884/photoeditor.png
Both end points ellipses would be draggable and the line joining them would follow as the end points move.
Now, I know how to implement this by simply adding these elements into a Canvas and then implementing the necessary event handling to make the elements move as they're dragged. But that's hard to maintain if I ever want to add other types of draggable controls.
What I'd like to do would be to isolate all the handling into its own class (say DragLine), derived either from FrameworkElement or UIElement. To add this draggable UI element into a Canvas, I'd create an instance of DragLine and just add it to Canvas.Children. The rest of my program would only see DragLine instances and wouldn't need to worry about the lines or ellipses used to draw the new element.
I'd like to implement the line end points using standard shapes such as the Ellipse rather than drawing all of the UI element myself. That's because I'd like to re-use the event handling and hit testing these shapes already implement.
Question: is deriving from FrameworkElement the right way to go about this? The line and end point ellipses would then be just be visual and logical children of in my new class.
If deriving from FrameworkElement is not the recommended way, how would you go about this instead?
If it is, is there a way to simplify its implementation given that the new class would only ever be used on a Canvas (and doesn't need to work well for things like a Grid or a StackPanel)?
Ah, yes, trying to reinvent things that already exist in the framework because you don't know about them. Its been a hobby of mine for quite some time.
What you are doing here is trying to create a special type of adorner. These are relatively easy to do using the bits that already exist in the framework. I suggest you start here.
Another thing you might want to look at are Decorators. Do pretty much the same thing but I think they are more visual. Which one to use depends on your requirements.

Silverlight DRY when animating multiple UserControls on main Navigation page

Starting with Silverlight development. Yet to read a good Silverlight book: suggestions welcome.
I have a main GUI screen where 7 user controls (menu items) 'swoop' into sight, all along their own path. I have the user controls nicely seperated and behaving well. Having multiple storyboards (1 each for each menuitem) with multiple keyframe animations (X,Y,height, width) in one .XAML is not sitting well with me. Repeating all those property values is hideous, neverthemind maintenance.
I've tried to move values into the app.xaml and set animation durations with style keys, but having limited success. Can anyone suggest a nice way of making this cleaner? Refactor the storyboards out to their own control? Property values in resources? Dynamic building in codebehind?
Referring me to a how-to site is fine as well.
You may be falling foul of XAML overload. It seems that most developers, when starting with WPF or Silverlight, feel everything should go into XAML that can go into XAML. They then get to a point where they're fighting with the XAML to get something done that would take moments in the code-behind (I too have hit his issue).
If you're finding something cumbersome or ugly in XAML, consider writing it in code. It's not a crime. You can probably declare a single method for creating your storyboard and then use it multiple times, or you could create a class that wraps your storyboard and add multiple instances into XAML in much neater ways. As you have quite rightly identified towards the end of your post, there are multiple ways to make it cleaner, you just need to decide which one suits your situation.
Without some example XAML, it's difficult to visualize the exact issue you face, so I couldn't make a distinct recommendation, but I hope this helps. I like the sound of your swooping controls - the image I have in my head is quite nice indeed.

Resources