Click here to Skip to main content
Click here to Skip to main content

WPF Philosophers

, 27 Jan 2009 CPOL
Rate this:
Please Sign up or sign in to vote.
This article shows how to make an animating card-sorter application in WPF

Introduction

There are basically two stances towards animation in applications. Some claim animation as an unnecessary eye candy and some welcome it as a new paradigm for user interfaces. Whatever your stance is, it's good to know the basics of it. Animation control support is baked into WPF and it's easy to use.

Using the Code

The sample app is a simple card sorter where a number of philosophers are presented in a rounded frame. Philosophers image, name, life span, quote and some information about their life and work are shown within the frame. When the user selects a philosopher from a menu, the current frame turns and fades away making room for another to turn in and fade in.

By studying this app, one can find ideas for:

  • Animation
  • Databinding
  • User Controls
  • C# 3.0 lambdas

The application uses:

  • Rotation Animation
  • Technically this is a 2D animation that uses Fade Animation

Philosopher Class and User Control

The background model that hold philosopher data and is databound to the UI is called Philosopher. A list of philosopher objects is made at the app init and this list is then bound to the menu and the currently selected philosopher is bound to the rounded frame, or a ComponentPresenterUserControl. The User Control consists of TextBlock -elements with their Text-properties databound with the normal Text="{Binding Path=Name}" style to Philosopher object's properties. This User Control is then animated - rotated and opacity modified - and WPF makes sure that each element within the frame rotates and fades accordingly.

I initially made the app without user control, but with the new "Make Control" feature in Expression Blend it was easy enough to make it a control. Using User Controls makes the XAML for the container page somewhat simpler.

The User Control bears the name philoPresenter in the container control:

<local:ComponentPresenterUserControl x:Name="philoPresenter" 
	Grid.Column="1" Grid.Row="1" Grid.RowSpan="2" Margin="0,0,0,0" >

(Note: I'll not produce Philosopher class or User Control code, since they are just basic WPF elements and can be seen from the source code.)

Animations

To turn away the current card and bring in another means that animation needs to take place in three steps:

  1. Turn out and fade away the User Control.
  2. Databind a new Philosopher object to the User Control.
  3. Turn in and fade in the User Control.

Rotating and Fading the Card Out

The next code snippet shows how two types of animation are initiated simultaneously. Both are of type DoubleAnimation, meaning that they both deal with double data type. One animation is bound to AngleProperty (of RotateTransform) and the other to OpacityProperty (of the User Control). The rotation and fade times are being set in a global variable elsewhere in the app. It's important to note that the lower-right corner (Point(1.0, 1.0)) of the User Control is set as the transform origin; this point remains static and rotation happens around it.

void StartOutAnimation()
{
   this.philoPresenter.RenderTransformOrigin = new Point(1.0, 1.0);

   // Rotation animation
   DoubleAnimation rotateAnim = new DoubleAnimation();
   rotateAnim.From = AnimInFromAngle; // start degree
   rotateAnim.To = AnimInToAngle; // end degree
   rotateAnim.Duration = new Duration(TimeSpan.FromMilliseconds(rotationouttime));
   // setting up the follow-up animation
   rotateAnim.Completed += new EventHandler(OutAnimation_Completed); 

   RotateTransform rt = new RotateTransform(0, 0, 0);
   philoPresenter.RenderTransform = rt;

   // "Fade Out" -animation
   DoubleAnimation da = new DoubleAnimation();
   da.From = 1.0;
   da.To = 0.0;
   da.Duration = new Duration(TimeSpan.FromMilliseconds(fadeouttime));

   // Kick off both animations!
   rt.BeginAnimation(RotateTransform.AngleProperty, rotateAnim);
   this.philoPresenter.BeginAnimation
	(ComponentPresenterUserControl.OpacityProperty, da);
}

Databind a New Philosopher Object to the User Control

Once WPF animation is kicked off, it runs until it's done or it is stopped. In the above code, a completed-event handler was set and when the event fires, and new Philosopher is brought in by setting the DataContext of the User Control.

this.philoPresenter.DataContext = philosophers[list.SelectedIndex];

Rotating and Fading the Card Out

This phase is pretty much the same as StartOutAnimation, but with reversed values.

Points of Interest

There is some additional logic in the app to detect whether the user has selected a new philosopher from above or below the current philosopher. This way the rotation direction can be changed accordingly, making the app behave a bit more according to Newtonian-Cartesian physics (more like the natural world).

One off-topic point-of-interest is the use of lambdas to fetch the selected philosopher object from the list:

int lindex = philosophers.FindIndex(p => p.Name == currentItemHeader);

This is quite handy and saves typing compared to C# 2.0 era, where the following code would have been needed:

int lindex = philosophers.FindIndex(IsCurrentPhilosopher);

// Not used, just for reference...old C# 2.0 Predicate to find item from list
private bool IsCurrentPhilosopher(Philosopher p)
{
  if (p.Name == (philoPresenter.DataContext as Philosopher).Name)
     return true;
  else
     return false;
}

P.S.: I have to mention that the menu I'm using is a modified version from a CodeProject article whose author I don't remember and I was not able to find the article in 15 minutes. Much kudos to the author of the menu article, whoever he is!

History

  • Version 1.0 submitted on 26.1.2009

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

pompair
Software Developer
Germany Germany
.Net Developer from Finland

Comments and Discussions

 
GeneralYou got my 5! PinmemberChris Carter27-Jan-09 14:57 
Great demo, thank!
 
-chris

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.1411023.1 | Last Updated 27 Jan 2009
Article Copyright 2009 by pompair
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid