In previous blogs , I talked about the classes in animation and what the different types are; not to mention how great WPF is that doing animations is so easy
Now, where do you place animations in xaml?
Firstly, they have to be defined within a storyboard.
A storyboard (I’ve always felt a slightly odd name for the class) can contain a number of animations, and it is the storyboard that controls the playing of the animations.
Here is n animation within a storyboard that makes the textbox widen when you put the mouse over the textbox:
Well TechEd 2008 has come and gone (USA version anyway)
Where were the announcements about new things for WPF?
There was a new beta for Silverlight (Beta 2), which is good as I believe Silverlight will be a great thing for web development
I was hoping there might be something about MVC and composite client for WPF.
If you remember, this was called Acropolis before being ‘folded’ into mainstream VS development
I hope I’m wrong and there is much more to come , maybe at PDC
The long awaited paging grid might be useful
Have you ever been in the situation where you’d thought you were in the UI thread nice and safely, but got the exception message:
The calling thread cannot access this object because a different thread owns it”
What this means is that you have created an object on a thread (usually UI thread), and are then trying to access it from another thread at runtime.
Maybe from a worker thread running an event handler.
To fix it, you need to use the very handy Dispatcher class, which will marshall your call to the correct thread.
You need to use the BeginInvoke (asynchronous) or the Invoke method.
However, you don’t want to have huge numbers of delegate definitions all over your code, so use an anonymous method instead.
The trick is to make sure the returned type from the anonymous delegate is one that matches what the Invoke method expects
If the correct thread happens to be the UI thread you can do the following:
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Normal, (DispatcherOperationCallback)delegate(object arg)
// do sommat
All of the interesting WPF classes derive from the TimeLine class.
What do I mean by interesting?
All of the classes for animating different types (like DoubleAnimation and ColorAnimation), MediaTimeLine (for playing videos and audio) and TimeLineGroup from which StoryBoard (which provides the canvas for running animations) is derived.
Also, the TimeLine class itself has some key properties which bear noting:
- Duration – length of time the animation runs, used by most of its children
- SpeedRatio – increases or decreases the speed of the animation. It defaults to 1, setting it to 5 runs the animation 5 times faster and setting it to 0.5 makes the animation twice as slow
- AccelerationRatio -changes the relative speed of the animation, so that it starts slowly and speeds up. You specify values between 0 and 1, where 0 keeps the animation constant and 1 accelerates it towards the end
- DecelerationRatio – does the opposite of AccelerationRatio, i.e. makes the animation slow down near the end
- AutoReverse – will make the animation reverse after it finishes, if set to true
- BeginTime – allows you to specify a delay before the animation starts
- FillBehaviour – specifies what happens when the animation finishes, e.g. hold the value or revert back to the original value
- RepeatBehaviour -gives the animation instructions on how many times to repeat the animation or for how long
In a previous blog, I spoke about the different sets of animation classes.
Also when you are doing animations in WPF, there are some key properties.
These are properties that apply to most animations.
From – this property gives you the starting value for your animation.
It is optional, and if you leave it out a starting value is calculated from existing value taking into account the animation
To – this property gives you the ending value for your animation.
It is also optional. When you leave it out, an ending value is calculated , but without taking into account the animation. That means it uses the value set in the xaml or code.
By – this property allows you to specify a once only increment for your animation.
You can combine this with a To property, or leave it without a To
Duration – this allows you to specify the length of time that the animation runs for
You can specify the Duration type, or a TimeSpan (which has an implicit cast to a Duration).
The advantage of the Duration class is that it can allow you to specify a duration of automatic or forever.
IsAdditive – this makes the From, To and By work by adding their values to the starting value for the property.
As a slight sea change from the norm, which just shows the (extremely) impressive animation facilities available in WPF, why don’t I explain a bit about the different animation classes.
Out of the box, the nice people on the WPF team(s) have defined three sets of classes for doing the animations.
- Linear interpolation classes, which start from a positon and smoothly increment to the end position
- KeyFrame classes, in which you provide a series of steps and the values change according to the steps provided
- Path classes, in which you use path geometry to specify how the animation proceeds based on the geometry specified (eg a shape like a square)
Also, you are free to create your own animation classes, as all these derive from abstract class TAnimationBase where T is the type name.
For example, there is a DoubleAnimation, a DoubleAnimationUsingKeyFrames and a DoubleAnimationUsingPath – all derived from DoubleAnimationBase.
All of these can be specified in code, or slightly more easily in xaml
I shall go into these different areas in future blogs
This is something that I had to do recently, and it wasn’t as obvious as I thought.
Given a very simple enum like:
The first (and obvious) try is:
Here we are trying to hide a label and a textbox based on the value of the enum.
However, it doesn’t work
As an aside, the autogrid you see heer is very handy, and can be found on www.codeplex.com
What you actually need to do is slightly odd, and is effectively instantiating the enum values:
Have you ever written any user controls or custom controls?
The difference between them is that with a custom control you have full scope to render it (plus you have to do it), whereas a user control is a container to amalgamate other controls.
With both of them though, you need to make sure that any calls made out of them are minimised.
Well because when they are created in WPF designers like Visual Studio 2008 or Expression Blend, they will be instantiated and therefore constructors will be called.
If you have calls out to databases etc, you will get a nasty looking exception thrown, or just the Visual Studio 2008 problem loading display:
How do you sort this problem?
By using the GetIsInDesignMode static method of DesignerProperties, like so
// do something you don’t want to appear in designer
As I am architecting a new Line Of Business system for a customer, one of my thoughts is to recheck the situation with WPF controls.
The power and styleability of WP, with a few small exceptions, means that there isn’t quite the need for third party control libraries as there was in WinForms. In the days of WinForms it was a question of which of the main control libraries you picked, and how that was achieved with whatever ridiculous purchasing system was in place.
Now with WPF (and Silverlight soon), the focus has changed. There are a couple of holes in the WPF offering, like a paging grid, date time picker, numeric value editor. However, if you look at codeplex, most of the holes have been addressed by free controls. Also Xceed moved the goalposts for the component writing companies by giving away a top quality grid.
However, it’s not beyond some development teams to write their own controls as well – whereas that would have been a long, frustrating and expensive process in Winforms. I know because I have seen it
Another bad effect I see, is that some companies just won’t bother – and try to muddle through on their own , which does seem a mistake to me.
What does that mean for the major component vendors?
Well, in my opinion, it means they need to up their gameplan, and provide components on a different level. They can’t just provide decent grids and toolbars etc, that were missing from Visual Studio.
To be fair we have started to see the beginning of that, with carousels and ribbons
Do you have problems printing documents in WPF?
My problem manifested itself when I tried to print a document from a FlowDocumentPageViewer (though the same is true from a FlowDocumentReader).
The problem I was getting was that if I had multiple pages, they would all be scaled and fitted onto the same size of printed page as on the screen.
How do you get around this?
Well the problem lies in the fact that the document is being shown on the screen which has a different size to the printed page.
Realising that, the solution itself is simple – change the height and width of the document before printing it, like:
Assuming docRdr is a FlowDocumentPageViewer and prtDlg is a PrintDialog:
FlowDocument doc = docRdr.Document;
doc.PageHeight = prtDlg.PrintableAreaHeight;
doc.PageWidth = prtDlg.PrintableAreaWidth;
Of course, you will need to remember to save the FlowDocument’s height and width, then re-apply after you have printed the document.