WindowsDevCenter.com
oreilly.comSafari Books Online.Conferences.

advertisement


AddThis Social Bookmark Button

Developing Visual Studio Project Wizards
Pages: 1, 2, 3, 4, 5, 6

WizardCancelledException

When Visual Studio handles the WizardCancelledException, it aborts the execution of the wizard, stops loading the template that activated the wizard in the first place, and, if possible, returns the Visual Studio environment to the state it was in before the template was selected.

Making effective use of the WizardCancelledException in your application requires that you be aware of several undocumented (or at least unmentioned) features:

  • Visual Studio does not provide any user interface in handling the exception. It simply cancels the execution of the wizard. This means that, before your wizard throws the exception, you should inform the user why the wizard is being cancelled. Alternatively, if the exception is thrown in response to the user clicking the Cancel button on a form or dialog, you should confirm that the user in fact wants to cancel.
  • The WizardCancelledException must be thrown in the class that implements the IWizard interface. If it isn't, Visual Studio handles the exception by cancelling the instance in which the exception occurred, then returning control to the wizard, which will execute without interruption (unless, of course, a runtime exception is thrown).

This latter restriction poses something of a dilemma. The most common reason for cancelling a wizard is that the user has clicked the Cancel button on one of the wizard's dialogs, indicating that he or she no longer wishes to continue with the wizard or the project. Code such as the following (which illustrates how not to throw a WizardCancelledException) therefore seems almost intuitive:

Public Class ProjectWizard : Implements IWizard
   Public Sub RunStarted(ByVal automationObject As Object, _
                         ByVal replacementsDictionary As Dictionary(Of String, String), _
                         ByVal runKind As WizardRunKind, _
                         ByVal customParams() As Object) _
                         Implements IWizard.RunStarted
      ' Initialization code goes here
      Dim frm As New WizardForm()
      frm.ShowDialog()
      ' handling of form data goes here 
   End Sub

   ' Other implemented IWizard methods
End Class

Public Class WizardForm : Inherits Form
   ' Form code to display interact with user

   Public Sub CancelButton_Click(ByVal sender As Object, _
                                 ByVal e As EventArgs) _
                                 Handles CancelButton.Click
      ' This exception is ignored
      Throw New WizardCancelledException("The user has cancelled the wizard.")
   End Sub
End Class

In this case, however, Visual Studio completely ignores the exception, the wizard continues to execute, and Visual Studio attempts to either create a new project (if the user selected a project template) or create a new project item (if the user selected a project item template). This code fails because the exception is thrown in the Form class, and not the class that implements IWizard.

Instead, if the wizard is to be cancelled as a result of the user selecting the Cancel button in a form, the button's DialogResult property should be set to Cancel, so that the form's DialogResult property will be set to DialogResult.Cancel if the form closes as a result of the user pressing the Cancel button. Code in the class implementing the IWizard interface can then evaluate the value of the form's DialogResult property and, if it is DialogResult.Cancel, throw the WizardCancelledException. The skeletal Visual Basic code appears as follows:

Public Class ProjectWizard : Implements IWizard
   Public Sub RunStarted(ByVal automationObject As Object, _
                         ByVal replacementsDictionary As Dictionary(Of String, String), _
                         ByVal runKind As WizardRunKind, _
                         ByVal customParams() As Object) _
                         Implements IWizard.RunStarted
      ' Initialization code goes here
      Dim frm As New WizardForm()
      frm.ShowDialog()
      If frm.DialogResult = DialogResult.Cancel Then
         Throw New WizardCancelledException("The wizard has been cancelled by the user.")
      End If
      ' handling of form data goes here 
   End Sub

   ' Other implemented IWizard methods
End Class

The equivalent C# code is:

public class ProjectWizard : IWizard
{
   public void RunStarted(object automationObject, 
                          Dictionary<string, string> replacementsDictionary, 
                          WizardRunKind runKind, 
                          object[] customParams)
   {
      // Initialization code goes here
      Form frm = new WizardForm();
      frm.ShowDialog();
      if (frm.DialogResult == DialogResult.Cancel)
         throw new WizardCancelledException("The wizard has been cancelled by the user.");

      // handling of form data goes here
   }
}

Although the WizardCancelledException is most commonly thrown in the RunStarted method, it can be thrown in any of the IWizard implementation methods. Visual Studio will terminate the wizard, abort the process of loading the template, and, if possible, restore the Visual Studio environment to its state before the new project or project item template was loaded.

WizardBackoutException

Visual Studio responds to the WizardBackoutException very much like it does to the WizardCancelledException: it aborts the execution of the wizard, stops loading the template that activated the wizard in the first place, and, if possible, returns the Visual Studio environment to the state it was in before the template was selected. It then reopens the dialog (either the New Project or Add New Item dialog) from which the template whose wizard was just terminated was selected. Also like the WizardCancelledException, the WizardBackoutException does not itself provide any user interface, and the exception is completely ignored if it is thrown from outside of the class that provides the IWizard implementation.

Integrating the Template and Wizard

Visual Studio 2005 also features a new (and more straightforward) method of integrating a Visual Studio template with its wizard. The wizard assembly itself must be signed and registered in .NET Global Assembly Cache, or GAC. This allows the assembly to be located regardless of where it resides in the file system. The wizard is then identified by its strong name and its fully qualified type name in the .vstemplate file of its associated template.

Pages: 1, 2, 3, 4, 5, 6

Next Pagearrow