Code-Only: Winforms Wizard Series Article 2 (VB .NET)

Imports System
Imports System.Collections
Imports System.ComponentModel
Imports System.Threading
Imports System.Windows.Forms

Public Interface IWizardDialog
    ReadOnly Property NavigatePrevious() As Control
    ReadOnly Property NavigateNext() As Control
    ReadOnly Property NavigateFinish() As Control
    ReadOnly Property UIRoot() As Control
    Property Display() As Boolean
End Interface

Public Interface IWizardPanel
    ReadOnly Property ShowNavigatePrevious() As Boolean
    ReadOnly Property ShowNavigateNext() As Boolean
    ReadOnly Property ShowNavigateFinish() As Boolean
End Interface

Public Class WizardController : Inherits ApplicationContext
    Private _complete As Boolean = False
    Private _wizardIndex As Integer = -1
    Private _wizardDialog As IWizardDialog = Nothing
    Private _wizardPanels As New ArrayList()
   
    Public Sub New()
    End Sub
   
    Public Sub SetDialog(dialog As Form)
        Try
            _wizardDialog = DirectCast(dialog, IWizardDialog)
        Catch
            _wizardDialog = Nothing
        End Try

        If _wizardDialog Is Nothing
            Throw New Exception("Wizard dialogs must support IWizardDialog")
        Else
            If _wizardDialog.NavigatePrevious Is Nothing Then Throw New Exception("Wizard dialogs must have a Previous Button")
            If _wizardDialog.NavigateNext Is Nothing Then Throw New Exception("Wizard dialogs must have a Next Button")
            If _wizardDialog.NavigateFinish Is Nothing Then Throw New Exception("Wizard dialogs must have a Finish Button")
            If _wizardDialog.UIRoot Is Nothing Then Throw New Exception("Wizard dialogs must have a non null UI Root")
        End If
       
        AddHandler _wizardDialog.NavigatePrevious.Click, AddressOf Me.Wizard_NavigatePrevious
        AddHandler _wizardDialog.NavigateNext.Click, AddressOf Me.Wizard_NavigateNext
        AddHandler _wizardDialog.NavigateFinish.Click, AddressOf Me.Wizard_NavigateFinish
        AddHandler dialog.Closing, AddressOf Me.Wizard_Closing
    End Sub
   
    Public Sub AddPanel(pnl As Panel)
        Dim vPanel As IWizardPanel = Nothing
       
        Try
            vPanel = DirectCast(pnl, IWizardPanel)
        Catch
            vPanel = Nothing
        End Try
       
        If vPanel Is Nothing Then Throw New Exception("Wizard panels must support IWizardPanel")
        _wizardPanels.Add(vPanel)
    End Sub
   
    Public ReadOnly Property Complete() As Boolean
        Get
            Return _complete
        End Get
    End Property

    Public ReadOnly Property Panels() As ArrayList
        Get
            Return _wizardPanels
        End Get
    End Property
   
    Public Sub Wizard_Closing(Sender As Object, E As CancelEventArgs)
        MessageBox.Show("You must complete the wizard in order to exit.")
        e.Cancel = True
    End Sub
   
    Public Sub Wizard_NavigateFinish(Sender As Object, E As EventArgs)
        ' 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()
    End Sub
   
    Public Sub Wizard_NavigateNext(Sender As Object, E As EventArgs)
        _wizardIndex += 1
       
        If _wizardIndex = _wizardPanels.Count
            Wizard_NavigateFinish(Sender, E) ' This shouldn't happen if your dialogs are correct
            Return
        End If
       
        Try
            Dim newPanel As Panel = DirectCast(_wizardPanels(_wizardIndex), Panel)
            InitPanel(newPanel)
        Catch
            ' Do Nothing
        End Try
    End Sub

    Public Sub Wizard_NavigatePrevious(Sender As Object, E As EventArgs)
        If _wizardIndex > 0
            Try
                Dim newPanel As Panel = DirectCast(_wizardPanels(_wizardIndex - 1), Panel)
                InitPanel(newPanel)
                _wizardIndex -= 1
            Catch
                ' Do Nothing
            End Try
        End If
    End Sub
   
    Public Sub StartWizard()
        If _wizardPanels.Count = 0 Then Throw New Exception("Must add panels to the wizard")
        If _wizardIndex <> -1 AndAlso Not _complete Then Throw New Exception("Wizard has already been started")
       
        _complete = False
        _wizardIndex = 0
       
        Try
            Dim startPanel As Panel = DirectCast(_wizardPanels(_wizardIndex), Panel)
            InitPanel(startPanel)
        Catch
            ' Do Nothing
        End Try
        _wizardDialog.Display = True
    End Sub
   
    Public Sub InitPanel(wizardPanel As Panel)
        wizardPanel.Dock = DockStyle.Fill
       
        Try
            Dim iwp As IWizardPanel = DirectCast(wizardPanel, IWizardPanel)

            _wizardDialog.NavigatePrevious.Enabled = iwp.ShowNavigatePrevious
            _wizardDialog.NavigateNext.Enabled = iwp.ShowNavigateNext
            _wizardDialog.NavigateFinish.Enabled = iwp.ShowNavigateFinish

        Catch
            ' Do Nothing
        End Try
       
        _wizardDialog.UIRoot.Controls.Clear()
        _wizardDialog.UIRoot.Controls.Add(wizardPanel)
    End Sub
End Class

Public Class WizardPanel : Inherits Panel : Implements IWizardPanel
    Private _prev As Boolean = False
    Private _next As Boolean = False
    Private _finish As Boolean = False
   
    Private _description As New Label()
   
    Public Sub New(description As String, showprev As Boolean, shownext As Boolean, showfinish As Boolean)
        _prev = showprev
        _next = shownext
        _finish = showfinish
        _description.Text = description
       
        InitializeComponent()
    End Sub
   
    Private Sub InitializeComponent()
        Me._description.Dock = DockStyle.Fill
        Me.Controls.Add(me._description)
    End Sub
   
    Public ReadOnly Property ShowNavigatePrevious() As Boolean Implements IWizardPanel.ShowNavigatePrevious
        Get
            Return _prev
        End Get
    End Property
   
    Public ReadOnly Property ShowNavigateNext() As Boolean Implements IWizardPanel.ShowNavigateNext
        Get
            Return _next
        End Get
    End Property
   
    Public ReadOnly Property ShowNavigateFinish() As Boolean Implements IWizardPanel.ShowNavigateFinish
        Get
            Return _finish
        End Get
    End Property
End Class

Public Class WizardTestDialog : Inherits Form : Implements IWizardDialog   
    Private _topPanel As New Panel()
    Private _bottomPanel As New Panel()

    Private _previousButton As Button
    Private _nextButton As Button
    Private _finishButton As Button
   
    Private _title As String
   
    Public Sub New(title As String)
        _title = title
        InitializeComponent()
    End Sub
   
    Public ReadOnly Property NavigatePrevious() As Control Implements IWizardDialog.NavigatePrevious
        Get
            Return _previousButton
        End Get
    End Property
   
    Public ReadOnly Property NavigateNext() As Control Implements IWizardDialog.NavigateNext
        Get
            Return _nextButton
        End Get
    End Property
   
    Public ReadOnly Property NavigateFinish() As Control Implements IWizardDialog.NavigateFinish
        Get
            Return _finishButton
        End Get
    End Property
   
    Public ReadOnly Property UIRoot() As Control Implements IWizardDialog.UIRoot
        Get
            Return _topPanel
        End Get
    End Property
   
    Public Property Display() As Boolean Implements IWizardDialog.Display
        Get
            Return Me.Visible
        End Get
        Set(Value As Boolean)
            Me.Visible = Value
        End Set
    End Property
   
    Private Sub InitializeComponent()
        ' Create our large containers
        ' Top for wizard
        ' Bottom for navigation
        _bottomPanel.Height = 30
        _bottomPanel.Dock = DockStyle.Bottom
       
        _topPanel.Dock = DockStyle.Fill
       
        Me.Text = _title
        Me.Controls.AddRange(New Control() { _topPanel, _bottomPanel })
       
        _finishButton = New Button()
        _finishButton.Text = "Finish"
        _finishButton.Left = _bottomPanel.Width - (_finishButton.Width + 10)
        _finishButton.Anchor = AnchorStyles.Right

        _nextButton = New Button()
        _nextButton.Text = "Next"
        _nextButton.Left = _finishButton.Left - (_nextButton.Width + 5)
        _nextButton.Anchor = AnchorStyles.Right

        _previousButton = New Button()
        _previousButton.Text = "Previous"
        _previousButton.Left = _nextButton.Left - (_previousButton.Width + 5)
        _previousButton.Anchor = AnchorStyles.Right
       
        _bottomPanel.Controls.AddRange(New Control() { _previousButton, _nextButton, _finishButton })
    End Sub
End Class

Public Class WizardTester
    <STAThread()> _
    Shared Sub Main()
        Dim controller As 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)
    End Sub
End Class

Published Sunday, April 25, 2004 4:35 PM by Justin Rogers

Comments

Monday, March 22, 2010 11:26 PM by Taci

# re: Code-Only: Winforms Wizard Series Article 2 (VB .NET)

Hi. We make a living by what we get, we make a life by what we give. Help me! It has to find sites on the: Mephisto battler. I found only this - <a href="advancedmaritimetechnology.aticorp.org/.../mephisto-lephanto">mephisto lephanto</a>. Mephisto, the warehouse of the need protagonist is guided and written while the note of the salad portal may be strategic. Mephisto, jokingly you might die some comfort joy. Waiting for a reply :-), Taci from Burundi.

Leave a Comment

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