Archive for the ‘.net 3.5’ Category

There’s been a project knocking around the back of my head for a while. I keep putting it off, doing some work on it now and again but never really settling down to really do it. This long weekend turned out to be one of those occasions; I’ve just finished playing Fallout 3 (Awesome game, the ending left a slightly bitter taste in my mouth though) and ended up with nothing to do. Visual Studio to the rescue…

Now what?

If you ever worked on an application that requires Internet connectivity, you will have had to handle situations where the connection may be unavailable for certain periods of time. Sometimes you can get by that by trapping an exception; I know I have, though I still find that particular solution to be somewhat inelegant. What I wanted was some way to monitor the state of the connection and keep track of it. This way, if you need to send a message for example, you can have your application decide whether it should try to send it right away, or whether it should stash it away till the connection becomes available. This post is about how to determine whether a connection is up or down, and notify the application when the state changes.

Doing it the managed way

There is a method in .net, NetworkInterface.GetIsNetworkAvailable(). This method will tell you whether there is a connection going out of the machine, and it seemed to be the ticket. Unfortunately (or fortunately – this would have been a really short post otherwise), in my case, it wasn’t. You see, when we’re working off a LAN, we can have local only connectivity, or low connectivity. This means that the machine can talk to the router, but cannot access the Internet at large; the method still returns true in this case. If you’re working on an intranet application, this may be ok for you, but I wanted something bigger.

Going native

My friends have a long standing joke. It goes something like, “If someone invents a piece of hardware to wipe your bottom, the Windows API probably already supports it.” (The exact quote is unsuitable for mixed company). The windows API does, indeed, grant you nearly god-like powers over your system, and nearly anything Windows can do, the API can too. Since Windows can tell when there is no connectivity to the web (the dreaded “local only” icon), I figured that PInvoke.net would be the next port of call in my search. Sure enough, wininet.dll defines a function InternetGetConnectedState…

Ouch. We still have the same issue… it doesn’t really care about the “local only” business. At least, it gives us some additional information, such as whether the connection is through a modem or a LAN.

Hackety-hack-hack time

I’m still fairly confident that there’s a direct way to get to this information, but since I just want to get this to work right now, I’ll fudge it up a bit.

Using the wininet.dll function, we can tell whether we’re connected to a modem, connected to a LAN, or not connected at all. Not connected means just that, so that’s easy. For modem connections, I’ll assume that it’s either connected to the Internet, or not connected at all (You’ll have to excuse my blatant ignorance of networking hardware. Drop me a comment if you know this is the case). This just leaves us with the LAN condition to deal with.

The machine that goes PING!

When we know we’re connected to a LAN, but not how far we can go, we have to resort to the time honoured mechanism of the PING. All hail the mighty PING.

A ping is simply a very short message that’s sent to the server. If the server accepts the ping, it just echoes it back. It’s a protocol for machines to determine if they can see each other over a network. In .net, the ping is represented by a Ping class, and returns a PingReply:

1:if (isLan)

2: {

3: PingReply reply = pingOfLife.Send(PingTarget, 3000);

4:return reply.Status == IPStatus.Success;

5: }

This sends a ping to a URL identified by the PingTarget property, and waits up to 3 seconds for a reply. The URLs for Ping don’t take a protocol specifier, so you’d use, say, www.google.com rather than http://www.google.com.

You will notice that in the sample code and the example above, we’re only assuming a successful connection if the reply to the ping is successful. This is a simplification. In reality, the ping is checking whether we can access the ping target, irrespective of whether the rest of the Internet is accessible. If the target server is down, you’ll get a “No connection” result.

When you think about it, it doesn’t matter in most cases. You only care about whether your application can reach its server, not whether it’s got access to random web pages.

What else?

This seemed to sort it out for me. You can find the entire source code in the sample project. The ConnectionState class in the sample also contains events you can hook into so your application will get notified of state changes.

or, for that matter, “DataContext = anything”, is still in the code behind class. This can easily be sorted out with some easy data binding and a supporting class.

First, create a class that will contain your controllers. You can create a factory class, or, simply a class which exposes your controllers. To demonstrate this, I’m only using a class with a static property:

If we look at the codebehind for this, we have only the usual, Visual Studio generated code:

public partial class Window1 : Window

{

public Window1() { InitializeComponent(); }

}

Is this really worth it?

Yes. No. Maybe. I think it is, because I prefer to keep everything together. Besides, the idea is to keep the code behind as clean as possible. If people have to touch this class to add the data context, they may be tempted to add more stuff in there. Then again, it’s very probably a matter of preferences.

I meant to write something about MEF after my holiday, but I’ve been sidetracked
for a while. One of the things that happened to divert my notoriously unstable attention was a quite excellent five day Blend course by Brennon Williams. My preferred method of writing XAML has been, so far, in a text editor, but Herr Williams was quite persuasive in demonstrating that Blend is, in fact, far, far better for the job.

As part of the course, we wrote a small application. I ended up hacking together a 3d carousel user control for this, which I felt was pretty cool, so I set about rewriting it as a custom control for future use. No, I did
not use Blend. Yes, I did notice it’s a damn sight harder to do it in pure code than it was in Blend.

Warning: This post contains some math.

The control

This control displays one (or, indeed zero) or more Visual objects in a 3d space. Elements are arranged on equally sized panels placed around a central point – imagine a number of controls glued to the sides of a box, or a prism. The control can also be rotated to present a given face to the user.

Since the control takes instances of Visual as content, it can support most WPF elements. The contents are wrapped in instances of Viewport3DVisual2D, which keeps the child element interactive.

The math (warned you, didn’t I?)

To lay out the Viewport3DVisual2D elements, we need to throw in a bit of math. The idea is to rotate each element by a number of degrees, so that the form a closed shape. The angle will always be 360 degrees, divided by the number of elements. If we have four sides, for example, each face would be rotated 90 degrees; the first element would be at 0 degrees, the second at 90, the third at 180, and the last one at 270. Since all sides are equal in size, this will always give us a closed shape.

Getting the angle may be easy, but it’s only part of the process – we also need to work out an offset, so that all the sides line up. (see diagram). Luckily, this isn’t much more complicated. We know that all the sides need to be the same distance from the centre of the shape, and we already know what the angle between two corners of the shape and the centre of the shape is (angle a in the diagram). We also know the length of one side – which we do, since this is actually the width of the Viewport3DVisual2D.

All we need now is a right angle, which we get by drawing a line (dotted grey in diagram) from the midpoint of the Viewport3DVisual2D (dark black line in diagram). This will also bisect angle a, so what we have is a right angled triangle with a known side and a known angle. This allows us to calculate the distance of the line from the centre to the face.

Angle b is adjacent to the line we want to find, and directly opposite the line whose length is half the width of a face. This lets us use the formula:

Tan(b) = opposite / adjacent

Which becomes

Tan(b) = (Width / 2) / adjacent

which becomes

Tan(b) * adjacent = width / 2

and finally

adjacent = (width / 2) / Tan(b)

… which will give us the length of the dotted grey line in the image. We will use this to specify the z coordinate for the axis of rotation for all the face – each face is generated centred on the origin (0,0,0), so any offset will result in an actual coordinate.

There, that wasn’t too bad was it?

Attack of the clones

While I was writing this control, I had a bit of a problem when attaching the child elements – WPF was complaining because the elements already had a parent. Luckily, Marlon came to the rescue and suggested that the elements be cloned, and the clone attached to the Viewport3DVisual2D elements. This isn’t as painful as it sounds, since the XamlWriter and XamlReader classes offer very simple methods to convert an element to and from raw xaml:

This did leave a bit of an issue with events – entirely my bad, should have RTFM. MSDN clearly states that XamlWriter.Save will not retain events, which is a bit of a problem considering we’re working with controls that are meant to be interactive here. The fix for this (as well as the problem with element parents) turned out to be quite straightforward – detach all the visuals from the Viewport2DVisual3D elements:

Using the control

This control inherits ModelVisual3D, so it can be dropped into any Viewport3D and used like any other 3D control. The elements that will make up the faces of the carousel have to be placed in the Visuals collection. The carousel control also exposes the ElementWidth and ElementHeight properties, which will define the aspect ratio of the faces. Finally, SelectedIndex determines which side is presented to the user.

What Marlon has not mentioned is that Speed Up My PC, affectionately known as The Sump, is, as of last Wednesday, Certified for Windows Vista. The process is certainly stressful (the testing is a lot more intense than I remember the older Certified for Windows tests – but maybe that’s just my memory covering up for trauma), but not as much as I’d anticipated. .Net goes a long way through helping you do things properly. In any case, congratulations all around to everyone involved :)

There will be some more silence for another week or so while everyone gets some overdue R&R, and then… well, then I’ll see if there’s anything I can be bothered to write about. One problem at a time :P