Tuesday, June 28, 2011

Being left handed

I am, in case you didn't know, left-handed. I love being left-handed, the greatest men in history were predominantly left-handed (so were some of the worst). Even God is left-handed. Don't believe me? He must be, since the Bible says that Jesus is sitting on His right hand.

Anyways, there are many, many places in which being left-handed puts me at a disadvantage. Some are trivial - did you know that the printing on pens and pencils is upside-down if you hold them in your left hand? Some are minor - scissors are built so that when held in your right hand, the top blade does not obscure your view of the cut line - when held in the left hand, you must look over the blade to see your cut line. Some can be dangerous - in fact left-handers may actually live shorter lives.

Here's one I'll bet no one has noticed before. The shortcut keys for the common editing commands undo, cut, copy, and paste use the shortcuts Z, X, C, and V respectively. All of those keys are on the left side of the keyboard. So, when I am using my mouse and I want to use one of those common shortcuts, I must take my hand off of the mouse, press the desired key chord, then return to the mouse. If I have a difficult series of edits to make (this is common when I am programming) this can be very inefficient. Sometimes I even move the mouse to the right side of the keyboard for a few minutes (another advantage to being left-handed is that most of us can use out right hands fairly well for common tasks).

Probably not the biggest issue in my life, but it sure can be irritating. I can only hope that all that movement reduces the risk of repetitive motion injuries.

Model-View-Controller

I have read all about this pattern for doing UI work, but I have never seen a great need to adopt the pattern. Both Builder and Visual Studio invite you to place all of your response code directly into the UI element class, and I have gladly taken the invitation. To be honest, I had never seen a good reason to do any differently. Oh, I would wrap some concepts into external (or even internal) classes, but the basic approach has worked fine for me.

The last couple of days I have been working on the configuration assistant for the accounting system at mypeoplematter. This is an ASP Wizard control with (as of now) 11 pages, some of which feature expanding windows that allow the user to configure things like bank accounts. Very quickly the number of buttons and their callbacks became unmanageable. So I built a controller class that provided a framework for each page. Then each "page" in the wizard got its own Controller-derived class to actually handle the work. My form class was left with just a little code to abstract out navigation events, and 4 general-purpose button events that it forwards to the controllers.

The Controller class has an interface with 7 methods:
virtual public void OnEnter(secure_accounting_ConfigAssistant page);
virtual public void OnExit(secure_accounting_ConfigAssistant page);
virtual public bool SkipMe(secure_accounting_ConfigAssistant page);
virtual public void OnSelect(secure_accounting_ConfigAssistant page, object sender);
virtual public void OnShowEditor(secure_accounting_ConfigAssistant page);
virtual public void OnSaveEditor(secure_accounting_ConfigAssistant page);
virtual public void OnCancelEditor(secure_accounting_ConfigAssistant page);

It provides (empty) default implementations so that derived classes need only override the methods they need. I built a small caching mechanism to keep track of controllers throughout postbacks.

The resulting code is so clean that I will use it in every Wizard I build from here one, and probably for multi-tab pages as well. I can find the implementation of a given event handler by going to the appropriate controller and looking through at most 7 methods, rather than the over 60 that I would have needed without the controller abstraction.

Having said all that, I still do not see how MVC (or MVVC) would simplify my pages that perform a single function. Now, I have done some abstracting - most of my data entry pages have FillPage() and Gather() methods that handle the populating and retrieval from these pages. But since the pages themselves perform only a single function, I do not see the benefit to be gained from adding a controller class.

Any thoughts?

Thursday, June 23, 2011

Demonstration

--- From my "Worship Words" series ---

Last week was Vacation Bible School. One of the things I love about VBS is all the songs with lots of hand motions and dancing. The reason we do it this way is because adding the actions helps the kids to stay interested and to learn. When we make big hand motions and sing about how big or powerful God is, the motions reinforce the message.

Our word today is “demonstration.” One aspect of our role as worship leaders is that of demonstrating what we are saying to the congregation. When we raise our hands in surrender, when we clap with joy, when we dance (or bounce) to a song of celebration, our actions reinforce the message we are singing. The principle we use when teaching children applies to adults as well – many people in our congregation are learning about God and how to worship Him by watching us. Let us demonstrate our words with our actions, just like we did last week at VBS.

Monday, June 20, 2011

UpdatePanels and Wizards

At the heart of my new website is a little control that does a dynamic lookup of a name as you type in a text box. Internally, I call it a PartyLookup (as the core table it searches is the Party table). Today, I am trying to add one of these controls to a rather nasty page: it has a wizard inside an update panel all in a modal popup extender. This all worked when the popup window did not have a wizard, but the page is complex enough that I decided I needed to break it up into 2 steps, hence the wizard. But my lookup control stopped working, as the dynamic javascript I generate to handle the AJAX calls was not getting emitted via the partial postback when I changed wizard steps (the lookup control is on the second page).

I searched Google for an hour, trying everything I could find. Finally, the following 2 changes worked:

For javascript I generate in the server-side code, I needed to use
ClientScript.RegisterClientScriptBlock, rather than Page.ClientScript.RegisterClientScriptBlock. This is a mysterious fix, but it works.

Second, for script that I want to include from an external source, I needed to add:
if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();

Together, these two calls seem to have gotten my control working in this new environment. We will see...

Saturday, June 18, 2011

Tax increases and subsidies

As anyone who knows me can attest. I am a fiscal conservative politically. My first presidential vote was for Ronald Reagan, and I considered it the best gift a young voter could have been given. I am against tax increases, period.

But I don't understand Grover Nordquist's position on the ethanol subsidies and other similar issues. I want the government to simplify the tax code, and I want the government to stop picking winners and losers. Subsidies go against both. Technically, ending a subsidy has the same effect as raising taxes, but when you have such a narrowly defined subsidy, the elimination of it feels more like a reform to me.

And these are the sorts of reforms we need. Eliminate preferences for one style of business over another. Eliminate preferences for one behavior over another. Let Americans decide what they want to buy without a parental government telling them what is best for them.

Besides, the ethanol subsidy is immoral...

Friday, June 10, 2011

Worship word: approach

My wife and I head the worship team at our church. We get to be on stage occasionally, but mostly this involves us training our young team. It's a lot of fun, and I always tell my pastor that I hadn't meant to sign up for youth ministry.

One of the things I do is what I call a "worship word." Every week at practice, I take a couple of minutes and do a short teaching around a single word and its application to worship. I'm going to start posting them here every Thursday or Friday. This week's word was "approach."

-----
The Bible tells us that we are to "boldly approach the throne of grace." It is here that we meet the God who gives grace and mercy and help. As worshipers, we do this in part when we worship. Through our singing and playing, we approach the throne of the God who meets with us. I am coming to a new understanding of the remarkable nature of our relationship with this God. He is the one who dwells in inapproachable light, whom if we were to look upon him we would die; and yet we can approach him because he invites us. Just as the shed blood of Christ opens the way for us to share in his table, so it has purchased for us an invitation to approach the inapproachable God.

As a worship team, we have an additional gift. Not only do we approach God, but we are given the task of leading others as they approach him to. Our leadership in worship is intended to open the door for the congregation to follow us into the presence of the God of the Universe. What a wonderful, inexpressible opportunity!

Javascript and .NET PostBacks

I always find it interesting when I suddenly find a use for a feature of a toolkit that I never needed before. This is the story of one such event, which just happened today.

Some background: I'm working on the accounting portion of my new company's product. It is almost ready to unveil; I just have to finish a couple of data entry screens and generate the core reports. Currently, I'm working on the bank account reconciliation page.

I want it to be nicely interactive - when you check an item off, I want to immediately update the item counts and totals so that the user can see their progress toward balanced. The most effective way to do this is to use javascript, and so that is what I did.

It worked great. But I have a handful of things that require a server round-trip, or a post back. When these happened, my totals were reset. This makes sense, the server-side couldn't possibly know what all had happened since it last sent the pages. This means that I have to figure out what the user had been doing, and have my server-side code reproduce the calculations the client-side was doing (I know I could have stored the values in hidden fields, I chose not to and I'm glad, because then this story wouldn't have happened).

Where to do these calculations? The answer is to handle them in Page_Load. I've done lots of coding in Page_Load, but never in response to a post-back. My pages mostly look a lot like this:

protected void Page_Load(object sender, EventArgs e) {
    if (IsPostBack) {
    } else {
        // Lots of code here to load the page from 
        // query strings and other stuff.
    }
}

I almost never had any code in the side of the if statement when IsPostBack was true. I had about decided I never would. But here was a case where I needed to fill my page only on a post-back.

Nothing really profound, but I just think it is interesting when something new comes up for me.

Thursday, June 09, 2011

Back again

I have been trying to figure out how the blog fits in my life. Basically, it hasn't for a couple of years now.

But I love to write, and writing helps me to organize my thoughts. So I have a new plan. I'm going to try and post at least 3 times a week. The posts will be as varied as my interests - one may be something new that I discovered about programming while working; another may come from politics or religion; others may just be from everyday life. I will try to make it all interesting, and hopefully the blog will be discovered again. But even if not, this will be the place where I can look back an remember what has happened.

But this post has another, more sinister purpose (cue music) - I want to get a link back to my new company's web site in place. So, here is a shameless plug/postback to the site in an effort to get Google to notice it. You can find my company at: www.mypeoplematter.com. The company makes church management software that runs in a browser. It is designed primarily for smaller churches - it doesn't have all of the bells and whistles of the well-established packages. But it is my experience that most churches don't want all of those things. They just need a few features: contact management, donation tracking, directories and communications, and accounting. When I finish the accounting piece in the next few weeks, I will have all of these features. And my pricing is designed for smaller churches, just a minimal monthly subscription fee, tiered based on church size. A church of under 120 will pay just $25/month for the entire package, only $15/month if they don't need accounting.

Anyways, that's what's up. If you're still out there, it's nice to be speaking again.