Please note that this needs to be ported to .net in an OO fashion by using inheritance. The logic however remains the same.
The formStateHelper is a class that automatically enables and disables controls on the form depending on the three main buttons that the user clicks on, namely "New", "Cancel" and "Save". Each one of these actions puts the form into a specific state, and the controls on the form are then enabled and disabled behind the scenes by the formStateHelper. Additionally the class has an addEditableControl method that allows you to define a group of controls that must party with the current state. The class raises a BeforeSave event that may be cancelled or may allow the data on the form to be validated and saved through custom validation and save methods written in the form.
Todo: Port this to .net and try and use an inheritance mechanism instead of delegation.
Class code:
Option Compare Database
Private WithEvents mSelectionBox As ComboBox
Private WithEvents mNewButton As CommandButton
Private WithEvents mSaveButton As CommandButton
Private WithEvents mCancelButton As CommandButton
Private mblnFalseFire As Boolean
Public Event BeforeSave(ByRef cancel As Boolean)
Private mControls As Collection
Public Enum EditStateEnum
EditStateEnumNoState = 0
EditStateEnumNewState = 1
EditStateEnumEditing = 2
End Enum
Public Sub Initialize(ByRef SelectionBox As ComboBox, ByRef NewButton As CommandButton, _
ByRef CancelButton As CommandButton, ByRef SaveButton As CommandButton)
Set mNewButton = NewButton
Set mSaveButton = SaveButton
Set mCancelButton = CancelButton
Set mSelectionBox = SelectionBox
setState EditStateEnumNoState
End Sub
Public Sub addEditableControl(ctl As Control)
mControls.Add ctl
End Sub
Private Sub EnableEditableControls()
Dim ctl As Control
For Each ctl In mControls
ctl.Enabled = True
Next
'select first control
Set ctl = mControls(1)
ctl.Enabled = True
ctl.SetFocus
End Sub
Private Sub DisableEditableControls(MoveFocusControl As Control)
Dim ctl As Control
Dim txt As TextBox
Dim chk As CheckBox
Dim cbo As ComboBox
For Each ctl In mControls
ctl.Enabled = True
ctl.SetFocus
If TypeOf ctl Is TextBox Then
Set txt = ctl
txt.Text = ""
ElseIf TypeOf ctl Is CheckBox Then
Set chk = ctl
chk.value = -1
ElseIf TypeOf ctl Is ComboBox Then
Set cbo = ctl
cbo.ListIndex = -1
End If
MoveFocusControl.SetFocus
ctl.Enabled = False
Next
mSelectionBox.Enabled = True
mSelectionBox.SetFocus
mblnFalseFire = True
mSelectionBox.Text = ""
mblnFalseFire = False
MoveFocusControl.SetFocus
mSelectionBox.Enabled = False
End Sub
Public Sub setState(NewState As EditStateEnum)
Dim ctl As Control
If Not mblnFalseFire Then
If NewState = EditStateEnumEditing Then
'raise error if not controls added that apply to this state
If mControls.Count = 0 Then
Err.Raise 50000, "FormStateHelper.setState", "State could not be set because no controls have been added to the collection"
End If
'select first control
Set ctl = mControls(1)
ctl.Enabled = True
ctl.SetFocus
mSaveButton.Enabled = True
mNewButton.Enabled = True
mSelectionBox.Enabled = True
mCancelButton.Enabled = False
ElseIf NewState = EditStateEnumNewState Then
'raise error if not controls added that apply to this state
If mControls.Count = 0 Then
Err.Raise 50000, "FormStateHelper.setState", "Stae could not be set because no controls have been added to the collection"
End If
'we first have to reset the state to nil just in case the user was editing at the
'time the "new button" was clicked
DisableEditableControls mNewButton
EnableEditableControls
mCancelButton.Enabled = True
mSaveButton.Enabled = True
mNewButton.Enabled = False
mSelectionBox.Enabled = False
ElseIf NewState = EditStateEnumNoState Then
mNewButton.Enabled = True
DisableEditableControls mNewButton
mCancelButton.Enabled = False
mSaveButton.Enabled = False
mSelectionBox.Enabled = True
End If
End If
End Sub
Private Sub Class_Initialize()
Set mControls = New Collection
End Sub
Private Sub mCancelButton_Click()
setState EditStateEnumNoState
End Sub
Private Sub mNewButton_Click()
setState EditStateEnumNewState
End Sub
Private Sub mSaveButton_Click()
Dim b As Boolean
RaiseEvent BeforeSave(b)
If Not b Then setState EditStateEnumNoState
End Sub
Private Sub mSelectionBox_Click()
setState EditStateEnumEditing
End Sub
Usage:
In the initialize event, use the following code:
Set mFormState = New FormStateHelper 'module level variable!
mFormState.addEditableControl Me.txtDescription
mFormState.Initialize Me.cboArtisans, Me.btnAdd, Me.btnCancel, Me.btnSave
The formStateHelper responds to all the buttons clicked on the form and raises the BeforeSave event that allows the programmer to write custom save and validation event handlers.
Private Sub mFormState_BeforeSave(ByRef cancel As Boolean)
cancel = Not validate
If Not cancel Then saveRecord
End Sub
Private Function validate() As Boolean
Dim b As Boolean
b = IsNull(Me.txtDescription.value)
If Not b Then b = Me.txtDescription.value = ""
validate = Not b
End Function
Private Function saveRecord()
'use this function to save the record to the database
MsgBox "Record saved"
End Function
Here is a warning about using this in MsAccess 2003:
You have to add dummy procedures in the current form as a workaround, otherwise the formStateHelper will not receive events when the user clicks on a form.
Private Sub btnAdd_Click()
'have to leave this empty for the event to fire
Dim s As String
s = "DUMMY"
End Sub
Private Sub btnCancel_Click()
'have to leave this empty for the event to fire
Dim s As String
s = "DUMMY"
End Sub
Private Sub btnSave_Click()
'have to leave this empty for the event to fire
Dim s As String
s = "DUMMY"
End Sub
Private Sub cboArtisans_Click()
'have to leave this empty for the event to fire
Dim s As String
s = "DUMMY"
End Sub