Thomas Alva Edison's light bulb VBInfoZine Home
   An ordinary VB developer shares his own successes and failures
   FREE to registered subscribers.  

Winforms OK / Cancel processing

Tips for using the winforms' built-in modal dialog boxes support

If you do a lot of winforms programming, I'm sure you appreciate the dialog-related functionality built into the base Form class. Specifically, I mean the ability to assign button references to the Form.AcceptButton and Form.CancelButton properties (the following quotation is from the article Getting Started with Windows Forms - highlights are mine): That's great.

But what if I want to do some validation WITHIN the button's Click event handler and if the validation fails, I DON'T WANT to close the dialog?

As an example, take the UserLogonDialog (discussed in the article .NET Interception). Here is the Click event handler code:

Private Sub OKCmd_Click( _
  ByVal sender As System.Object, _
  ByVal e As System.EventArgs) Handles OKCmd.Click
	
  Try
    If Not App.LogonUser(UserName.Text, Password.Text) Then
      Password.Text = String.Empty
      UserName.Select()
      MsgBox("Invalid logon or password. Try again.", MsgBoxStyle.Exclamation)
    End If
  Catch ex As Exception
    MsgBox(ex.Message, MsgBoxStyle.Exclamation)
  End Try
End Sub
When the App.LogonUser call returns False, I want to display a message to the user and allow her to enter the logon information again. But when the OKCmd_Click handler returns, the dialog is always closed.

First solution: Set OKCmd.DialogResult = DialogResult.None (string "None" in the designer) and close the form manually:

Private Sub OKCmd_Click( _
  ByVal sender As System.Object, _
  ByVal e As System.EventArgs) Handles OKCmd.Click
	
  Try
    If Not App.LogonUser(UserName.Text, Password.Text) Then
      Password.Text = String.Empty
      UserName.Select()
      MsgBox("Invalid logon or password. Try again.", MsgBoxStyle.Exclamation)
    Else
      Me.DialogResult = DialogResult.OK
      Me.Close()
    End If
  Catch ex As Exception
    MsgBox(ex.Message, MsgBoxStyle.Exclamation)
  End Try
End Sub
Second solution: Leave the OKCmd.DialogResult = DialogResult.OK, but prevent the form to automatically close when the user enters invalid logon information. Here is how:
Public Class UserLogonDialog
  Inherits System.Windows.Forms.Form

  ' Signal the Closing event handler whether the form's
  ' closure should be canceled.
  Private _CancelClose As Boolean
...

Private Sub OKCmd_Click( _
  ByVal sender As System.Object, _
  ByVal e As System.EventArgs) Handles OKCmd.Click
  Try
    If Not App.LogonUser(UserName.Text, Password.Text) Then
      Password.Text = String.Empty
      UserName.Select()
      MsgBox("Invalid logon or password. Try again.", MsgBoxStyle.Exclamation)
      _CancelClose = True
    End If
  Catch ex As Exception
    MsgBox(ex.Message, MsgBoxStyle.Exclamation)
  End Try
End Sub
...
Private Sub UserLogonForm_Closing( _
  ByVal sender As Object, _
  ByVal e As CancelEventArgs) Handles MyBase.Closing
  
  e.Cancel = _CancelClose
  _CancelClose = False
End Sub
That is, set a form level _CancelClose flag and handle the Closing event in order to prevent the form from being closed.

I've been using the second solution until now, but I'll switch to the first one eventually – it is simpler and more maintainable.

(I'd appreciate some kind of Form.CancelAutoClose property, however :-)).

 ©2003-2008 Palo Mraz. All Rights Reserved.   See my 'new browser window' policy