Code-Only: Winforms Wizard Series Article 2 (C#)

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);
    }
}

Published Friday, April 23, 2004 7:27 PM by Justin Rogers

Comments

No Comments

Leave a Comment

(required) 
(required) 
(optional)
(required)