Archive

Archive for the ‘Programming’ Category

Adventures in WPF

August 5th, 2009
Comments Off

I’m very new to Microsoft’s Windows Presentation Foundation (WPF), even though the technology has been out for a few years now (since .NET Framework and Visual Studio 2008). As with many new programming paradigms, I tend not to put in the hard yards in learning them until (1) they appear bedded down and stable and (2) I see a real use for them. The latter is usually the big decider – I can’t learn everything, particularly as my aging brain finds it harder and harder to cram in new stuff.

Anyway, I did do some work in WPF earlier this year, in building a digital signage system for the National Sports Museum. Basically a display of current world records, it needed to be attractive, have interesting transitions, and be very easy to update.

In years gone by I would certainly have built this kind of thing in Flash, possibly under the control of a C# shell program. But it seemed like a good opportunity to get my feet wet with WPF, and so I gave it a go. It was a struggle, but with the aid of a good textbook (Programming WPF by Chris Sells and Ian Griffiths) I managed to achieve a pretty good result, I think. By the way, I do find that when learning something new it’s far more helpful to have a good, hardcopy, text book by my side than any amount of electronic help.

So over the weekend I got the impulse to do some more with WPF, the trigger being some astronomy articles I was reading.

A long time ago I wrote a program called Gravitorium, still available as shareware (though hardly anyone ever buys it now). The purpose was to act as a simple simulator of gravitational interactions between arbitrary stars, planets, asterioids, etc. Build your own solar system and see what happens. Throw a black hole through the middle of our own solar system. That sort of thing.

The old version of Gravitorium

Now here’s the thing: Gravitorium was written nearly 10 years ago, in Visual Basic 6. Calculating all the interactions in such a system is very slow, and updating the display is even slower. Running on the kind of computers and graphics cards we had 10 years ago, it’s surprising that I was able to get any kind of reasonable result at all. Watching a simulation the motion of the Moon around the Earth, for example, was a bit like watching grass grow, unless you cranked down the accuracy of the simulation a fair bit.

So for some time I’ve been toying with revisiting the program, using modern programming techniques and a much faster computer platform. And I figured that WPF, which gives direct access to the graphics processor, would be just the shot to give a much speedier result.

Well, so far it hasn’t worked out like that. Now do bear in mind that in what follows I’m just going to be exposing my experimentation and learning processes to you. If you already thoroughly understand WPF, this article is not for you!

I can see that there are going to be major benefits from a WPF approach. For example, in the old Gravitorium I was doing some pretty dumb things to draw planets and orbits. Everything happened on a PictureBox control. To create the illusion of a moving object I first drew a colored circle and then on the next phase, ‘erased’ it by drawing a black rectangle over it. All the objects and all of orbital trails were just bitmapped onto a single layer. The orbit trails were just literally painted dots, and each time the display is rescaled, I had to keep track of the dots and repaint them.

In my new version, I’m playing with using a WPF Canvas object, and associating Ellipse, Label and Polyline objects with each body in the system. These get moved around as the calculation proceeds, and WPF takes care of redrawing the display. The Polyline object redraws the orbital trails (admittedly as a series of straight lines rather than curves, but the segments are so small they look smooth).

It’s kind of working, but I’m not there yet! Refreshing the display regularly is a bit of a struggle, which I don’t yet understand. In the old Windows Forms days, I would just repaint things in a loop, invalidating the picture box or doing an Application.DoEvents() call. You can’t do that in WPF, which seems odd. I found a couple of ways around this limitation. The one that works best so far is a ‘fake’ DoEvents() procedure which I found here. I modified it by adding the null object check, which avoids an exception on closing the application.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using System.Threading;
using System.Windows.Threading;
//....
 
/// <summary>
/// Processes all messages currently in the message queue.
/// </summary>
/// <remarks>
/// This method can potentially cause code re-entrancy problem, so use it with great care.
/// </remarks>  
public static void DoEvents()
{
     if (Application.Current !=null)
    {
       Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate { }));
     }
}

I do suspect that having to use a crutch like the above means that I don’t have my head around WPF as yet.

Anyway, the revisited application (which at present is only a proof of concept) is coming along:

Gravitorium WPF POC

This is working fast enough to be able to animate the labels along with the objects (the VB6 version has to pause to show labels) and still get a pretty swift animation. At an equivalent level of accuracy the VB6 version takes 95 seconds to complete an orbit of the Moon. The WPF one, even with the overhead of redrawing labels, only takes 25 seconds. That’s about a four-fold increase in speed, and the results look much nicer.

Anyway, this is a WPF Work in Progress, so I’ll return to it as I continue my learning process.

david Programming ,