# Friday, October 30, 2009

So my final piece of functionality for the week in Project Resistance was to add key handling to the code base.  The idea is that if you're running on a non-touch device (or for some reason want to use the D-Pad on a touch device) then you need some ability to "select" a resistance band to change.  I plumbed through events from the Form down to the ResistorController, and back up to the View so now you can move left or right to select a resistance band and then up or down will cycle the band just like a gesture will.  Of course there's nothing yet to *visually* show you what band is selected, but the code is in place for it.

What's most interesting about the way this works is that I'm not using the standard old EventHandler subscription mechanism in code.  Instead I'm using a pattern called "event aggregation."  It's a bit odd, but I couldn't find a reasonable definition online of exactly what event aggregation is, so instead of a link, I'll actually have to provide a bit more information. 

Event aggregation is the ability of a framework to automatically collect up (or aggregate) event information and wire publishers to subscribers.  The OpenNETCF.IoC framework, which Project Resistance is using for Dependency Injection and as well as the UI framework, also provides Event Aggregation through simple Attributes.  Let's look at this key-handling as an example.

In the normal old-school event handling way of thinking, if the ResistorController wanted to get events when a KeyDown happened on the Form, the controller would need a reference to the Form so it could do a form.KeyDown += new KeyEventHandler(Foo).  The problem with this is that to do this, the Controller now has to know about the Form, meaning that they get coupled together.  That's bad from a maintenance and extensibilty standpoint, and it really sucks from a test standpoint.

Sure, I could interface the Form and then pass an interface reference in, but still, why does the Controller need to know anything about the Form?  Really it just wants to know when some other component wants to change the currently selected band or change the value of the selected band.

Well this is a classic case of where Event Aggregation rocks.  In the OpenNETCF.IoC framework, we simply need to know the string name of the event (which is stored in a global constant so everyone can use it).

The Form "publishes" the event with a simple attribute like this:

[EventPublication(EventNames.DPadEvent)]
public event KeyEventHandler DPadKeyPressed;

The anything that wants to receive the event simply uses an attribute to subscribe.  This is what it looks like in the ResistorController:

[EventSubscription(EventNames.DPadEvent, ThreadOption.Caller)]
public void DPadHandler(object sender, KeyEventArgs e)
{
...
}

By the nature of the fact that these objects were inserted into one of the IoC framework's DI container collections, the two automagigically get paired up.  No references get passed around, no interfaces get unnecessarily polluted, and out objects stay nicely decoupled.  All that is required is that both attributes use the same string name for the event and that the handler method signature matches the expected publisher's delegate.

Friday, October 30, 2009 1:51:57 PM (Central Standard Time, UTC-06:00)  #     | 
# Thursday, October 29, 2009

I didn't do much today with Project Resistance, but that didn't stop progress. Alex got all of the background paionting ironed out today while I was screwing around with paying work.  It looks pretty nice (well, except for the lower workspace, which is awaiting artwork):

I did do some thinking on the broader process of developing WinMo apps, though.  One thing that most Windows developers (as well as a great many devs for other OSes) have come to rely on is the good old WYSIWYG editor for Form/Screen/View layouts.  Generally speaking, they've been around for a good while now and not counting that major backslide called Visual InterDev, they've done a pretty good job of presenting a design time what you see at runtime.

Well for everything except Smart Device projects.  We at OpenNETCF have been building controls and libraries for devices since before we were a company.  We've seen all the iterations of Microsoft's tools (all the way back to the add-in for VB 6 in fact). Never has designing a Form in the tool been easy once you go past the basic Label, Textbox and Button UI.

Since Studio '03, to get any form of custom control to render properly you had to do a whole load of extra work.  And to make matters worse, how you had to do it seems to have changed with every new release of Studio, meaning you have to re-do a lot of the work for existing controls to get the new tools to support them.  I think this is one of the reasons there are so few 3rd-party vendors doing nice controls (especially with any sort of designer support).  To make thigs even worse, trying to support just the current tool runs into bugs almost immediately.

So what do those of use who build these apps day-in and day-out do?  Well we live with a rectangle, or a series of them, in the designer and do all of the actual layout by iterating with a device or the emulator.  So the run-time view you see above looks like this in the designer:

Fancy, eh?  And what, you ask, is the upper "DeckWorkspace"?  Well it's a container object from the OpenNETCF.IoC framework.  It basically holds a UserControl, which is what that resistor image is.  It, similarly, gives you very little as design time:

Yes, this is the state-of-the-art.  If you're coming to device development from the desktop, be prepared to be a bit frustrated.  Could we have added designer support for the resistor to this project?  Sure.  But I bet it would take more than twice the time we have already into the entire project just to get it to render, and even then it would come with caveats (like it would work with CF 3.5 but not 2.0 projects or similar silliness).

So the moral of the story is that you just get used to it.  Unless you plan to be a control vendor don't bother wasting your time even trying to get designer support working.  You'll only end up frustrated, behind schedule, and with a load of convoluted code that you'll have to rewrite the next time Microsoft releases a new version of Studio.  Maybe things will change in VS10, but based on the track record I seriously doubt it.

Don't take all of this as being completely down on Studio though.  As far as a development tool it's still the best thing out there (well it's not so great for C++, but that's another diatribe - just do yourself a favor and get SourceInsight for that).  I've used a lot of tools, and Studio, by far, is the most stable and feature-rich tool that I've ever used.  It's just that there's still a lot of room for improvement.

Thursday, October 29, 2009 8:41:22 PM (Central Standard Time, UTC-06:00)  #     | 
# Wednesday, October 28, 2009

We've made more today progress on Project Resistance.  It turns out that the earlier bug was indeed due to the fact that in the Compact Framework Color.Transparent is not a transparent color.  How intuitive.  If you do Graphics.Clear(Color.Transparent) what actually occurs is that the underlying bitmap gets filled with white.  We (and by "we" I mean "Alex") had to create some utility functions to directly manipulate the HDC and do actual transparency. 

Again, it's more than a little awkward, and how Microsoft might expect the vast majority of developers out there to get this right I'm not sure.  Even if everyone could write this code, I still think they shouldn't have to.  We should be focused on solving our business problems, not solving platform problems.

At any rate, we got a fix into the code, and I added gesturing support for the resistance bands in the ResistorView as well.

 

You can see that the background is not right, but that's an offset math issue (again due to the inability to draw transparent controls on a Form) that should be simple to fix.  Yes, the View for the numeric data at the bottom is hideous, but right now it's simply there to ensure that events get properly wired from the view above, down to the controller and back out.  Making it look good will require work from the graphic designer.

As a side note, Alex seems to be having some difficulties using SVN as a CodePlex client and that's why the fix took so long to get published.  I'm not having any problems with the TFS client.

Wednesday, October 28, 2009 12:59:50 PM (Central Standard Time, UTC-06:00)  #     | 
# Tuesday, October 27, 2009

Today has been a slow day here for Project Resistance because I'm neck deep in writing other code.  I did manage to get the gesture events for the Tolernace band on the ResistorView plumbed in so now you can swipe up/down with your finger and it actually changes the band color (though I noticed I need to fix a couple images) and it updates a second View with a text representation of the tolerance. Right now that view looks like an engineer created it, so no screen shot today - I'd rather not embarass myself.

On another, more fun note, fellow MVP and iPhone development author Christopher Fairbairn has started an iPhone port of Project Resistance.  He's also started blogging about his project.  Looking at his posts and how easy a time he's having so far makes me almost jealous.  If it weren't for the facts that you have to subject your eyes to the abomination known as Objective-C and you have to work on a Mac I just might be.  It should be interesting to see how the two projects track toward getting a product to market.  So far we're both just barely out of the gate.

Tuesday, October 27, 2009 5:35:35 PM (Central Standard Time, UTC-06:00)  #     | 
# Monday, October 26, 2009

Alex made some headway over the weekend on Project Resistance with the ResistorView and doing some drawing.  Now (on the WinMo classic emulator) it looks like this:

Notice the white border around the bands.  Nicely enough, Alex gave me a bug item for this, so I started looking at it this morning, thinking that maybe the images simply have some non-transparency problem along the edges.  Well, not so simple.  Here's a close up (using Paint.NET if you're curious) along the right edge of a Ring1 Yellow band (the one used for generating this view):

 

You can see that there's nothing wrong here.  What appears to be happening is that pixels with partial transparency (or partial opacity if you're a glass-half-empty kind of person) are getting incorrectly rendered as white.  So now we're off to chase down a redering problem instead of spending time developing logic for our actual business problem.  My off-the-cuff guess is that it's because we're storing the bands as a Bitmap class, which probably has no notion of an alpha channel, and therefore is just replacing these pixels with white.

It's worth noting that just getting this far with drawing has been heavily reliant on non-CF classes, and if my guess on the Bitmap being the problem is corrrect it means that even more of the drawing code will rely on objects not in the CF.  Again, this exemplifies the pain of creating WinMo apps that have the aethetics users have come to expect since iPhone came on the scene.

Monday, October 26, 2009 9:14:06 AM (Central Standard Time, UTC-06:00)  #     | 
# Sunday, October 25, 2009

Well, last night I got an email from Microsoft:

Not too bad.  Less that 48 hours from when we applied we got accepted, and I'm not sure what "contact" I was supposed to get from GeoTrust.  I did get an email response immediately after the application (within a few minutes) to confirm my contact info, but that was it.  All in all, a completely painless process.

Sunday, October 25, 2009 2:34:17 PM (Central Standard Time, UTC-06:00)  #     |