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:

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

    ReplyDelete
  2. 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

    ReplyDelete
  3. 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

    ReplyDelete

NOTE: Anonymous Commenting has been turned off for a while... The comment spammers are just killing me...

ALL comments are moderated. I will review every comment before it will appear on the blog.

Your comment WILL NOT APPEAR UNTIL I approve it. This may take some hours...

I reserve, and will use, the right to not approve ANY comment for ANY reason. I will not usually, but if it's off topic, spam (or even close to spam-like), inflammatory, mean, etc, etc, well... then...

Please see my comment policy for more information if you are interested.

Thanks,
Greg

PS. I am proactively moderating comments. Your comment WILL NOT APPEAR UNTIL I approve it. This may take some hours...