Saturday, 31 January 2009

Beware of The Zone

As a developer, often I'll go into The Zone on a particular project. I'm sure most people reading this will be familiar with it, but if you're not, for me, it's when I'm coding on an exciting or time critical task and am completely oblivious to all that is going on around me. But here is a cautionary tale.

A while ago now, I had a small application to write that would facilitate the scanning of barcodes on boxes as they were unloaded off the large racks that held them. There was a pretty tight deadline for this, so I started coding in the morning with the aim of getting it done by the end of the day. And so I did. Both client and server were easily done due to the coding frenzy that had occurred. Zone Central. I registered the application name in the development database table that allowed/denied permission to particular assemblies ready for testing the next day.

Next morning, I came into work, grabbed a coffee and sat down. I couldn't help but notice rather a lot of sniggering and stifled laughter behind me.

"Dave," says one of my fellow developers between snorts, "you can't call an application, Rack Scan..."

Indeed you can't. In the Zone, Rack Scan was a perfectly logical name for the application. Of course, in the real world to which I was blinded, Rack Scan instantly conjures up images of something completely non-work related.

Been in the Zone? Take my advice, and take a step back for thought at the end of the day.

Labels:

Bookmark and Share

Friday, 30 January 2009

Using the LinearGradientBrush for Good and not Evil

When it comes to Windows Forms applications, people these days have higher expectations about how they're going to look, especially with operating systems themselves coming with UI bells and whistles. When it comes to non-WPF C# apps, you can quite easily create something that looks like you dredged it out of the "My First VB6 Application" school of user interfaces if you're not careful.

Here's one way in which you can make good use of the LinearGradientBrush to add a nice gradient effect to a panel background:



Firstly, I'm going to seperate the actual drawing code into a method, so I can use it for other controls:



Then, in the paint event of the control I want the gradient to appear in:



Simple as that. Obviously, such an effect should be used judiciously - there are some particularly vile things that can be done with Gradient brushes I'm sure we've all seen examples of. But with a little patience, you can make your UI look that bit more appealing. You might also want to experiment with LinearBrush.SetBlendTrianglularShape and the values passed into the LinearBrush functions.

You can download the project file here:
GradientDemo.zip

Labels:

Bookmark and Share

Thursday, 29 January 2009

Productivity Tools - SlickRun

Due to the nature of my job, I have the curse of using a laptop to develop on when I'm at work. It's not a bad spec, plenty of RAM, XP, Core 2 Duo processor. But it falls down when it comes to the hard drive, which is a pretty nasty 5,400 rpm excuse of a thing. The speed at which my considerable Start Menu loads can at times, be pretty dire. It's a classic case of portability at the expense of productivity.

Previously, I had favoured the use of a double height taskbar and the quick launch toolbar for frequently used programs, but even this was becoming unwieldy.

Fortunately, I then discovered a rather nice freeware application with a small footprint, called SlickRun.

Once installed, SlickRun sits in the corner, or wherever you place it, waiting for the hotkey combination to activate it. You can configure in terms of opacity, colour, and whether you would like it to display the date. Here's how SlickRun currently looks on my system:



Once configured, it allows me, in a few keypressess, to launch my apps without having to go near the start menu or quick launch toolbar. For example, to launch Visual studio 2008, I simply press 'WINDOWS + W' (which sets focus to slickrun) and then I type '08' followed by 'ENTER'. Another nice feature is the ability to launch an application under a different account (RunAs).

I can't vouch for v4.0 of the app which is currently in development, but 3.9.8.3 works like a charm.

Launchy does a similar thing, but works by indexing the Start Menu and desktop. SlickRun however, is my current preference. Cunningly, it also keeps a running total of how many commands it has executed since installed. I think this following screen capture proves just how useful I find SlickRun to be!



What productivity apps would you recommend?


Labels:

Bookmark and Share

Wednesday, 28 January 2009

Visual Studio - Dock or Anchor?

There's two very important UI concepts to grasp when designing windows Forms in Visual Studio - Dock, and Anchor. These can be used to make the best use of available space when your form scales to different screen resolutions.

Dock

Dock effectively sticks a control to one, or all sides of the parent container, with 'Fill' being the option that docks to all sides. The gap that is left between the sides of the parent container and the child control(s) docked in it can be controlled using the parent's Padding property.

In the following example, you can see the effect the dock property has on a standard button when applying each particular dock setting. Padding is left at the default value of zero:

And here you can see the effect of having the Dock Property set to 'Fill', with the padding property on the parent container set to a value of 10:

Even if the form is resized, dock will cause controls docked to an edge to move or scale appropriately.

Anchor

Anchor works differently, and is used to maintain a constant distance between the edge of a control and the container it is in. The anchor property can be applied to between zero and four sides - left, right, top and bottom. Controls default to docking to the top and left sides of a form. If you dock a button on a form to the bottom and right, your button will move both down and right when a user resizes the form in those directions. For example, here's our button, anchored bottom and right, moving as the form is resized:

Finally, it's worth bearing in mind that unlike their nautical equivalents, you can't dock and anchor at the same time. But that's ok; we're not on a boat.

Labels:

Bookmark and Share

Tuesday, 27 January 2009

About Me, and Why You Should Read This Blog

Now that I'm half a dozen posts into this blog, let me introduce myself.

I'm Gareth. I've been a full-time software developer since 2001.

In what seems like a century ago, I've been programming computers since I was 7 years old when my eyes lit up as my father purchased a shiny new Amstrad CPC. For those of you unfamiliar with such a machine (I'm pretty sure it never made it big in America), it was an 8-bit home computer which competed with the Sinclair Spectrum and the Commodore 64 in Europe.

So, as you might have guessed, it all started with good old BASIC on the Amstrad. One of the more perplexing errors during my first experiments with programming was, "Improper Argument on line x" - hence the title of this blog.

From BASIC, I progressed to Turbo Pascal and a little inline assembler for those all important graphic routines. During my university years, I had dealings with Visual Basic, C++, Java and Prolog. I spent many of those years debating whether or not to be a programmer or graphic artist, becoming quite a successful community level designer for Unreal Tournament, one of which won a prize in 2003's "Make Something Unreal" competion.

But these days, and professionally, I almost exclusively code and only use C# except when it's necessary to maintain legacy apps.

Amongst my interests relevant to this blog, I enjoy programming, technology, gadgets and the odd XBox 360 or PC game, too.

Can I e-mail you?

Yes. gareth at improperargument.com

So why should you read this blog?

  • From a programming point of view I'm going to share C# code, tutorials and finished components I've written, like the charting component I wrote about a few days back.
  • From a general technology and gadget point of view, there'll be review and opinion pieces.
  • I'm a good guy to have a debate with or bounce ideas off, should you so wish.
  • I've got my head screwed on the right way.

Hopefully, you'll find it entertaining along the way.

Bookmark and Share

Monday, 26 January 2009

The Authentic XBox 360 Red Ring of Death Experience

It finally happened, earlier this year.

Inevitable, really. Just about everyone I know with an Xbox 360 had already had the Red Ring of Death experience, and now it was my turn. My turn just as I had some quality time to myself to play Guitar Hero III, and Gears of War 2. Murphy, I'm looking at you.

The point of this however, is to provide an insight into the returns process.


Breakdown Day (Tues 30th December)
  • XBox dies
  • Air is blue
  • Sign in to Xbox Live on PC
  • Register Console Serial Number Details
  • Check warranty status (I'm was fortunate in that the RRoD is now covered for three years from date of purchase)
  • Request Repair
  • UPS Shipping Label received via e-mail
  • Label printed

Third Day (Thur 1st January)
  • Decide if I have a New Year hangover
  • Negative
  • XBox wrapped in bubble wrap by yours truly, and placed in a large shoebox
  • Shipping label attached

Fourth Day (Fri 2nd Jamuary)
  • UPS collect XBox
  • UPS Man looks at the size of the box and wryly grimaces, "Another XBox?
  • I nod
  • Suspect UPS man secretly pleased the the XBox 360 is keeping him in a job

Sometime the week after
  • XBox arrives in the German repair centre

Sixteenth Day (Wednesday 14th January)
  • UPS Deliver XBox to my neighbour
  • UPS put a card through my door

Not bad. Sixteen days for my XBox to go from broken, to Germany, and subsequently into the clutches of Next Door, even with the inevitable backlog due to it being over the Christmas period. The DVD drive had also been replaced, which was odd because I didn't think it was broken. I'm guessing this was done to prevent the disk scratching problem that is known about. Was slightly concerned that they are being returned with the instructions that they can be left with a neighbour, because I don't know my neighbours that well. They could be anyone. However, my neighbour grudgingly obliged and handed over the goods, much Guitar-Heroing of debatable quality took place and all was well.

Labels: ,

Bookmark and Share

Sunday, 25 January 2009

How to Bind an Enumerated Type to a ComboBox

Simple, when you know how. Let's say we have a custom enumerated type of car manufacturers:



Now I'm going to create a method whose purpose is to bind the manufacturers enum to a ComboBox:




You might also want to change the "DropDownStyle" property on your ComboBox to "DropDownList" to stop people typing their own data into the ComboBox. And that's all there is to it. Call your binding method, and you've bound your enum.



Labels:

Bookmark and Share

Saturday, 24 January 2009

Creating a Basic Charting API in C#

Previously I've worked with several proprietary and expensive charting solutions for .NET, and wondered how long it would take to develop my own. So, with some time to spare one weekend I had a go. When the weekend was done I had a rather nice API which supported different chart types (2D Bar, 3D Bar, Stacked 2D Bar, Pie), differing styles, and the passing in of data via DataSet objects.



Above, the stacked 2D Bar with a gradient fill background.



In this one, the 3D Bar with what I called the "Stormy Weather" style applied. I also managed to implement the whole API so any chart scales with the size of the window it is placed in, and regenerates axis numbering appropriately to take advantage of available space.

Next time you have a requirement for a chart, before you go out and buy an expensive 3rd party charting solution - think - can I do that myself? You might be surprised.


Labels:

Bookmark and Share

Friday, 23 January 2009

DateTime Hell and What's Up With Facebook for iPhone?

If there's one area in particular that can make developing software seem like a chore, then it's DateTime problems. Spend long enough working as a developer and chances are you will encounter some bug or problem that deals with DateTimes that has you pulling your hair out.

Sometimes, it's jut a case of attention to detail. Does the person you're developing software for really need to see their shipping times down to the nearest millisecond? Probably not. If not, don't show that level of detail on your UI. It may well come out of SQL Server like that, but chances are no-one wants to see it.

Famously, even most members of the non-technical public will have heard of the Y2K problem. But on a day to day basis - it's the mundane things like leap years, leap seconds, varying numbers of days in a month, time zones and logic that uses the exact time when you only wanted it to be specific to a day that cause the serious headaches.

But here's the thing. Horrible though they may be, DateTime issues are, to my mind, some of the most critical and they need high priority on any fix list. Got your dates and times wrong? Then you're displaying wrong and in many cases, useless information to your customers.

What's up with Facebook's iPhone app then? Despite the recent release of an update, the DateTime issue persists, where I see my friend's status updates several hours askew, and often appearing in a completely different order to that which they occurred.



Given the size of the user base, not fixing what looks suspiciously like a time zone and ordering bug is taking a bemusing amount of time to solve. It's probably a dreary and uninteresting problem to fix, I can sympathise with that - but if it takes much longer to resolve I can't forgive.

Labels: ,

Bookmark and Share

Thursday, 22 January 2009

Essential Visual Studio Knowledge, Part I

I'm often baffled when people say, "I'm looking for such-and-such a .NET class, but I can't find it!". In many cases, it's as simple as making use of the smart tags. Smart tags are the little red underscores that often appear under code you've typed into the IDE. For example:



Subsequently pressing CTRL + . brings up the smart tag menu:


Hit return to have the IDE insert the using statement for you and hey presto!

Bookmark and Share

Wednesday, 21 January 2009

To Dispose, or not to Dispose

The question was recently posed to me:
  • If the .NET framework handles garbage collection for me, why would I ever need to use object.Dispose()?
Well, although the framework may well handle the freeing up of memory automatically (which is great), you should really dispose of limited resources as soon as you're done with them. Database connections and GDI+ objects, for example.

Let's look at the GDI+ example in a bit more detail. Windows limits the number of GDI+ handles. So if you're creating a lot of GDI+ objects, for example, a number of Brush objects, the framework will dispose of them when the garbage collector gets around to it. In the meantime, you could have run out of available GDI+ handles (even though you haven't run out of memory). Unexpected Things may then occur.

As developers, we don't like Unexpected Things. In many cases, they may cause the people using your application to have cause for the client-helpdesk "just try rebooting it" scenario, which will miraculously fix the problem, but in the most horrible way.

So, in the case of our Brush it's better to do:


using (SolidBrush SB = new SolidBrush(Color.Red))
{
// Code
}


than:


SolidBrush SB = new SolidBrush(Color.Red);


The first way ensure that the Brush gets disposed ASAP, especially if the second example is used and Dispose() is not explicitly called.

Labels:

Bookmark and Share