Sunday, January 18, 2009

Why create your own wizard when there’s Merlin? The Merlin Framework Wizard v1.0 released

CodeProjectMerlin Wizard Framework

merlinCPlogo

A framework for easily making wizards in .NET. Originally developed by IONA Technologies for its Artix Connect for WCF product, Merlin provides a delicate blend of power and simplicity for all your wizard-making needs.

Merlin Wizard Framework (tm) is released under the Apache 2.0 License. Check out our blog for the latest news and tutorials.

…”

Merlin Wizard Framework - 1.0.0

“…

Step Library API Reference.zip
documentation, 351K, uploaded Today

Merlin1.0.0.zip
application, 75K, uploaded Today

Release Notes

An easy and painless way to make wizards in your winforms applications. A clean yet flexible API, no messy artifacts, and getting started is a snap.

…”

How many “wizards” have we written? How many times do we re-invent this same wheel? Yeah, too many. And every time it seems we think, “We should create a framework for this…”

If this sounds familiar then The Merlin Wizard Framework maybe just what you were looking for.

Using a simple API, you construct your wizard in code, adding validation, conditional steps as you need them. Draggie-Droppy, no WinForm gymnastics, just code.

Below is from the included demo. The code is all that’s needed to create a four form wizard (snapped below the class).

namespace NilremUserManagement.CustomSteps
{
static class NewUserWizard
{
delegate bool AnswerValidation(string answer);
public static User RunNewUserWizard()
{
//Create a list of steps
List<IStep> steps = new List<IStep>();
User newUser = new User();

//Step 1. Welcome message
TextBox t = new TextBox();
t.Multiline = true;
t.ScrollBars = ScrollBars.Vertical;
t.ReadOnly = true;
t.Text = Resources.WelcomeMessage;
t.Select(0, 0);
steps.Add(new TemplateStep(t, 10, "Welcome"));

//Step 2. Role selection
var roleStep = new SelectionStep("Role Selection", "Please select the user's role:",
Enum.GetNames(typeof(User.UserRole)));
roleStep.NextHandler = () =>
{
newUser.Role = (User.UserRole)Enum.Parse(typeof(User.UserRole), roleStep.Selected as string);
return true;
};
steps.Add(roleStep);

//Step 2. Role selection
var userFormStep = new TextFormStep("User Details");
userFormStep.Prompt = "Please provide the following user information:";
var userIdQuestion = userFormStep.AddQuestion("User &ID:", Validation.NonEmpty);
var fullNameQuestion = userFormStep.AddQuestion("Full &Name:", Validation.NonEmpty);
var passwordQuestion = userFormStep.AddQuestion("&Password (6 or more characters):",
Validation.MinLength(6), '*');
var passwordQuestionRetype = userFormStep.AddQuestion("&Retype Password:",
Validation.MinLength(6), '*');
var emailAddressQuestion = userFormStep.AddQuestion("&E-Mail address:", Validation.NonEmpty);
steps.Add(userFormStep);
userFormStep.NextHandler = () =>
{
if (!passwordQuestion.Answer.Equals(passwordQuestionRetype.Answer))
{
MessageBox.Show("The password does not match the retyped password.",
Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return false;
}
newUser.FullName = fullNameQuestion.Answer;
newUser.Email = emailAddressQuestion.Answer;
newUser.Password = passwordQuestion.Answer;
newUser.UserId = userIdQuestion.Answer;
return true;
};

//Step 3. Picture Selection step. This step features the selection of a file.
var pictureSelectionStep = new FileSelectionStep("User picture selection", "Please provide a picture for this user.");
pictureSelectionStep.Filter = "Images|*.bmp;*.jpg;*.gif;*.tif;*.png|All Files (*.*)|*.*";
pictureSelectionStep.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
pictureSelectionStep.NextHandler = () =>
{
if (File.Exists(pictureSelectionStep.SelectedFullPath))
{
newUser.Picture = Image.FromFile(pictureSelectionStep.SelectedFullPath);
return true;
}
else
{
MessageBox.Show("Selected image does not exist", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return false;
}
};
pictureSelectionStep.AllowNextStrategy =
() => !string.IsNullOrEmpty(pictureSelectionStep.SelectedFullPath);
steps.Add(pictureSelectionStep);

//Step 4. Preview step. This step features a custom UI implemented separately.
steps.Add(new CustomSteps.PreviewStep(newUser));

//Run the wizard with the steps defined above
WizardController wizardController = new WizardController(steps);
wizardController.LogoImage = Resources.NerlimWizardHeader;
var wizardResult = wizardController.StartWizard("New User");

//If the user clicked "Cancel", don't add the user
if (wizardResult == WizardController.WizardResult.Cancel)
{
newUser = null;
}

return newUser;
}

}
}
image 
image 
image 
image 
image 
 

4 comments:

Anonymous said...

how did you publish c# code in color syntax like visual studio format.
could you share that technique with me.

Greg said...

I used the Paste from Visual Studio (VSPaste) addin for Windows Live Writer.

Windows Gallery entry for VSPaste
Windows Live Writer

I hope this helps,
Greg

Anonymous said...

Greg:

What a godsend! I don't know what I'd do without your blog. This is great.

Yev and the rest of the Merlin dev team have put out a great product, and they are quite responsive to their community. If only every OS project would have its own "blog-torial."

Keep up the good work, Greg, and thank again.
-Scott

Greg said...

@Scott,
Thanks... :)