RSS Feed

Wednesday, July 30, 2008

The Holy Grail - Application Development without Developers

If you've made it this far, I can tell you that the title is tongue-in-cheek. No throwing things at me or unsubscribing (thus cutting my readership in half).

Over the course of my career, I've seen attempts on various projects to eliminate the need for ongoing developer involvement in system maintenance. The argument goes something like this: If we could just build a flexible business rules engine, we wouldn't have to call the developers every time we need to update our FILL IN THE BLANK.

Don't get me wrong... there is definitely a time and a place for application configurability. It's just that business owners (egged on by developers looking for a good challenge) tend to over-extend the concept. For example, they may foster the creation of a new micro-language for defining pricing rules. Something like:

IF ($PRICE$ > 100) $PRICE$ * .90 --> $PRICE$ ELSE $PRICE$

Given that I personally know both people who read my blog, I know you could implement the parser to apply this business rule. And why not? Now my business owners can be in complete control of their pricing rules! We're not just talking a few canned rules... No, I mean autonomous, unbridled, master-of-your-own-universe power!

But there are a few catches. What happens when my business owner misses a closed parentheses? Well, it's back to the drawing board to write a user-friendly syntax checker (a.k.a. compiler). But then, they forget the symbol for manufacturer cost and complain (which is, of course, $MFG_COST$). Well, it's probably time for documentation (language specification) and macro-builder (IDE). The next complaint you get is "My pricing rules are getting really hard to enhance without messing them up." Well, this time (again because I know who my readers are) you realize you'll need to implement a unit testing framework and educate your business owners on Test Driven Development.

By now, however, the gig is up. You don't know how to implement a unit testing framework for your new language, POOP (Pricing Open Operation Protocol). However, you've now spent 20% of your career developing it, its compiler, it's language specification, and its IDE. You're highly invested - it's no time to abandon POOP now!

You forge on... You begin gathering pricing requirements from your business owner (if only you could just program all day), implementing them, and demonstrating them for acceptance. It's just that you're life is harder than it used to be. You used to have a powerful, expressive language (C#), complete documentation (MSDN), whiz-bang development tools (Visual Studio & Resharper), and unit testing framework (NUnit). Now you've just got POOP.

Friday, July 18, 2008

Welcome to Headspring!

In what has become a growing trend, we've recently brought on two outstanding new team members: Blake Caraway and Duane DeRouen.

Blake comes to us from Callaway Golf Interactive where he led teams to implement distributed e-commerce systems. Blake is a technology thought leader and has experience working with clients to define what they really need (as opposed to what they initially think they need).

Duane joined us officially after playing an instrumental role at our largest client. His expertise in project and account management will be vital to our company's continuing success.

On a personal note, my biggest motivation in being on the leadership team of a small company has always been to have the opportunity to work with the very best people. Our two newest hires exemplify that excellence in their work, and I can't wait to spend more time in the trenches with them.

Saturday, July 12, 2008

A little help with the .NET WinForms TreeView

So here's the situation: you're developing a .NET WinForms application that needs a TreeView. Obviously, there are a lot of tree controls out there from Infragistics, DevExpress, etc. but you may find that the .NET 3.5 TreeView is sufficient. As I discovered this week, there are likely two issues you'll face when you use the TreeView.

First, when the tree loses focus, the selected node no longer appears highlighted. Maintaining the highlight can be useful if the TreeView is used in conjunction with other controls to help a user navigate or enter data. In these cases, the highlighting can help provide context to the user about the current state of the application.

Second, there is no ideal event for handling what would seem to be the most basic TreeView event - a user selecting a node. How is this possible? Sure, there's the AfterSelect and NodeMouseClick events, but they're both lacking in their own way. The AfterSelect event is close but it isn't fired a second time when you click on the same node twice. The NodeMouseClick event would seem like a good choice, but it isn't fired when the user navigates to a node using the keyboard (for example using the up and down arrows).

Here's a little code to address both issues:

Issue #1:

In your form constructor, attach a handler to the BeforeSelect and AfterSelect events of the TreeView (trv):

trv.BeforeSelect += trv_OnBeforeSelect;
trv.AfterSelect += trv_OnAfterSelect;

In the BeforeSelect event handler, add the following code:

private void trv_OnBeforeSelect(object sender, TreeViewCancelEventArgs e)
if (trv.SelectedNode != null)
trv.SelectedNode.BackColor = SystemColors.Control;
trv.SelectedNode.ForeColor = SystemColors.ControlText;

I've used the Control and ControlText colors because I've set the background color of the TreeView to Control. I think by default the background color is SystemColors.Window.

Next, add the following code to the AfterSelect event handler:

private void trv_OnAfterSelect(object sender, TreeViewEventArgs e)
e.Node.BackColor = SystemColors.Highlight;
e.Node.ForeColor = SystemColors.HighlightText;

// Handle the Node Selection Here...

That's it! Every time a node becomes selected, it's background and font color is set to the highlight color (typically blue background with white text). Every time a node is deselected (just before another node is selected) its color scheme is returned to the default.

Issue #2

To solve the second issue, hook up the following two event handlers in your form constructor:

trv.AfterSelect += trv_OnAfterSelect;
trv.NodeMouseClick += trv_OnNodeMouseClick;

Now, enter the following code in the corresponding event handlers:

private void trv_OnAfterSelect(object sender, TreeViewEventArgs e)
// Handle the node selection

private void trv_OnNodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
if (trv.SelectedNode == e.Node)
trv_OnAfterSelect(sender, new TreeViewEventArgs(e.Node));

Obviously, the "magic" for this one happens in the second handler. Here, we simply check to see if an already selected node has been clicked. If it has, we delegate to the handler for the AfterSelect event passing in the node that was clicked on.

Hope this helps!

Everything starts small...

Although I realize those reading constitute a (very) small group, welcome to my first blog post. Reaching even the most impressive destinations always requires a small first step - I hope this post will serve as that step. As I stated in the blog's description, my immediate goal in creating this blog is to disseminate valuable insight that will ultimately help Headspring better serve our clients by delivering the most value possible within our clients' budgets. Since this is a goal common to all IT organizations, others may find the information valuable also. However, my first allegiance is to the guys (sorry, no female consultants yet) who get up every morning to build outstanding software for our clients and by so doing grow our company's reputation and future prospects.

A sincere thank you to Jeffrey Palermo (or for those likely reading, just Jeffrey) for his continued mentorship. He's taught me far more in the past two years about software development than I learned in the preceding ten.