Export (0) Print
Expand All

Building a Custom Web Form Wizard in Visual Studio .NET

Visual Studio .NET 2003
 

Atul Gupta
.NET Center of Excellence
Infosys Technologies Limited

May 2003

Summary: Learn how to extend Visual Studio with a custom Web Form Wizard that easily adds common functionality to your Web applications. (17 printed pages)

Overview

As we use Microsoft Visual Studio® .NET to build solutions, we realize the power of this tool. At the same time, there are instances when we feel the need for more wizards and templates. After all, the developer world is moving towards more wizard-generated code.

When working on an application, we often find ourselves doing repetitive work. Macros can help with some of these tasks, but what about the need to have a custom Web Form along with its code-behind file? There is a wizard that allows adding a new Web Form page to a Web project, but there are some shortcomings:

  1. The Web Form page is a default page with no additional controls on it.
  2. The code behind the Web Form page doesn't have any custom code.

Wizards

Wizards allow us to create base implementations and provide them as New Project or New Item options in Visual Studio .NET. It would be helpful if we could create a new wizard that adds a Web Form with more controls. For example, a typical Web application would have a consistent look and feel for their Web pages. It could be that all pages need to have a standard header and a standard footer, for example. One can build a sample page and then, using the wizard, add new pages to the project (using the same template), and then add additional logic to the page. Along with the Web page the code-behind file also gets added, giving a jump start to the code for the page as well.

Note   There are other ways to add standard headers and footers to all the pages in an application. One can use HttpModules, handle Application_Start and Application_End events in Global.asax.cs, or build user controls and use them in all thevpages. The idea at use in this article is to demonstrate how to create a wizard, which is not necessarily the best way of creating only headers and footers.

In this document, we will see how we can create a wizard to help us add a new Web Form page and its associated code-behind file. Since there is already an existing project to do this, we will start our wizard's implementation using that as the base. The wizard will appear in the Add New Item dialog, which can be invoked by right-clicking on the solution and selecting Add / Add New Item.

Where necessary, I will also point out the changes required if you are working with Visual Studio .NET 2003.

Before we move ahead with the steps of creating the wizard, there is one final point that needs to be discussed. Visual Studio .NET does provide a Custom Wizard and Visual Studio .NET Add-in project templates. This can be used to create new wizards and add-ins. Note, however, that the option to create a Custom Project wizard is available only to create Visual C++® projects. In the case of the add-in, we need to implement the IDTWizard interface. The approach taken in this document is to show what happens when a new wizard is created and also to demonstrate the point that you can easily build additional custom wizards and simplify your day-to day-work with Visual Studio .NET and increase your productivity.

Steps to Create Custom Wizards in C#

  1. Locate the VC#Wizards directory in the Visual Studio .NET installation. The default installation location for this is C:\Program Files\Microsoft Visual Studio .NET\VC#\VC#Wizards.
  2. Create a new folder under this directory and name it CSharpAddCustomWebFormWiz. This name is derived per the convention followed by existing wizards.
  3. Copy the contents of CSharpAddWebFormWiz to this new folder. This will give you a Templates\1033 subdirectory (along with Scripts\1033 subdirectory also), which contains two files—Templates.inf and Webform1.aspx.
  4. Modify the Webform1.aspx as per your requirements. One way to do this is to build a Webform.aspx page as you need it using Visual Studio .NET and then put that file into this folder. However, make sure that the top portion of the Web Form looks like the code snippet below. The bold faced items get replaced when the form is inserted in the project using the wizard and will help in setting the proper names for various parts of the Web Form. Your code will go within the <form> tag.
    <%@ Page language="c#" Codebehind="$FILENAME$.cs" 
    AutoEventWireup="false" Inherits="$INHERITS$" %>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > 
    <html>
      <head>
        <title>[!output SAFE_ITEM_NAME]</title>
        <meta name="GENERATOR" Content="Microsoft Visual Studio 7.0">
        <meta name="CODE_LANGUAGE" Content="C#">
        <meta name=vs_defaultClientScript 
      content="[!output DEFAULT_CLIENT_SCRIPT]">
        <meta name=vs_targetSchema content="[!output DEFAULT_TARGET_SCHEMA]">
      </head>
      <body MS_POSITIONING="[!output DEFAULT_HTML_LAYOUT]">
       <form id="[!output SAFE_ITEM_NAME]" method="post" runat="server">
            <!-- Your code goes here -->
       </form>
      </body>
    </html>
    
    

    The !output directive is for the wizard engine to output the value of the symbol mentioned. For example, the SAFE_ITEM_NAME is the name of the Web Form selected using the Add New Item dialog.

  5. Put the required code-behind file in the same folder as the ASPX page and call this file as WebForm1.aspx.cs. A sample code-behind file is shown below. Again, note the bold faced text below. These values will be replaced by the namespace of the project and class name for this page when the ASPX is added using the wizard. Also, edit the Templates.inf file to include the name of the CS file after the WebForm1.aspx.
    Note   The order of file names in Templates.inf is important. It should be WebForm1.aspx and then Webform1.aspx.cs.
    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Web;
    using System.Web.SessionState;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.HtmlControls;
    
    namespace [!output SAFE_NAMESPACE_NAME]
    {
       /// <summary>
       /// Summary description for [!output SAFE_CLASS_NAME].
       /// </summary>
       public class [!output SAFE_CLASS_NAME] : System.Web.UI.Page
       {
          private void Page_Load(object sender, System.EventArgs e)
          {
             // Put user code to initialize the page here
             if(Page.IsValid())
             {
                //TODO: Take action if validation succeeds
             }
          }
    
          #region Web Form Designer generated code
          override protected void OnInit(EventArgs e)
          {
             InitializeComponent();
             base.OnInit(e);
          }
          
          /// <summary>
          /// Required method for Designer support - do not modify
          /// the contents of this method with the code editor.
          /// </summary>
          private void InitializeComponent()
          {    
             this.Load += new System.EventHandler(this.Page_Load);
          }
          #endregion
       }
    }
    
    
  6. Visual Studio .NET uses files with the extension .VSZ to launch wizards. We will create a VSZ file using any text editor and name this file CSharpAddCustomWebFormWiz.vsz. The name of the file matches the name of the folder we created in Step 3. This file is stored in the CSharpProjectItems subdirectory in the VC# directory (default installation location is C:\Program Files\Microsoft Visual Studio .NET\VC#\CSharpProjectsItems). Type the following text in the file.
    VSWIZARD 7.0
    Wizard=VsWizard.VsWizardEngine
    Param="WIZARD_NAME = CSharpAddCustomWebFormWiz"
    Param="WIZARD_UI = FALSE"
    Param="PROJECT_TYPE = CSPROJ"
    
    
    Note   For Visual Studio .NET 2003, the Engine version is 7.1. Hence, the Wizard value would be VsWizard.VsWizardEngine .7.1
  7. Visual Studio .NET uses another file with the extension .VSDIR to get information for the Add New Item dialog box. These files are, by default, in the folder C:\Program Files\Microsoft Visual Studio .NET\VC#\CSharpProjectItems\WebProjectItems which is for items that can be added to Web projects. The items are further categorized within subfolders like Code, Data, UI, and so on. To easily identify the new Web Form that we are adding, we will also create a subfolder named Custom. You may choose to give it a name more appropriate to your needs at this point.
  8. Create a new VSDIR file in this new folder that we created in the preview step (Custom) and name this file as Custom.vsdir. As you can see, the name of the file matches the folder name and this is by convention. Type the line below in the custom.vsdir file. The GUID refers to an assembly from which the icon is loaded which is used in the Add New Items dialog box. In our case, we have picked up the value from other existing VSDIR files. The "..\..\" before the VSZ file name is for the relative path of it from this file.
    ..\..\CSharpAddMyWebFormWiz.vsz|{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}
    |Custom Web Form|10|A custom form for Web Applications|
    {FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}|4534|0|WebForm.aspx
    
    

    Figure 1 below shows the Add New Item dialog as it appears once this wizard is ready for use. You can see the MyFolder in the left-tree view (Categories View). The other values shown in bold face above are used in the following manner:

    • Custom Web Form: is used to identify this custom Web Form in the right side of the dialog (Templates view).
    • A custom form for Web Applications: is a small help message for this item.
    • 0: signifies the position where this item will appears in the right side of the Add New Item dialog (Templates View). 0 means this item will be first item to be displayed.
    • Webform.aspx: signifies the name that will be used for this item while adding a new item in the project. The IDE is able to automatically add a number with this name to make sure that the name is distinct in the project. In Figure 1 we see the name selected is Webform3.aspx.

      Figure 1. The Add New Item dialog box once the wizard is in use

  9. Because all the items that can be added also are seen in the right pane (Templates view) even when the Web Project Items is selected in the Categories tree view, we need to make another entry in the WebProjectItems.vsdir (default installation location is C:\Program Files\Microsoft Visual Studio .NET\VC#\CSharpProjectItems\WebProjectItems). Add the following line to this file. (This file also has additional entries for each sub folder, but this is not mandatory.)
    ..\CSharpAddCustomWebFormWiz.vsz|{FAE04EC1-301F-11d3-BF4B-
    00C04F79EFBC}|Custom Web Form|10|A custom form for Web Applications 
    |{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}|4534|0|WebForm.aspx
    
    
  10. This completes the basic setup. We now get back to the default.js (location is C:\Program Files\Microsoft Visual Studio .NET \ VC# \ VC#Wizards \ CSharpAddMyWebFormWiz \ Scripts \ 1033) script file which drives the show. This file already has some code in it because we copied it from another location in Step 3. Replace the existing code with the following code snippet. (The bold faced parts of the script below are the changes we have done to the default.js script.)
    // (c) 2001 Microsoft Corporation
    function AddDefaultServerScriptToWizard(selProj)
    {
       wizard.AddSymbol("DEFAULT_SERVER_SCRIPT", "JavaScript");
    }
    
    function AddDefaultClientScriptToWizard(selProj)
    {
        var prjScriptLang = selProj.Properties("DefaultClientScript").Value;
        // 0 = JScript
        // 1 = VBScript
        if(prjScriptLang == 0)
        {
            wizard.AddSymbol("DEFAULT_CLIENT_SCRIPT", "JavaScript");
        }
        else
        {
            wizard.AddSymbol("DEFAULT_CLIENT_SCRIPT", "VBScript");
        }
    }
    
    function AddDefaultDefaultHTMLPageLayoutToWizard(selProj)
    {
        var prjPageLayout = selProj.Properties("DefaultHTMLPageLayout").Value;
        // 0 = FlowLayout
        // 1 = GridLayout
        if(prjPageLayout == 0)
        {
            wizard.AddSymbol("DEFAULT_HTML_LAYOUT", "FlowLayout");
        }
        else
        {
            wizard.AddSymbol("DEFAULT_HTML_LAYOUT", "GridLayout");
        }
    }
    
    function OnFinish(selProj, selObj)
    {
        var oldSuppressUIValue = true;
       try
       {
            oldSuppressUIValue = dte.SuppressUI;
          var strProjectName      = wizard.FindSymbol("PROJECT_NAME");
          var strSafeProjectName = CreateSafeName(strProjectName);
          wizard.AddSymbol("SAFE_PROJECT_NAME", strSafeProjectName);
          SetTargetFullPath(selObj);
          var strProjectPath      = wizard.FindSymbol("TARGET_FULLPATH");
          var strTemplatePath      = wizard.FindSymbol("TEMPLATES_PATH");
    
          var strTpl = "";
          var strName = "";
          var InfFile = CreateInfFile();
          
          // add the default project props for the aspx file before we
          // render it
          AddDefaultServerScriptToWizard(selProj);
          AddDefaultClientScriptToWizard(selProj);
          AddDefaultTargetSchemaToWizard(selProj);
          AddDefaultDefaultHTMLPageLayoutToWizard(selProj);
          
          // render our file
          AddFilesToProject(selObj, strProjectName, 
                  strProjectPath, InfFile, true);
          
          AddReferencesForWebForm(selProj);
       }
       catch(e)
       {
          if( e.description.length > 0 )
             SetErrorInfo(e);
          return e.number;
       }
        finally
        {
             dte.SuppressUI = oldSuppressUIValue;
             if( InfFile )
             InfFile.Delete();
        }
    }
    
    //Make sure that the names of the files mentioned here match with that physically present in the folder
    function SetFileProperties(oFileItem, strFileName)
    {
        if(strFileName == "WebForm1.aspx")
        {
            oFileItem.Properties("SubType").Value = "Form";
        }
        
        if(strFileName == "WebForm1.aspx.cs")
        {
            oFileItem.Properties("SubType").Value = "Code";
        }
    }
    
    function AddFilesToProject(oProj, strProjectName, 
         strProjectPath, InfFile, AddItemFile)
    {
       try
       {
          dte.SuppressUI = false;
          var projItems;
    
               projItems = oProj;
    
          var strTemplatePath = wizard.FindSymbol("TEMPLATES_PATH");
    
          var strTpl = "";
          var strName = "";
    
          // if( Not a web project )
          if(strProjectPath.charAt(strProjectPath.length - 1) != "\\")
              strProjectPath += "\\";   
    
          var strTextStream = InfFile.OpenAsTextStream(1, -2);
          while (!strTextStream.AtEndOfStream)
          {
             strTpl = strTextStream.ReadLine();
             if (strTpl != "")
             {
                strName = strTpl;
                var strType = "";
                if (strName == "WebForm1.aspx")
                {
                    strType = "Form";
                }
                else // this would be code-behind file
                {
                    strType = "Code";
                }
     
                var strTarget = "";
                var strFile = "";
                strTarget = wizard.FindSymbol("ITEM_NAME");
     
                //if we are adding the code 
                            //behind file, we need to append 
                            //the .CS extension
                //to the name obtained from the 
                            //Add New Item dialog. this name would be
                //something like "webform2.aspx"
                if(strType == "Code")
                {
                    strTarget = strTarget + ".cs";
                }
    
                var fso;
                fso = new 
                              ActiveXObject("Scripting.FileSystemObject");
                var TemporaryFolder = 2;
                var tfolder = fso.GetSpecialFolder(TemporaryFolder);
                var strTempFolder = 
                               fso.GetAbsolutePathName(tfolder.Path);
    
                var strFile = strTempFolder + "\\" + 
                              fso.GetTempName();
                //var strFile = strTempFolder + "\\" + strTarget;
    
                var strClassName = strTarget.split(".");
                wizard.AddSymbol("SAFE_CLASS_NAME", strClassName[0]);
                    wizard.AddSymbol("SAFE_ITEM_NAME", strClassName[0]);
    
                var strTemplate = strTemplatePath + "\\" + strTpl;
                var bCopyOnly = false;
                var strExt = strTpl.substr(strTpl.lastIndexOf("."));
                if(strExt==".bmp" || strExt==".ico" || 
                              strExt==".gif" || strExt==".rtf" 
                              || strExt==".css")
                   bCopyOnly = true;
                wizard.RenderTemplate(strTemplate, 
                              strFile, bCopyOnly, true);
    
                var projfile = 
                                projItems.AddFromTemplate(strFile, strTarget);
                SafeDeleteFile(fso, strFile);
     
                if(projfile)
                   SetFileProperties(projfile, strName);
    
                if(strType == "Form")
                {
                   var window = projfile.Open(vsViewKindPrimary);
                   window.visible = true;
                }
     
                //when adding the webform.aspx, 
                            //the AddFromTemplate function called above
                //automatically also adds the code-behind file. 
                            //Since we want to add our file
                //we will have to delete the file that 
                            //was created by default before we 
                //create our custom code-behind file
                if(strType == "Form")
                {
                    var strTargetCS = strProjectPath 
                                   + strTarget + ".cs";
                    SafeDeleteFile(fso, strTargetCS)
                }
             }
          }
          strTextStream.Close();
       }
       catch(e)
       {
          strTextStream.Close();
          throw e;
        }
    }
    
    

    The original default.js uses a AddFilesToCSharpProject function , which is defined in the common.js file. If we use the same function, the issue we face is that after adding the ASPX page, the AddFromTemplate function, which is used inside of the AddFilesToCSharpProject function, automatically adds the code-behind file. Thus, we are not able to add our custom code-behind file. In order to be able to do this, we need to make some changes to this function. I decided to take the existing function, make the modifications, and include it in the default.js itself. I didn't want to make any changes to common.js because it is used by other existing wizards. To add our custom code-behind file, we need to first delete the file that is automatically created and then add our custom file.

    When the wizard is ready for use, you can start Visual Studio .NET and test it out by creating a new C# ASP.NET application, and then adding a new Web Form page to it.

Steps to Create Custom Wizards in Visual Basic .NET

  1. Locate the VBWizards directory in the Visual Studio .NET installation. The default installation location is C:\Program Files\Microsoft Visual Studio .NET\VB7\VBWizards.
  2. Create a new folder under this directory and name it CustomWebForm.
  3. Copy the contents of the WebForm folder to this new folder. This will give you a Templates\1033 subdirectory (along with Scripts\1033 subdirectory also), which contains one file—Webform.aspx.
  4. Modify the Webform.aspx per your requirements. One way to do this is to build a Webform.aspx page that meets your needs using Visual Studio .NET and then put that file into this folder. However, do make sure that the top portion of the Web Form looks like the code below. The bold faced items get replaced when the form is inserted in the project using the wizard and helps with setting the proper names for various items. Your code will go within the <form> tag.
    <%@ Page language="vb" Codebehind="$FILENAME$.vb" 
    AutoEventWireup="false" Inherits="$INHERITS$" %>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > 
    <html>
      <head>
        <title>[!output SAFE_ITEM_NAME]</title>
        <meta name="GENERATOR" Content="Microsoft Visual Studio 7.0">
        <meta name="CODE_LANGUAGE" Content=" Visual Basic 7.0">
        <meta name=vs_defaultClientScript content="[!output 
              DEFAULT_CLIENT_SCRIPT]">
        <meta name=vs_targetSchema content="[!output DEFAULT_TARGET_SCHEMA]">
      </head>
      <body MS_POSITIONING="[!output DEFAULT_HTML_LAYOUT]">
       <form id="Form1" method="post" runat="server">
            <!-- Your code goes here -->
       </form>
      </body>
    </html>
    
    

    The !output directive is for the wizard engine to output the value of the symbol mentioned. For example, the SAFE_ITEM_NAME is the name of the Web Form selected using the Add New Item dialog.

  5. Put the required code-behind file in the same folder and call this file as WebForm.aspx.vb. A sample code-behind file is shown below. Again, note the bold faced text below. These values will be replaced by the class name for this page when the ASPX is added using the wizard.
    Imports System.Drawing
    Imports System.Web.UI.WebControls
    Imports System.Web.UI.HtmlControls
    
    Public Class [!output SAFE_ITEM_NAME]
        Inherits System.Web.UI.Page
    
    #Region " Web Form Designer Generated Code "
    
        'This call is required by the Web Form Designer.
        <System.Diagnostics.DebuggerStepThrough()> _
        Private Sub InitializeComponent()
    
        End Sub
    
        Private Sub Page_Init(ByVal sender As System.Object, _
             ByVal e As System.EventArgs) Handles MyBase.Init
            'CODEGEN: This method call is required by the Web Form Designer
            'Do not modify it using the code editor.
            InitializeComponent()
        End Sub
    
    #End Region
    
        Private Sub Page_Load(ByVal sender As System.Object, _
             ByVal e As System.EventArgs) Handles MyBase.Load
            'Put user code to initialize the page here
        End Sub
    
    End Class
    
    
  6. Visual Studio .NET uses files with extension VSZ to launch wizards. We will start by creating a VSZ file by using a text editor and naming this file CustomWebForm.vsz. The name of the file matches the name of the folder we created in Step 2. This file is stored in the VBProjectItems subdirectory in the VB7 directory (default installation location is C:\Program Files\Microsoft Visual Studio .NET\VB7\VBProjectsItems). Type the following text in the file.
    VSWIZARD 6.0
    Wizard=VsWizard.VsWizardEngine
    Param="WIZARD_NAME = CustomWebForm"
    Param="WIZARD_UI = FALSE"
    Param="PROJECT_TYPE = VBPROJ"
    
    
    Note   For Visual Studio .NET 2003, the Engine version is 7.1. Hence the Wizard value would be VsWizard.VsWizardEngine.7.1
  7. Visual Studio .NET uses another file with extension VSDIR to get information for the Add New Item dialog box. These files are in the folder C:\Program Files\Microsoft Visual Studio .NET\VB7\VBProjectItems\Web Project Items by default for items that can be added to Web project. The items are further categorized within subfolders like Code, Data, UI, and so on.
  8. The existing Webform Wizard is part of the UI page. We will create a new folder called Custom in the Web Project Items folder and create a WebCustomProjectItems.vsdir file in this location. Type the following line in this file. The GUID refers to an assembly from which the icon is loaded that is used in the Add New Items dialog box. The "..\..\" before the VSZ file name is for the relative path of it from this file.
    ..\..\CustomWebForm.vsz|{164B10B9-B200-11D0-8C61-00A0C91E29D5}|Custom 
    Web Form|10|A custom form for Web applications|{164B10B9-B200-11D0-
    8C61-00A0C91E29D5}|4533| |WebForm.aspx
    
    

    Figure 2 shows the Add New Item dialog as it appears once this wizard is ready for use. You can see the Custom folder in the left tree view (Categories View). The other values shown in bold face above are used in the following manner:

    • Custom Web Form: is used to identify this custom Web Form in the right side of the dialog (Templates view).
    • A custom form for Web Applications: is a small help message for this item.
    • 0: signifies the position where this item will appears in the right side of the Add New Item dialog (Templates View). 0 means this item will be first item to be displayed.
    • Webform.aspx: signifies the name that will be used for this item while adding a new item in the project. The IDE is able to automatically add a number with this name to make sure that the name is distinct in the project. In Figure 2 we see the name selected is Webform3.aspx.
    • Figure 2. Add New Item dialog box as it appears when the wizard is ready for use

  9. Since all the items that can be added are seen in the right pane (Templates view) even when the Web Project Items is selected in the Categories tree view, we need to make another entry in the WebProjectItems.vsdir (default installation location is C:\Program Files\Microsoft Visual Studio .NET\VB7\VBProjectItems\Web Project Items). Add the following lines to this file.
    Custom|{164B10B9-B200-11D0-8C61-00A0C91E29D5}|Custom|70
    .
    .
    ..\CustomWebForm.vsz|{164B10B9-B200-11D0-8C61-00A0C91E29D5}|Custom Web 
    Form|10|A custom form for Web Applications|{164B10B9-B200-11D0-8C61-
    00A0C91E29D5}|4533| |WebForm.aspx
    
    
  10. This completes the basic setup. We now get back to the default.js (location is C:\Program Files\Microsoft Visual Studio .NET\Vb7\VBWizards\CustomWebForm\Scripts\1033) script file that drives the show. This file already has some code in it because we copied it from another location in Step 3. Replace the code with the snippet below. The bold faced parts of the script below are the changes we have made to the default.js script.
    //
    // Copyright (c) Microsoft Corporation. All rights reserved.
    //
    
    function OnFinish(selProj, selObj)
    {
        var oldSuppressUIValue = true;
        try
        {
            oldSuppressUIValue = dte.SuppressUI;
            var bSilent = wizard.FindSymbol("SILENT_WIZARD");
            dte.SuppressUI = bSilent;
    
            var strItemName = wizard.FindSymbol("ITEM_NAME");
            var strTemplatePath = wizard.FindSymbol("TEMPLATES_PATH");
            var strTemplateFile = strTemplatePath + "\\WebForm.aspx"; 
    
            AddDefaultWebFormsPropertiesToWizard(dte, wizard, selProj);
    
            var item = AddFileToVBNETProject(strItemName, 
                selProj, selObj, strTemplateFile, false, true);
            if( item )
            {
                var editor = item.Open(vsViewKindPrimary);
                editor.Visible = true;
            }
            
            //Add the custom code-behind file also
            strTemplateFile = strTemplateFile + ".vb"; 
            item = AddFileToVBNETProject(strItemName, 
                selProj, selObj, strTemplateFile, false, false);
            
            return 0;
        }
        catch(e)
        {   
            switch(e.number)
            {
            case -2147221492 /* OLE_E_PROMPTSAVECANCELLED */ :
                return -2147221492;
    
            case -2147024816 /* FILE_ALREADY_EXISTS */ :
            case -2147213313 /* VS_E_WIZARDBACKBUTTONPRESS */ :
                return -2147213313;
    
            default:
                ReportError(e.description);
                return -2147213313;
            }
        }
        finally
        {
            dte.SuppressUI = oldSuppressUIValue;
        }
    }
    
    function AddFileToVBNETProject(strItemName, selProj, 
       selObj, strTemplateFile, bValidate, bForm)
    {
        AddBaseNameToWizard("SAFE_ITEM_NAME", strItemName, ".");
    
        if( bValidate )
        {
            var strSafeName = wizard.FindSymbol( "SAFE_ITEM_NAME" );
            if( !wizard.ValidateCLRIdentifier( strSafeName, false ))
            {
                strSafeName = "_" + strSafeName;
                wizard.AddSymbol("SAFE_ITEM_NAME", strSafeName);
            }
        }
    
        var isReferenceExpanded;
        if(selProj != null) 
            isReferenceExpanded = IsReferenceExpanded(selProj);
    
        // Get project item for selObj collection
        var folder = selObj.parent;
    
        var strProjectPath = folder.Properties("FullPath");
    
    
        //if we are adding the code-behind file, we need to append the .vb 
        // extension to the name obtained from the Add New Item dialog. this 
        // name would be something like "webform2.aspx"
        if(!bForm)
        {
            strItemName = strItemName + ".vb";
        }
    
        var fsoTemporaryFolder = 2;
        fso = new ActiveXObject("Scripting.FileSystemObject");
        var tFolder = fso.GetSpecialFolder(fsoTemporaryFolder);
        var strTempName = fso.GetTempName();
        var strTempFile = tFolder.Path + "\\" + strTempName;
        SafeDeleteFile(fso, strTempFile);
        wizard.RenderTemplate(strTemplateFile, strTempFile, false);
        var item = folder.ProjectItems.AddFromTemplate(strTempFile, 
            strItemName );
        SafeDeleteFile(fso, strTempFile);
    
        if(item)
            SetFileProperties(item, strTemplateFile);
    
        if(bForm)
        {
            var window = item.Open(vsViewKindPrimary);
            window.visible = true;
        }
     
     
        //when adding the webform.aspx, the AddFromTemplate function called above
        //automatically also adds the code-behind file. Since we want to add our
        //file we will have to delete the file that was created by default 
        // before we create our custom code-behind file
        if(bForm)
        {
            var strTargetVB = strProjectPath + strItemName + ".vb";
            SafeDeleteFile(fso, strTargetVB)
        }
    
        return item;
    }
    
    //Make sure that the names of the files mentioned here match with that physically present in the folder
    function SetFileProperties(oFileItem, strFileName)
    {
        if(strFileName == "WebForm.aspx")
        {
            oFileItem.Properties("SubType").Value = "Form";
        }
     
        if(strFileName == "WebForm.aspx.vb")
        {
            oFileItem.Properties("SubType").Value = "Code";
        }
    }
    
    

    The original default.js uses a AddFileToVSProject function , which is defined in the common.js file. If we use the same function, the issue we face is that after adding the ASPX page, the AddFromTemplate function, which is used inside of the AddFileToVSProject function, automatically adds the code-behind file. Thus, we are not able to add our custom code-behind file. In order to be able to do this, we need to make some changes to this function. I decided to take the existing function, make the modifications, and include it in the default.js itself. I didn't want to make any changes to common.js because it is used by other existing wizards and I didn't want any existing functionality to be affected. To add our custom code-behind file, we need to first delete the file that the is automatically created and then add our custom file.

    When the wizard is ready for use, we can start Visual Studio .NET and test it out by creating a new Visual Basic .NET ASP.NET application and then adding a new Web Form page to it.

Conclusion

A Custom Web Form Wizard can help you add common functionality to your Web applications, using both C# and Visual Basic .NET. This article shows you how to add this functionality to your own applications, as well as being a stepping-stone upon which you can build more feature-rich Web Forms Wizards or other types of wizards.

References

Show:
© 2015 Microsoft