Fondest greetings, and welcome to the blog home of the Merlin Wizard Framework! In spite of some tangential posts, this blog will be geared toward getting you up and running with the slickest, simplest, and richest WinForms wizard framework for .NET. If you read the blog posts in chronological order, it may even read like a tutorial.

Tuesday, December 23, 2008

Maybes and What-ifs

In Merlin, we represent a wizard as a sequence of steps. Of course, a wizard isn't always a fully-defined sequence - sometimes the end user's input determines what step comes next or whether a step occurs at all. In this post we will investigate the simplest technique Merlin offers for dynamically determining whether a step occurs.

It's called a ConditionalStep, and as the name implies, it occurs only if some condition is true. Creating a ConditionalStep is easier than gaining weight on a cruise ship:

var conditionalStep = new ConditionalStep(condition, actual step);

The condition above is a boolean delegate. The actual step is another step. If (and only if, for the mathematical purists) condition is true, actual step occurs. If the condition is false, we skip on down to the next step. This implies, of course, that a conditional step cannot be the last step in the step sequence. If you try to give such a sequence to the wizard controller, it will throw a ConditionalStepAtEndException.

I put a small demo together to show off this functionality. You can get the complete code here, but here's the gist: For our first step, we have a simple form (shown below). If the user clicks next, she goes straight to our farewell message. But, if the user checks the "Show Advanced Options" checkbox, she gets to enter some more data, and then sees the farewell message.

image 

And here's the code that makes all this magic possible:

var steps = new List<IStep>();
var simpleEntryUI = new SimpleEntryUI();
var simpleEntryStep = new TemplateStep(simpleEntryUI, "User Information");
var advancedEntryStep =
    new TemplateStep(new AdvancedEntryUI(), "Advanced User Information");
steps.Add(simpleEntryStep);
steps.Add(new ConditionalStep(
    () => { return simpleEntryUI.ShowAdvancedOptions; },
    advancedEntryStep));


Label farewellMessage = new Label();
farewellMessage.Text = "Well, done. Bye, now!";
steps.Add(new TemplateStep(farewellMessage, 10, "Goodbye!"));
new WizardController(steps).StartWizard("User Data Wizard");

When the wizard runs, the condition does not get evaluated until the controller reaches the conditional step, which allows you to use data from previous steps in your conditions. That data will be available by the time the condition gets evaluated.

If you put a breakpoint inside the condition, you will also notice that the condition does not get evaluated on the way back. In other words, if skip down to the farewell message and click the "back" button, the condition will not be evaluated to determine whether or not you see the advanced data step. Instead, the result of the last condition evaluation will be used. But, if you go backward through a conditional step and then go forward again, the condition will be reevaluated. So to summarize: conditions are evaluated only when the conditional step is reached by clicking the "next" button.

No comments:

Post a Comment