Latest Articles

Using Windows in WPF

{ No Comment }

On our Manning book forum, I received a question from trifonius regarding the use of multiple windows in WPF:

First of all, I'd like to compliment the authors with the book. It's a great read, thorough explanations and clear examples.

I'm working on an application that needs to be able to edit data as well as showing reports on data. Since these two interfaces are very different I think I need multiple windows in this app, available from a menu or something.
Since there is no mention in the book of multiple windows, I wonder whether this is the recommended way to go. Is it advisable to use panels with controls and set their visibility (or something like that) instead? Seems like a bit of a hassle to me.

If it is fine to use multiple windows, how can I display them from selecting a menu item?

Thanks

Thank you for the compliments! It's great to hear that our work is proving to be beneficial. It's the result of a lot of blood, sweat, and tears, and mostly blood... :)

It's fine to use multiple windows in a WPF application. For various reasons we had to cut some material, including drag and drop and multiple windows, but that should not be interpreted as a recommendation against them. It's true that some people are very adamant about not having multiple windows, but it really comes down to what problem you are trying to solve, who are your users, and what your application does.

Working in a single window was a limitation of web development for a long time, and it forced web developers to think of new approaches to solve problems typically addressed by windowing operating systems. This resulted in some very nice UI approaches, but also resulted in what I see as an over-correction where a group of those people came to view windowing in general as "evil." One of the more effective counter arguments comes from multiple monitor configurations.

I have used multiple monitors for years, and found the productivity of having 2 or more screens is unquestionable. An application that does not allow you to open multiple windows is fundamentally incapable of taking advantage of such a configuration, so if you have anything in your application that might be able to make better use of monitor real estate, definitely look here. Think about the XAML Designer itself in Visual Studio. If you have two monitors, wouldn't it be great to open the XAML window on one monitor, and the full design surface on another? You can't now, but this strikes me as a major omission. (The poor man's approach is to split the designer and xaml vertically, then stretch the window across both monitors and you get nearly the right effect).

That's enough pontificating (for now) so on to your question...

On the context menu of your WPF Application project, you can select "Add/Window..." to create the Window XAML and code. For the sake of this example, I created a new project and left the Window1, and created a new Window called "DataEditWindow"

Add a CommandBinding and a both a Button and MenuItem to demonstrate the call:

    <Grid>
        <Grid.CommandBindings>
            <CommandBinding x:Name="new"
        Command="ApplicationCommands.New"
        CanExecute="new_CanExecute"
        Executed="new_Executed" />
        </Grid.CommandBindings>
        <StackPanel>
            <Menu>
                <MenuItem Header="_File">
                    <MenuItem
                       Command="ApplicationCommands.New"
                       Header="_New"/>
                </MenuItem>
            </Menu>
            <Button Width="80" Height="23"
        Command="ApplicationCommands.New">New</Button>
        </StackPanel>
    </Grid>

In the cs file, a couple special notes apply:

If you want to give the new window a particular DataContext for binding, you can set it here. Also, the Window should know who its parent is, so always set the Owner property to the Window you are launching from. In this example I'm binding to the ApplicationCommands.New command, but you could just as easily bind it to a control event or RoutedEvent (I tend to recommend thinking and binding in terms of commands):

private void new_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
    e.CanExecute = true;
}

private void new_Executed(object sender, ExecutedRoutedEventArgs e)
{
    var window = new DataEditWindow()
        {
            DataContext = DataContext,
            Owner = this,
        };
    bool? result = window.ShowDialog();
    if (result.HasValue && result.Value)
    MessageBox.Show("Ok clicked");
    else if (result.HasValue && !result.Value)
    MessageBox.Show("Cancel clicked");

    //window.Show(); // Show window, but do not wait
}

The next bit is a choice. If you want the window to be model and block all operations in the parent window (a print dialog is a good example where modal makes sense), then use the window.ShowDialog() method. If the window is more of a palette and you want to allow the user to be able to continue using the application, use the window.Show() method. Too many modal windows can be frustrating, but attempting to handle state changes can also hurt.

Since window.Show() is the simple case, this is what you'll need to add to the child window for handling the DialogResult. In the XAML, we'll need some buttons to let the user indicate their intent with the dialog:

DataEditWindow.xaml:

    <Grid>
        <StackPanel>
            <Button x:Name="Ok" Click="Ok_Click">Ok</Button>
            <Button x:Name="Cancel" Click="Cancel_Click">Cancel</Button>
        </StackPanel>
    </Grid>

Then you will need to set the DialogResult before you close the window so that the caller can decide what to do. This way, the parent window can decide whether to take the action or not. Note that you will get an exception if you try to set DialogResult, but the window was opened with window.Show(), so if you want this window to be dual purpose, you will have to handle both cases.

DataEditWindow.cs:

private void Ok_Click(object sender, RoutedEventArgs e)
{
    DialogResult = true;
    Close();
}

private void Cancel_Click(object sender, RoutedEventArgs e)
{
    DialogResult = false;
    Close();
}

In an application I would tend towards the approach of creating a DataTemplate, and I would create a generic WPF Window class that is simple a ContentControl. Set the DataContext of the Window to the object you want to edit, and let the template system pull up the right template for the editor. Something like this:

<DockPanel>
    <StackPanel DockPanel.Dock="Bottom">
        <Button x:Name="Ok" Click="Ok_Click">Ok</Button>
        <Button x:Name="Cancel" Click="Cancel_Click">Cancel</Button>
    </StackPanel>
    <ContentControl Content="{Binding}">
    </ContentControl>
</DockPanel>

With this approach, you can choose to show the editor in-place or show it in a window with very few code changes.

Fine Tuning an LCD Monitor Connected to an Analog Port

{ Only 1 Comment }

Quite a while ago, I discovered the joys and productivity of using multiple monitors. On my current system, I have two identical Samsung 19" LCD monitors connected to an ATI Radeon 9800 Pro. Unfortunately, the video card only has a single DVI connector so my second monitor is hooked up through the analog SVGA port.

When I first hooked it up, I couldn't get over how bad the monitor looked when it was hooked to the analog port. I knew it would be worse, but it looked defective, or as if the resolution was not set to the native LCD resolution. Also, I love ClearType, but on the monitor connected via SVGA it looked horrible no matter how much I used the ClearType tuner.

This is what I learned...

For a while, I just hit auto adjust when things looked particularly poor. It usually helped a bit, but invariably the poor quality would show up again in spades in some other context, and it never helped a lot. At one point, I hit auto adjust when the only thing displayed on the monitor was a solid blue background. The next time I dragged a window across, it looked like a car hit my screen. That's when I suspected the feature was relying on feedback from the signal generated by the image to adjust itself correctly.

With my newfound realization, I started hunting for an image complex enough to give the electronics something difficult to chew on. My first attempt was to see if the old Windows 3.1 desktop patterns survived through Windows XP. The black and white checkerboard gray-scale seemed like an ideal pattern to help the monitor adjust itself. No dice, Microsoft finally put a stake through that particular feature after Windows 2000.

So I put together this quick little utility to assist my monitor with its auto adjusting woes. All it does is set various background patterns to display on the monitor to adjust. I am happy to say that by using the white and black pixel checkerboard pattern, the result of the auto-adjust function on my Samsung 930B resulted in an image rivaling the DVI connected 930B. ClearType looks beautiful, there are no more strange shimmering or jittering effects, and I can be productive on both of my monitors again!

Just to make sure I wasn't imagining things, I pressed the auto adjust button on the monitor with a solid blue background again. When I dragged the checkerboard window across, it looked horrendous and ClearType was in a shambles. Now I hit the auto adjust with the checkerboard up, and watched as the monitor figured out how to display it perfectly again.

I've attached the utility as well as the source code. It is mind-numbingly trivial, but I've already thought of more patterns (and color patterns) to add based on what I learned about LCD technology. Right now I am just using some embedded resources and tiling the image...

Usage is pretty straight-forward:

  1. Run the program
  2. Maximize the window on the LCD monitor to adjust (connected to an analog port)
  3. The checkboard pattern should be all you need, but I added a couple other patterns via context menu

m

Video Patterns
Video Patterns Source Code

Exception Handling 101

{ No Comment }

I hate buggy software. However, as a developer, I know how difficult it is to write bug-free software and so I am always looking for new ways to learn how to write better software. One of those ways is exception based programming. Sadly, exceptions are often glossed over in samples and books so exception anti-patterns tend to propagate.

Take a look at the following code...

public void HorrifyingMethod()
{
    try
    {
        Cursor preCursor = Cursor.Current;
        Cursor.Current = Cursors.WaitCursor;
        DoSomething();
        DoSomethingElse();
        try
        {
            Log.Write("I did something");
        }
        catch {}
        Cursor.Current = preCursor;
    }
    catch (Exception ex)
    {
        if (ex.Message == "Failed")
            throw ex;
        else
            Log("Something failed", ex);
    }
}

There's so much wrong with this method it makes my skin crawl. Let's start with the obvious:

Catching the base exception type
There aren't a lot of cases where this is ever justified. When you catch an exception, you are effectively stating that you understand the nature of the failure, and you are going to resolve the problem (logging, by the way, is not resolving the problem). Our nested try/catch block may as well say "if the server caught fire, I'm just going to ignore it." When you write an exception method, it is helpful to say to yourself, "The managed runtime exploded, therefore I am ..." and say what your catch block does. If you find yourself saying something like "The managed runtime exploded, therefore I am returning the default value" you can see how problematic this really is.

Discriminating on exception data rather than exception type
Exceptions should describe the nature of the problem, not where it came from. Every exception already comes with a stack trace so we know where it came from. A good exception is something like "TimeoutException" rather than "MailComponentException" If you find yourself commonly digging through exceptions to determine what exactly went wrong, you are using a poorly designed library. If you are throwing exceptions, use an existing exception class if it fits the problem, or write a new class that describes the problem. The exception type itself is the filter used for catching, so it's important for exceptions to describe the nature of the failure.

Re-throwing a caught exception from a new catch block
There are times when you might catch an exception, and after doing some programmatic investigation decide that you can't actually handle it and you need to rethrow it. Never rethrow the same instance that you caught in the catch or you'll wipe out your stack. The correct way to rethrow a caught exception is just a single "throw;" statement with no variable.

public void CorrectRethrow()
{
    try
    {
        SomeMethod();
    }
    catch(Exception ex)
    {
        if (!ex.SomeProperty)
            throw;
    }
}

Eating the exception
This is probably by far one of the worst offenders. Exceptions work well because they are an opt-out method of detecting abnormalities rather than past "opt-in" methods such as errorcodes. Eating exceptions is rarely correct. If you are developing a library for use by other developers, you should not be making decisions for them with regard to exceptions. Always throw the exception to the library user so that she can handle it as she sees fit. The HorrifyingMethod() code shows two exception eating problems: The inner try/catch block is catching both managed and unmanaged exceptions, and completely hiding the fact that anything went wrong. This is all too common, and contributes to bugs, failures, and strange side-effects with nearly impossible to trace causes. The outer block logs the exception, making a token gesture of "handling" it. Imagine this method being called from a button click event. The user keep smashing the button, the program continues to fail to execute the procedure, and somewhere an obscure log file is recording all the detail. Logging an exception is not handling it.

(Note that if you do have more than one try/catch/finally in a method, your design is probably screaming for an ExtractMethod refactoring. Your method is almost certainly too large if there is a need for more than one)

Lack of a finally block to ensure consistency of changes in the method
There should be far more try/finally blocks in your code than try/catch blocks. In order to write exception-safe code, anything in a try block must be reverted by a finally block to leave the application in a consistent state. When an exception was thrown in Visio, it would bring up a dialog box saying that the application state was inconsistent and advised you to restart the application. This is decidedly not okay in the .NET world.

Eye Nutrition

{ No Comment }

A few years ago, I got a Mac. It started when I read about Apple jettisoning their entire operating system core and starting over with the UNIX-based NeXT operating system. Every day after work, I stopped by CompUSA and just explored all the OS X systems there. This all happened in late 2002 and, at the time, there was just nothing that looked anything like OS X... it was just incredibly gorgeous. When Apple announced Jaguar, I decided to jump on the train and buy an iBook. It was relatively inexpensive, and a good way to step into the world of OS X.

Today I am using Vista, Ubuntu, and deeply exploring the depths of WPF, and the unique shine of OS X doesn't seem as unique anymore. Now that everyone has pretty well jumped on the "eye candy" bandwagon, I've been doing a lot of thinking and observing how much many of them are missing the point.

The thing that Apple did so well with OS X aesthetically was to use the full power of the hardware and software to create a beautiful and usable system. There are many subtle hints in OS X that employ alpha channels, stencils, and color to great effect, but I don't call it eye candy. In most cases, it's eye nutrition. For example, look at the search of the System Preferences in Tiger. Immediately it not only lists the relevant results, but through visual design, you get even more immediate feedback on where you might be most interested to look.

OS X showing some eye nutrition in a System Preferences search

OS X showing some eye nutrition in a System Preferences search

The use of an alpha channel in this way really helps improve the usability, and communicates with the user. Of course, the typical use of an alpha channel in most systems is to make semi-transparent, difficult to read windows.

OS X also uses the alpha channel to display a shadow under each window. The top-most window has the deepest shadow and provides an instant visual cue to the user about the arrangement of the windows on the screen.

None of this is to say that OS X doesn't have eye candy as well, but it's a lot sweeter when there's nutrition to go with it.

Agile Development for Commercial Software

{ No Comment }

My development experience has primarily been in commercial software. As such, I am quick to recognize that some aspects of agile methodologies aren't always practical for commercial software development, nor were they designed with commercial developers in mind. For example, sitting with the customer you have not yet won is not really practical (or even possible, unless you happen to know the Doctor). and the ability to freely modify and refactor published interfaces is greatly reduced without significant customer impact.

In fact, commercial software must often be written "on spec" prior to winning any customers, and may in fact be written in secret to avoid the possibility of larger competitors with a greater ability to execute from implementing your own product ideas before you have a chance to get them to market. Therefore, some agile cookbooks aren't going to work for you, but that does not mean agility isn't desirable or appropriate. Another problem with specific agile methodologies is that they are very geared toward the internal IT developer. This isn't an unreasonable perspective as well over 90% of software development is internal, but again, this won't necessarily address the needs of commercial software shops.

In addition, most commercial ISVs have a greater need for a predictable software releases. While a missed internal deployment can certainly cost money, a missed commercial deployment involving marketing, sales, partners, and competitors can call the future of a small commercial ISV into question. I have personally found a mutilated mix of waterfall, spiral, and cowboy coding in commercial software companies, and often with a culture of heroism.

Regardless of what specific agile methodology you look at, fundamentally they are all based on the same idea: Embrace Change. By "embrace change" I don't mean "deal with change" with emergency design sessions and marathon coding sessions, or "cope with change" by padding estimates, or "ignore change" because you've got some heroic developers to save you. Change comes from many places: software or framework limitations, requirements, leadership, competitors, coworkers, design constraints, and so on. Arguably, commercial software is even more subject to change than internal projects, so there is a lot of benefit to be gained from greater agility.

Unfortunately, and with a few exceptions, internal IT development is generally the focus for both research and practice in agile methodologies. Commercial software companies are on their own in figuring out the best way to take advantage of recent agile practices. Commercial software can definitely benefit from agile development, but it will take a lot more effort and understanding to balance the constraints of commercial software with the tenants of agile development.

Cargo Cult Agile

{ No Comment }

I first came across the phrase "Cargo Cult" in the book Surely You're Joking, Mr. Feynman! by Richard Feynman. In the book, Feynman warned researchers against fooling themselves and thus becoming cargo cult researchers. The term is from a 1974 commencement address given by Feynman where he talks about learning not to fool yourself, because you are the easiest person to fool.

What is a cargo cult?

The cargo cults Feynman described were based on natives from the islands of Melanesia in the South Pacific. During the war, the islands of Melanesia served as a staging area for the military where they built temporary operations. The natives observed all the ways in which the allied forces landed the planes and learned the techniques. After the war, the planes stopped landing and the cargo disappeared. The cults decided that they must perform the allied rituals of landing planes and bringing out the cargo, and so they built runways, control towers, bamboo "headsets" and military uniforms.

Apparently they have learned the "rituals" very well, and continue to perform them in the hopes of bringing back more planes full of bountiful cargo. Unfortunately, no matter how well they duplicate the ritual, there is no result.

Waterfall: The Worst Cargo Cult

As I wrote this post, I realized that the Waterfall process is actually the worst cargo cult of all. Waterfall software projects fail at astounding rates, and we still create our gantt charts and do our huge designs up front, and wonder why the planes aren't landing or why a simple project costs tens if not hundreds of millions of dollars to complete.

Asked for the chief reasons project success rates have improved, Standish Chairman Jim Johnson says, “The primary reason is the projects have gotten a lot smaller. Doing projects with iterative processing as opposed to the waterfall method, which called for all project requirements to be defined up front, is a major step forward.”

In 1970, W.W. Royce described a software development model in which each phase of the development process sequentially follows one another, and in the end results in a finished product. In this article, often cited by waterfall proponents, Royce points out that this "grandiose" model is prone to failure and recommends instead an iterative "feedback" model. Unfortunately this is the worst software process cargo cult of all because it never actually had anything to back it up as being a successful approach. The waterfall cultists stopped reading before they got to the conclusion.

In an ironic twist, about the time waterfall was losing popularity, the US military created a software development methodology called DOD-STD-2167 which not only reintroduced the otherwise failing software development methodology into widespread use, but lent it renewed credibility. I guess the natives weren't the only ones easily fooled into hopeless ritual destined to failure. Somewhere some cargo cultists are laughing.

Unfortunately, cargo cults tend to yield to more cargo cults.

What does a cargo cult agile shop look like?

From the outside, it may look a lot like an actual agile shop. After all, a cargo cult shop is imitating what they have seen about agile. However, like waterfall proponents, cargo cult agile shops are led by people who have looked at pictures of agile models, "read" agile books, or "learned" agile development from PowerPoint presentations. Perhaps there are a number of developers who know agile, but they may not be able to move the company towards agility in the face of generations of managers and developers who have been indoctrinated by DoD-2167.

By definition, agility describes an ability to respond to changes. As such, any agile process is going to have some sort of iterative process in which the software is improved and responds to any changes that have occurred during development. In a cargo cult shop, keep a particular eye out for iterations that don't include tasks other than programming. If the details of analysis, design, and testing are excluded, you are probably looking at a "cowboy" project or a waterfall project in disguise. An iteration should always include or consider changes. While possible, it is unlikely that the project will remain completely unchanged after an iteration.

With any agile process, the speed and effectiveness of adapting to change is the primary measure of how agile your team has become. If you are using an effective agile process, responding to change should be graceful. If a change causes a lot of disruption, or re-visiting a line of code that someone has already typed causes alarms to go off, you may be in a cargo cult.

If you are looking at a potential agile company, look at their process in as much detail as they will allow during the interview. If they use XP, ask to look at story cards. Do their unit tests actually test the functionality, or are they a check box to get past a sign-off? Are the story cards simply a requirements document created in one big design up front or do they add, change, and remove cards as they get further into the project. On a scrum project, ask how long a typical scrum meeting lasts. If their idea of a daily scrum is two hours, run, don't walk, to your next interview because they have missed the point entirely.

If you are already in a cargo cult agile shop challenge your process. Good agile process encourages a constant feedback loop regarding both your product and your process. If an agile process isn't working look into why and fix it. Go past the powerpoint presentations and the diagrams. Reproduce the results that created the processes you are attempting to emulate. If the agile process is printed and bound, and they haven't made a single change to it in five years, it is highly likely they have not challenged and enhanced their process to fit their people.

Some agile models are a toolkit and give guidance on how to effectively use them, while other methodologies require practices to be used together to achieve a result. Some practices stand on their own while others may be interdependent. Understand the benefits and consequences of cherry picking from agile, especially if you are doing a project waterfall style.

Agile as a Cult

I am a fan of agile development in general because the Agile movement formally questioned and rejected the dogma of how software development should be done and, in particular, challenged the continuously failing waterfall model. Agile is just a step along the way and isn't without fault and dogma itself. We sorely need to keep moving towards improving our understanding of successful software development.

Post-agilism is starting to take hold with a tempered view, absent much of the hype and absolutism that has formed in some Agile communities. I look forward to the thoughts of these people who refuse to be constrained by dogma and continually challenge how we write software. It is this sort of skepticism that I think Feynman is looking for when he says we must not fool ourselves.

Related links:


Cargo Cult Science

The Cargo Cults

Scott Ambler

Agile Alliance

Post-Agilism: Process Skepticism

Don’t draw diagrams of wrong practices - or: Why people still believe in the Waterfall model

There's no such thing as the Waterfall Approach! (and there never was)


m