Thunderclap, the Newsletter of Rolling
Thunder Computing
Volume 8, Number 2, Winter 2007
In this issue:
Public Training Class on Composite UI Application Block and Smart Client
Software Factory in Boston on March 6-9
Feature Article: Establishing Order in Shared User Interface Negotiation in CAB Applications
New Book from David Platt: Why Software Sucks (and What You can Do About It)
Blatant Self-Promotion: New in-house class on Composite UI Application Block and SC-SF
The last two articles in this newsletter have dealt with the Composite UI Application Block and its Smart Client Software Factory. I've been teaching so much in that arena lately that I'm going to continue the trend in this article, discussing a problem that crops up in essentially every class that I teach.
CAB contains a mechanism for sharing a composite application's main user interface elements, such as the menu, toolbar, and status bar, among the various work items that get loaded in a CAB application. A user interface negotiation process takes place, conceptually similar to the one that happens in object linking and embedding when an embedded object undergoes in place activation. The mechanisms are different, and the fact that CAB allows multiple work items to be running at the same time, whereas OLE allows only one in-place active object at a time makes for even greater differences in the details, but conceptually it's the same thing. In the application below, the shell owns all of the menu, toolbar, and status bar items except for those labeled as belonging to a subordinate work item. This article assumes (more accurately, requires) that you be familiar with CAB's basic user interface negotiation process.
A UIExtensionSite doesn't allow extension items to be poked into any arbitrary location on the extendable UI object. It only allows items to be appended, tacked onto the end of the object (the right-hand end of the toolbar, the bottom of the popup menu or the right side of the main menu, etc.). This means that the order in which items are added to the shared UI, the order in which the different work items add and remove their items, controls the position in which those items are displayed. And the loose coupling of CAB means that different modules may be loaded in different use case scenarios.
For the sake of having a consistent user interface, it is necessary to ensure that different modules and work items extend the user interface in the desired order. If module A loads before module B in one scenario, and user interface extension is done automatically in the Run method as is most often done, then Module A's menu items will be shown to the left of Module B's, as shown in the left-hand picture below. However, suppose a different configuration leads Module B to be loaded before Module A. Now B's menu items are shown to the left of A's, as in the right-hand picture below. The user will get very confused if his menu starts jumping around in front of his eyes. Even if it doesn't happen dynamically at runtime, but only at load time in response to configuration settings, administration and documentation and training and testing will get blown to hell if A's menu appears to the left of B's in some configurations and to the right of B's in others.
There needs to be some way of enforcing standardization on the final user interface. Since the UIExtensionSite allows this only by modifying the order in which the user interface items are extended, there must be some way of centrally enforcing this order. We could, of course, specify the load order of the modules using the DependentModuleLoaderService provided by SC-CF. But our app might easily have some reason not related to the user interface why modules needed to load in a certain order, perhaps related to security, and it would be better not to have the user interface dictate the load order. How can we solve this problem?
The easiest way that I can think of to enforce a user interface modification order is through CAB's loosely coupled event mechanism, as shown in the code samples below. You can download and examine the sample code at this link. The shell, which is the main orchestrator of the user interface extension dance, publishes an event called AddUserInterfaceExtensions. The EventArgs parameter of this event contains a string which specifies the name of the module that is to perform its extension. The shell fires the event once for each listener that it is expecting, in the order in which it wants the extensions to take place. Here's the code for firing the event, in response to the user clicking the Add button on the toolbar. The string passed in the EventArgs is whatever the user types into the text box, also on the toolbar. The sample application contains work items that respond to the string names "A" and "B". Thus:
private void toolStripButton1_Click(object sender, EventArgs e)// Fetch the EventTopic with the name "AddUserInterfaceExtensions"
EventTopic et =
_RootWorkItem.EventTopics[EventTopicNames.AddUserInterfaceExtensions];
// Fire the event. This tells the subscriber work item whose name matches
// the provided string to add its extensions to the shared
user interface
et.Fire(this,
new
EventArgs<string>(this.toolStripTextBox1.Text),
this._RootWorkItem,
PublicationScope.Global);
}
Each work item that wants to extend the user interface will subscribe to that event. When it receives the event notification, it checks the EventArgs, looking for its own name. When it finds its name, it modifies the user interface. The code can live anywhere it wants, but this particular example I put in the work item's controller class. Thus:
[
EventSubscription(EventTopicNames.AddUserInterfaceExtensions,
// Check to see if the name being told to extend the shared user
// interface is our name. If not, ignore the event.
if (eventArgs.Data ==
"A")
{
// The name matches. Perform our extensions of the shared UI.
MyOwnExtendMenu();
}
}
If you really wanted to get fancy and do dynamic changes during operations, you could publish another event such as RemoveUserInterfaceExtensions. If modules A and B had their extensions up and you wanted to add C in between them, you could fire the Remove event containing B's name, then the Add event for C, then the Add event for B again. But before you start whamming things around, sit down and ask yourself carefully, "What would make my users (not me) the happiest?" It's usually making simple things simple, and this might just be enough rope to hang yourself here.
If you'd like to learn more about CAB and SC-SF, I'm teaching a public class on it in Waltham MA on March 6-9, 2007. Or I can teach it in-house at your company, which you'd probably find cost-effective if you had five or more attendees. Information on both is online at this link,
Until next time, as Red Green would say, "Keep your stick on the ice."
Why Software Sucks (and What You Can Do About It)
ISBN 0-321-46675-6
Sample Chapter Online at www.whysoftwaresucks.com
It's finally out! Anyone whose spoken with me in the last couple of years probably got an earful about the latest bee in my bonnet, the book entitled Why Software Sucks. I’m sure that I’ve inflicted sample chapters on just about everyone I know.
It's gotten a storm of publicity, primarily from a Reuters wire service article that ran during the first week of the new year. It was picked up in the electronic editions of such publications as the such as the New York Times (http://www.nytimes.com/reuters/technology/tech-software-platt.html) , Fox News, (http://www.foxnews.com/story/0,2933,241578,00.html), and PC Magazine (http://www.pcmag.com/article2/0,1759,2078820,00.asp).
I've started a new blog based on it, at www.suckbusters.com . It's dedicated to the notion that software shouldn't suck. Instead, software should Just Work.
The title was originally my idea, but I also love the subtitle, suggested by my editor at A-W. I’ve always thought that the right subtitle can really make a book. Like the 60’s bestseller Everything You Always Wanted to Know About Sex (But Were Afraid to Ask). Or Werner von Braun’s autobiography, entitled I Aim for the Stars. Humorist Mort Sahl suggested that its subtitle ought to be, But Sometimes I Hit London. (If you don’t get that last one, go look up von Braun online. As Tom Lehrer famously sang about him in the sixties: “ … A man whose allegiance is ruled by expedience … ‘Once the rockets are up, who cares where they come down? That’s not my department,’ says Werner von Braun.”)
This is my first book aimed at end users, not programmers. Early returns from this market are highly positive. My barber, the librarian at my local public (dead tree edition) library, and the contractor who built my house, all report that early chapters are informative, entertaining, and easy to read.
I’m still working on the “what you can do about it,” piece. If you have any thought as to how ordinary users can make their voices heard, I’d like to hear them. Use the contact info link of this web site, if you don’t already have my email. Thanx.
Blatant Self Promotion: Would you buy a used car from this guy?
4-day In-House Training Class on Composite UI Application Block. Available In-House, or to the Public in Waltham MA, March 6-9
The CAB that I describe above is useful, but has a steeper learning curve than other parts of .NET. My in-house training class on it will get you up and spinning in no time. See the online syllabus here, then call me to schedule yours.
5-day In-House Training Class on .NET or .NET for Insurance
.NET is here, and it's hot. It changes everything in the software business, and you can't afford to be without it. Rolling Thunder Computing now offers in-house training classes on .NET, using my book as the text. See the syllabi online here, then call to schedule yours.
ACORD XML for Insurance In Depth, Including Web Services
Insurance carriers, learn ACORD XML from David Platt. This 5-day class will give you everything you need to know to jump-start your application development. Learn about security and plug-and-play, and combining ACORD XML with XML Web Services. See the syllabus online here. It can be customized to your needs.
And now, the moment for which I know you've all been waiting -- the pictures of my two girls. Lucy just turned four. She loves her preschool at Cape Ann Waldorf School. Here you see her holding our new cat, Marley, whom she also loves. You can also see that Annabelle, now 6 1/2, has had a visit from the tooth fair -- two visits, in fact. Remember the song "All I Want For Christmas Is My Two Front Teeth"? We got to live that this year. Remember her birth picture, which ran in this newsletter about 5 minutes ago?
Photographs by Ellen Spector Platt and David S Platt
Thunderclap is free, and is distributed via e-mail only. We never rent, sell or give away our mailing list, though occasionally we use it for our own promotions. To subscribe, jump to the Rolling Thunder Web site and fill in the subscription form.
Legal Notices
Thunderclap does not accept advertising; nor do we sell, rent, or give away our subscriber list. We will make every effort to keep the names of subscribers private; however, if served with a court order, we will sing like a whole flock of canaries. If this bothers you, don't subscribe.
Source code and binaries supplied via this newsletter are provided "as-is", with no warranty of functionality, reliability or suitability for any purpose.
This newsletter is Copyright © 2005 by Rolling Thunder Computing, Inc., Ipswich MA. It may be freely redistributed provided that it is redistributed in its entirety, and that absolutely no changes are made in any way, including the removal of these legal notices.
Thunderclap is a registered trademark ® of Rolling Thunder Computing, Inc., Ipswich MA. All other trademarks are owned by their respective companies.