using System;
using System.Collections;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;
public interface IWizardDialog {
Control NavigatePrevious { get; }
Control NavigateNext { get; }
Control NavigateFinish { get; }
Control UIRoot { get; }
bool Display { get; set; }
}
public interface IWizardPanel {
bool ShowNavigatePrevious { get; }
bool ShowNavigateNext { get; }
bool ShowNavigateFinish { get; }
}
public class WizardController : ApplicationContext {
private bool complete = false;
private int wizardIndex = -1;
private IWizardDialog wizardDialog = null;
private ArrayList wizardPanels = new ArrayList();
public WizardController() { }
public void SetDialog(Form dialog) {
IWizardDialog wDialog = dialog as IWizardDialog;
if ( wDialog != null ) {
if ( wDialog.NavigatePrevious == null ) {
throw new Exception("Wizard dialogs must have a Previous Button");
}
if ( wDialog.NavigateNext == null ) {
throw new Exception("Wizard dialogs must have a Next Button");
}
if ( wDialog.NavigateFinish == null ) {
throw new Exception("Wizard dialogs must have a Finish Button");
}
if ( wDialog.UIRoot == null ) {
throw new Exception("Wizard dialogs must have a non null UI Root");
}
} else {
throw new Exception("Wizard dialogs must support IWizardDialog");
}
wizardDialog = wDialog;
wizardDialog.NavigatePrevious.Click += new EventHandler(Wizard_NavigatePrevious);
wizardDialog.NavigateNext.Click += new EventHandler(Wizard_NavigateNext);
wizardDialog.NavigateFinish.Click += new EventHandler(Wizard_NavigateFinish);
// Last time we get a chance on the Form object
dialog.Closing += new CancelEventHandler(Wizard_Closing);
}
public void AddPanel(Panel pnl) {
IWizardPanel vPanel = pnl as IWizardPanel;
if ( vPanel == null ) {
throw new Exception("Wizard panels must support IWizardPanel");
}
wizardPanels.Add(vPanel);
}
public bool Complete {
get {
return complete;
}
}
public ArrayList Panels {
get {
return wizardPanels;
}
}
public void Wizard_Closing(object sender, CancelEventArgs e) {
MessageBox.Show("You must complete the wizard in order to exit.");
e.Cancel = true;
}
public void Wizard_NavigateFinish(object sender, EventArgs e) {
// this could be fired anywhere in case you have an opt out
// early button on any of your forms.
wizardDialog.UIRoot.Controls.Clear();
wizardDialog.Display = false;
complete = true;
ExitThread();
}
public void Wizard_NavigateNext(object sender, EventArgs e) {
wizardIndex++;
if ( wizardIndex == wizardPanels.Count ) {
Wizard_NavigateFinish(sender, e); // This shouldn't happen if your dialogs are correct
return;
}
Panel newPanel = wizardPanels[wizardIndex] as Panel;
if ( newPanel != null ) {
InitPanel(newPanel);
}
}
public void Wizard_NavigatePrevious(object sender, EventArgs e) {
if ( wizardIndex > 0 ) {
Panel newPanel = wizardPanels[wizardIndex-1] as Panel;
if ( newPanel != null ) {
InitPanel(newPanel);
wizardIndex--;
}
}
}
public void StartWizard() {
if ( wizardPanels.Count == 0 ) {
throw new Exception("Must add panels to the wizard");
}
if ( wizardIndex != -1 && !complete ) {
throw new Exception("Wizard has already been started");
}
complete = false;
wizardIndex = 0;
Panel startPanel = wizardPanels[wizardIndex] as Panel;
if ( startPanel != null ) {
InitPanel(startPanel);
}
wizardDialog.Display = true;
}
private void InitPanel(Panel wizardPanel) {
wizardPanel.Dock = DockStyle.Fill;
wizardDialog.NavigatePrevious.Enabled = ((IWizardPanel) wizardPanel).ShowNavigatePrevious;
wizardDialog.NavigateNext.Enabled = ((IWizardPanel) wizardPanel).ShowNavigateNext;
wizardDialog.NavigateFinish.Enabled = ((IWizardPanel) wizardPanel).ShowNavigateFinish;
wizardDialog.UIRoot.Controls.Clear();
wizardDialog.UIRoot.Controls.Add(wizardPanel);
}
}
public class WizardPanel : Panel, IWizardPanel {
private bool prev;
private bool next;
private bool finish;
private Label description = new Label();
public WizardPanel(string description, bool prev, bool next, bool finish) {
this.prev = prev;
this.next = next;
this.finish = finish;
this.description.Text = description;
InitializeComponent();
}
private void InitializeComponent() {
this.description.Dock = DockStyle.Fill;
this.Controls.Add(this.description);
}
public bool ShowNavigatePrevious { get { return this.prev; } }
public bool ShowNavigateNext { get { return this.next; } }
public bool ShowNavigateFinish { get { return this.finish; } }
}
public class WizardTestDialog : Form, IWizardDialog {
private Panel topPanel = new Panel();
private Panel bottomPanel = new Panel();
private Button previousButton;
private Button nextButton;
private Button finishButton;
private string title;
public WizardTestDialog(string title) {
this.title = title;
InitializeComponent();
}
public Control NavigatePrevious {
get {
return previousButton;
}
}
public Control NavigateNext {
get {
return nextButton;
}
}
public Control NavigateFinish {
get {
return finishButton;
}
}
public Control UIRoot {
get {
return topPanel;
}
}
public bool Display {
get {
return this.Visible;
}
set {
this.Visible = value;
}
}
private void InitializeComponent() {
// Create our large containers
// Top for wizard
// Bottom for navigation
this.bottomPanel.Height = 30;
this.bottomPanel.Dock = DockStyle.Bottom;
this.topPanel.Dock = DockStyle.Fill;
this.Text = title;
this.Controls.AddRange(new Control[] { topPanel, bottomPanel });
this.finishButton = new Button();
this.finishButton.Text = "Finish";
this.finishButton.Left = this.bottomPanel.Width - (this.finishButton.Width + 10);
this.finishButton.Anchor = AnchorStyles.Right;
this.nextButton = new Button();
this.nextButton.Text = "Next";
this.nextButton.Left = this.finishButton.Left - (this.nextButton.Width + 5);
this.nextButton.Anchor = AnchorStyles.Right;
this.previousButton = new Button();
this.previousButton.Text = "Previous";
this.previousButton.Left = this.nextButton.Left - (this.previousButton.Width + 5);
this.previousButton.Anchor = AnchorStyles.Right;
this.bottomPanel.Controls.AddRange(new Control[] { previousButton, nextButton, finishButton });
}
}
public class WizardTester {
[STAThread()]
private static void Main(string[] args) {
WizardController controller = new WizardController();
controller.SetDialog(new WizardTestDialog("What do you want?"));
controller.AddPanel(new WizardPanel("foo 1", false, true, false));
controller.AddPanel(new WizardPanel("foo 2", true, true, false));
controller.AddPanel(new WizardPanel("foo 3", true, true, false));
controller.AddPanel(new WizardPanel("foo 4", true, true, true));
controller.AddPanel(new WizardPanel("foo 5", true, false, true));
controller.StartWizard();
Application.Run(controller);
}
}