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.

Sunday, January 18, 2009

Step Sequence Manipulation

Putting aside the unrelenting bliss over the 1.0 release (and my propensity for exaggerating it), it’s time to lay down some more Merlin features. Specifically, we’re going to cover manipulating the step sequence when the wizard is already running.

Here’s how that works:

Somewhere in a step (generally in the NextHandler), you would access the wizard controller and call one or more of the following methods on it:

  • public void AddAfterCurrent(IStep step);
    Adds the specified step immediately after the current step. After the new step executes, the step that originally followed the current step will execute. 
    stepadd
  • public void AddAfterCurrent(IEnumerable<IStep> steps);
    Adds all the steps in the argument immediately after the current step. After all the new steps execute, the step that originally followed the current step will execute. 
    multiplestepadd
  • void DeleteAllAfterCurrent();
    Deletes all steps that follow the current step.
    delete

There are two blatant pitfalls possible here:

  • If a current step has a “Next” button (i.e. it’s not the last in a sequence), but then you delete all the steps that follow, the user will click Next and “run off the end” of the wizard. The wizard will just close, and the Wizard Controller will consider the wizard successfully completed.

  • If the current step is the last one, it will appear with a “Finish” button. If you dynamically add steps afterward, the user will be surprised that clicking the “Finish” button actually leads to more steps. To avoid this phenomenon, just place a dummy step after the first one, so that the first step appears with a “Next” button. Then, you can use DeleteAllAfterCurrent() to delete the placeholder step prior to adding new steps.
  • To see these features in action, check out our step sequence manipulation demo. In this demo, the user chooses a fruit type (apples or oranges), and the subsequent steps are determined by which fruit type the user has chosen.

    Bon app├ętit!

We're 1.0!

Pop the champagne, folks! But first, head on down to the downloads page, and grab yourself a sizzling-hot cup of Merlin magic.

As always, we'd love to hear your comments or suggestions either in the blog comments or in our forum on Codeplex.

Saturday, January 17, 2009

Step Library! Part 2.

The last step in the step library for the 1.0 release is a simple text form. Merlin is all about getting you through your wizard creation quickly, so we wanted to give you a way to get text input from the user without needing build your own controls. Of course, if you do need more flexibility than the text form offers, the option to build your own UI is still there.

Ok, here’s a 5-second text form:

var textFormStep = new TextFormStep("Additional Information", 
    "Please answer the following questions:", "Name:", "Age:", "Hobby:");

Once the wizard controller executes this step, here's what we see:

textformSimple

After this step has run, the textFormStep.Answers property will return an IEnumerable<string> containing the answers in the order in which their respective questions were specified in the constructor. Here’s another way of defining exactly the same form:

var textFormStep = new TextFormStep("Additional Information",
    "Please answer the following questions");
var nameQuestion = textFormStep.AddQuestion("Name:");
var ageQuestion = textFormStep.AddQuestion("Age:");
var hobbyQuestion = textFormStep.AddQuestion("Hobby");

There are two advantages to this approach: one is that it allows me to retrieve the answers without going through an enumeration and remembering the question order. I can just do:

MessageBox.Show("Your age is: " + ageQuestion.Answer);

The second advantage for the longhand approach is that it allows you to provide some additional options. Have you noticed how the “Finish” button appears in the above wizard even though we haven’t typed anything? We’d probably want to impose some minimal validity criteria before we’re allowed to move on:

var nameQuestion = textFormStep.AddQuestion("Name:",
    Validation.MinLength(3));
var ageQuestion = textFormStep.AddQuestion("Age:", Validation.NonEmpty);

Now, the “Next/Finish” button will not be enabled until at least 3 characters have been typed into the “Name” field and the “Age” field is non-empty. There are more validations available, and you can always plug in your own delegate/lambda expression that takes a string and returns a bool.

If you want to ask for a password, you can just as easily use a password masking character:

var hobbyQuestion = textFormStep.AddQuestion("Password:", 
     Validation.Length(6, 12), '*');

Disclaimer: this UI provides no more password security than a ye olde winform with a textbox.

And last but not least, you may want to pre-populate the textbox with a default answer or a previously-specified value. Easier done than said:

var nameQuestion = textFormStep.AddQuestion("Name:");            nameQuestion.Answer = "Merlin";

Now, “Merlin” will appear in the “Name:” textbox when this step is executed.

Oh, and one really last thing: if your questions are of very uneven length, the textboxes can appear quite far away from the text of the shorter questions:

textformdemo

If you’d like all the textboxes to start right next to their respective labels, just set the step’s LineUpQuestions property to false (it’s true by default). Then, your question will appear like this:

textd2

‘Till next time!

Step Library!

Fondest greetings to all. The 1.0 release is microscopically-near, and you can already savor its features in the latest release candidate. And among these oh-so-savory features is the new step library! In the previous entries, we covered creating steps from your own Controls. But some kinds of steps are so common, we’ve pre-built them for you. For example, choosing one option out of several:

SelectionStep

This step took all of one line of code to create (highlighted below):

var steps = new List<IStep>();
var choiceStep = new SelectionStep("Color choice",
"Please pick a color", "Red", "Blue", "Green", "Turqoise");

steps.Add(choiceStep);
new WizardController(steps).StartWizard("Hello");
MessageBox.Show((string)choiceStep.Selected);

Once the step has run, you can retrieve the selection via the Selected property.

Next up on our step library hit parade is the file selection step. Patently simple: often you need the user to select a file. This step will do that:

FileSelectionStep

The code to create this step:

var fileStep = new FileSelectionStep("License",
"Please provide your license file");
fileStep.Filter = "License Files (.lnc)|*.lnc";

After the step has run, fileStep.SelectedFullPath will return the full path of the selected file.

There’s one more step to cover, but I’ll save it for the next entry. Let me just add that the examples above do not cover every feature and tweak of these steps. We’ll post the complete API reference somewhere after 1.0 is out the door.