Introducing InfoPath Form Template Projects

Highlights

In this chapter, you will learn how to

  • Describe the advantages of InfoPath projects that use .NET managed code instead of JScript or VBScript for form event handling.
  • Create a new InfoPath project, and write a simple Visual Basic .NET event handler for the OnClick event of a button control.
  • Write handlers for the OnBeforeChange and
  • OnAfterChange events of field values that update the values of other fields with ISO 8601 “formatted date and dateTime values.
  • Create an InfoPath project from an existing template, write a handler for the OnAfterChange event that fires when you add an optional repeating section to a form, and add default RFC1123- formatted dateTime values to a string field.
  • Resolve conflicts that occur when opening multiple versions of the same template in data entry mode; copy InfoPath projects from one location to another; create release versions of projects; and publish projects to shared folders, Web servers, and Windows SharePoint Services form libraries.

For more information

  • See the index topic Date and Time Format Strings in the .NET Framework s help file for more information about the DateTime object s formatting options.
  • Refer to the MSXML 4 Core Services documentation to learn more about the IXMLDOMNode and
  • IXMLDOMNodeList objects for navigating the XML tree of InfoPath data sources. Search msdn.microsoft.com for the term MSXML 4.0 SDK (include the quotation marks), click the MSXML 4.0 SDK link to open the introduction to the SDK, and scroll to and click the Program With DOM In Visual Basic link for a Visual Basic 6/VBA tutorial.


Overview

To work through this chapter

  • You need Microsoft Visual Basic .NET Standard 2003 or Microsoft Visual Studio .NET Professional 2003 or later installed on your local computer. This chapter refers to both versions as Visual Studio.
  • You must download and install the InfoPath 2003 Toolkit for Visual Studio .NET (Toolkit) after installing InfoPath SP-1. The Toolkit is available for download at no charge from a link at www.microsoft.com/infopath/ .
  • You should have experience writing Microsoft Visual Basic 6 code or, preferably, Microsoft Visual Basic for Applications (VBA) code, and familiarity with MSXML Core Services 3 or later and programming the XML Document Object Model (XML DOM). The chapters in Part IV assume that you ll be more comfortable writing Visual Basic .NET code than C# code.
  • You should have a working knowledge of elementary Visual Basic .NET programming techniques in the Microsoft Development Environment for .NET and be familiar with .NET Framework 1.1 s namespaces and classes. You don t need to be a Visual Basic .NET expert.
  • Some experience writing Visual Basic .NET code for Microsoft Excel 2003 or Microsoft Word 2003 projects with the Microsoft Visual Studio Tools for the Microsoft Office System (VSTO) is useful, but not essential.
  • You should have installed the sample files from the CD that accompanies this book to provide the data sources for the procedures in this chapter. These folders also contain code snippets that you can paste into the event handler examples.

 SP-1   Several earlier chapters discuss the need to add programming code to Microsoft Office InfoPath 2003 forms to handle tasks that you can t accomplish with InfoPath s declarative programming model. The declarative programming features added by InfoPath 2003 Service Pack 1 (SP-1) ”such as the Insert Formula dialog box, event-based rules, and user roles ”substantially reduce the need to add programming code to forms. The InfoPath 2003 release version supported only JScript or VBScript programming with the Microsoft Script Editor (MSE). SP-1 lets you create InfoPath 2003 Projects, which substitute managed Visual Basic .NET or C# code for script. You must install the Toolkit to take advantage of SP-1 s managed code features.

The chapters in Part IV use Visual Basic .NET for all procedures, because most Office developers are accustomed to writing VBA code to automate Office applications. Visual Basic .NET has full parity with C# as a programming language, although each language has a few features that are missing in the other. For example, Visual Basic .NET supports With ... End With constructs; C# doesn t. C# offers XML comments, which aren t available in Visual Basic .NET. Building .NET assemblies with either language generates identical Microsoft Intermediate Language (MSIL) code, which the just-in-time (JIT) compiler converts to the same machine-language instructions. Neither language offers a significant performance benefit or penalty.

Note  

Programming InfoPath forms with JScript or VBScript
If you re an experienced JScript or VBScript programmer, you might want to apply your scripting skills to form programming. The sample forms installed by InfoPath include JScript event handlers and general-purpose functions that you can use as models for programming your forms. The majority of the InfoPath programming documentation provides JScript ”rather than VBScript ” examples, which is an odd language choice for an Office application. It s much easier for Office developers to apply their VBA skills to VBScript programming than to JScript programming.

Regardless of your scripting experience, Microsoft Visual C# and Visual Basic .NET are Microsoft s preferred programming languages (in that order, unfortunately ), and they represent the future of Microsoft Windows application development. Future versions of InfoPath are likely to be full- fledged .NET implementations ; if so, managed code for implementing business logic probably will be a requirement, not an option.


Comparing Managed NET Code and Script

The primary distinction between managed .NET code and script is how the code executes: .NET code is compiled, and script is interpreted. A language compiler translates .NET source code into MSIL, and the Common Language Runtime (CLR) JIT-compiles the MSIL to executable (machine) code for a specific processor, such as the 32-bit Intel Pentium or 64-bit AMD Opteron series. The JIT compilation process generates machine code on an as-needed basis; the first time a subprocedure or function executes, the JIT-compiled machine code is cached for reuse. An interpreter reads successive lines of script code and translates each line to machine code every time the script runs. In most cases, compiled code executes faster than interpreted code.

The most important benefits of managed code for InfoPath developers are much easier debugging and early object binding, which enables Microsoft IntelliSense in Visual Studio for statement completion. Building and running managed code opens the form in preview mode. When execution reaches a breakpoint, Visual Studio receives the focus to let you determine the value of variables or object properties at that point. Continuing past the breakpoint returns the focus to the form preview. Another advantage of managed code is that your source code isn t easily accessible to InfoPath users or your competitors . The template stores a reference to an assembly , which is a dynamic-link library (DLL) that contains program metadata and MSIL, not source code. Although it s possible to decompile MSIL, you can make it very difficult for others to reverse-engineer your MSIL code with the Dotfuscator obfuscation tool that s included with Visual Studio.

Substituting managed code for script also enables strong typing, which isn t turned on by default for Visual Basic .NET. To enforce strong typing, you must add an Option Strict On statement at the beginning of the code or set a language compiler option to enforce strong typing for all Visual Basic .NET projects. When you declare all variables with their data or object types, the language compiler won t let you set the variable s value to a different type. Strong typing prevents declaring variables of the Object data type, the .NET equivalent of VBA s Variant data type. JScript and VBScript are loosely typed; variables assume the type of the values you assign to them and can change data or object types without notice. Strong typing improves code execution performance and minimizes the potential for run-time errors.

The .NET Framework provides myriad useful classes and methods that aren t present in JScript or VBScript. For example, the InfoPath sample forms require custom getDateString and getTimeString functions to return date and time in the ISO 8601 pattern that s required by fields of the xsd:date and xsd:dateTime datatypes. The .NET Framework s DateTime class provides standard date/time formatters to return ISO 8601, RFC1123, and many other patterns. RFC1123 is the date format used in the RSS 2.0 examples in this and the preceding chapters. The sections Responding to OnAfterChange Events and Taking Action Based on the Value of Another Field, later in this chapter, contain ISO 8601 formatting examples. The section Adding Managed Code to an Existing Form demonstrates RFC1123 formatting.

A minor downside of adding managed code to InfoPath templates is the requirement to install the run-time version of the .NET Framework 1.1 on users computers to provide required classes, and JIT-compile the assembly when the form loads. The 108 MB run-time .NET Framework 1.1 is freely distributable so you can put the  Setup.exe file on a server share and instruct users to install it, or users can download .NET Framework 1.1 from the Microsoft Windows Update site, at windowsupdate.microsoft.com .


Adding Managed Code Behind a Form

After you install the Toolkit, you can add managed code to an imported copy of an existing form or create a new form in Visual Studio s integrated development environment (IDE). When you open the New Project dialog box, you ll find that the Toolkit has added a new Microsoft Office System Projects icon to the Project Types list, which contains subfolders for Visual Basic and Visual C# projects and an InfoPath Form Template icon, as shown in Figure 15-1. (Installing the VSTO also adds this folder and three template icons for Excel and Word 2003.) If you re using Visual Basic .NET Standard, only Visual Basic Projects appear in the list.

click to expand
Figure 15-1: The Toolkit adds an InfoPath Form Template icon for Visual Basic and, if installed, Visual C#, and supplies default values for the project name and its folders.

Accepting default settings for the project and clicking OK opens the single screen of the Microsoft Office Project Wizard, which lets you choose between importing a copy of an existing form or creating a new form. Importing a form with JScript or VBScript code disables script operation, but the .js or .vbs files remain in the template file for reference when you replace the script s methods with Visual Basic .NET code. If you select the Create A New Form Template option, the project opens with an empty InfoPathProject1 form in design mode in front of Visual Studio s InfoPathProject1FormCode window, as shown in Figure 15-2. Solution Explorer displays the working file set created by the Toolkit.

click to expand
Figure 15-2: Creating a new form template with the default project name opens a new InfoPathProject1 template in design mode and displays the files added to the project by the Toolkit in Solution Explorer.

The Toolkit adds project references to the System namespace and the Microsoft.Office.Interop.InfoPath.SemiTrust namespace defined by the primary interop assembly DLL of the same name. Microsoft provides primary interop assemblies (PIAs), which are wrappers for Component Object Model (COM) type libraries, for most Office XP and Office 2003 applications. PIAs install in the global assembly cache (GAC) so they can be shared by all .NET projects. Don t infer from the presence of a PIA that an Office application is .NET-enabled; Microsoft Word 2003, Excel 2003, and InfoPath 2003 SP-1 were the only Visual Studio .NET “enabled Office applications when this book was written.

The Toolkit generates Visual Basic .NET code to create instances of the InfoPath Application and XDocument objects in a _Startup event handler. These two objects are the most important members of the InfoPath object model, which is described in detail in Chapter 16. Figure 15-3 shows the default Visual Basic .NET code added by the Toolkit ”commonly called an event-handling stub ”with empty lines removed and minor edits for readability. To have Solution Explorer show all files in the project after building and running the default Visual Basic .NET code, choose Project, Show All Files. Notice that the file set includes multiple references to extracted template files.

click to expand
Figure 15-3: Running the default Visual Basic .NET code generated by the Toolkit and choosing Project, Show All Files creates the files and file pointers shown here.

Navigating Project Folders

Visual Studio creates all projects in subfolders of your My DocumentsVisual Studio Projects folder by default. If you accept the default values in the New Project dialog box, click OK, select the Create A New Form Template option in the Microsoft Office Project Wizard s only screen, and click Finish, the template generates a set of files and subfolders in a My DocumentsVisual Studio ProjectsInfoPathProject1 folder, which contains only solution (.sln and .suo) files. Your working files, shown in Figure 15-3 s Solution Explorer, are in a nested InfoPathProject1 folder and its subfolders. The files that you deploy after building the project in the default debug mode are located in the My DocumentsVisual Studio ProjectsInfoPathProject1 InfoPathProject1inDebug folder. InfoPathProject1.xsn is the final template file, InfoPathProject1.dll is the managed code assembly, and InfoPathProject1.pdb contains the debugging symbols. When you compile release versions of your projects, .pdb symbols aren t generated.

Changing file names and locations after creating a project is a chancy process at best, so it s a good practice to decide on a final project name and the initial location for the project files before you start a new InfoPath project. Minimizing the length of the project s path makes it easier to check file locations in the file s Properties dialog box. The examples you create in this chapter run from project subfolders of a C:IPProjects projects folder and don t create separate subfolders for the solution (.sln and .suo) files.

Adding an Event Handler to a New Form

Your only access to InfoPath s COM objects that the InfoPath PIA exposes is through event handlers and subprocedures or functions invoked by event handlers. The _Startup event handler of the code behind the form declares two variables ” thisApplication and thisXDocument . These variables represent the current InfoPath form instance and its data source document. XDocument objects contain a UIObject , which has an Alert method to display InfoPath s standard alert message box. A button with a click event handler that opens an alert box is the simplest example of adding event-handling code behind an InfoPath form.

To add a button and an event handler that displays an alert, follow these steps.

Create a new project and add a button event handler

  1. Create a new C:IPProjects folder to store all InfoPath project examples you create in this chapter and in Chapters 16 and 17.
  2. Start Visual Studio, and choose Tools, Options to open the Options dialog box. Select the Environment node s Projects And Solutions item, and change the Visual Studio Projects Location to C:IPProjects. To enforce strong typing with all Visual Basic .NET projects, select the Projects node s VB Defaults item, and set Option Strict to On. Click OK to save your changes.
  3. Choose File, New, Project to open the New Project dialog box, expand the Microsoft Office InfoPath Projects node, and select the InfoPath Form Templates icon.
  4. Change the project s Name to IPEvents.Click More and clear the Create Directory For Solution check box to eliminate one subfolder level, as shown here:

    click to expand

  5. Click OK to close the dialog and open the Microsoft Office Project Wizard, leave the default Create New Form Template option, and click Finish to generate the project and open the IPEvents form in design mode.
  6. Add Option Explicit On and Option Strict On statements above the first Imports statement. It s a good practice to add Option Explicit On and Option Strict On because other programmers who work on your form might not have these defaults set.
  7. Give the focus to the IPEvents template, add a button control, and open its Properties dialog box. Leave the default Rules And Custom Code item in the Action drop-down list, change the Label value to Click Event Test, and set the ID value to btnClickEvent, as shown here:

    click to expand

  8. Click the Edit Form Code button to add the button s OnClick event handler to the IPEvents class as a Visual Basic subprocedure and return the focus to Visual Studio.
  9. Replace the ˜Write your code here comment in the event handler with
  10. thisXDocument.UI.Alert("Button OnClick event handler"), and observe the property and method options as you type each period.
  11. Press F5 to build and run the project, and click Yes in the message box, which opens a preview of the IPEvents form.
  12. Click the button to display the message in a standard InfoPath Alert message box, as shown here:

    click to expand

Note  

Restoring InfoPath templates that disappear
If you accidentally close the current InfoPath template instance, choose Tools, Open InfoPath or Project, Open InfoPath to restore it.

The event handler s < InfoPathEventHandler (MatchPath:="btnClickEvent", EventType:=InfoPathEventType.OnClick) > attribute delegates handling of the InfoPath OnClick event to the btnClickEvent_OnClick event handler. The e parameter s DocActionEvent interface has three properties: ReturnStatus , Source , and XDocument . The ReturnStatus property is a Boolean value that defaults to True and is useful for handing InfoPath events that accept return values and cancel the action if the return value is False . The Source property returns a read-only IXMLDOMNode instance that represents the form s current data source ” my:fields for the example at this point.

Note  

Copying and pasting code snippets
Your C:Microsoft PressIntroducing InfoPath 2003Chapter15IPEvents folder has text files that contain the code snippets you add to the event-handling procedures in the remaining exercises in this chapter. The file name is provided in the step that describes the code to be added.

The UI object s Confirm method provides the visual equivalent of a Windows forms message box and offers a choice of OK/Cancel, Yes/No, or Yes/No/Cancel buttons . You can use the return value of the message box to control program flow with an If ... Else ... End If construct. To change the alert to a confirmation message box, replace the alert statement you added in step 9 of the preceding procedure with the following statements or add them from Confirm.txt:

With thisXDocument
 If .UI.Confirm("The source is " + e.Source.baseName + _
 ". Do you want to continue?", XdConfirmButtons.xdYesNo) = _
 XdConfirmChoice.xdYes Then
 e.ReturnStatus = True
 .UI.Confirm("Continuation confirmed.", _
 XdConfirmButtons.xdOKCancel)
 Else
 e.ReturnStatus = False
 End If
End With

When you click the button, the upper confirm message box of Figure 15-4 opens. Click Yes to open the message box. Unfortunately, the Confirm method doesn t offer a single OK button choice to provide a more compact version of an alert.


Figure 15-4: Clicking Yes in the first (upper) confirm message box displays the lower one.


Working with Data Source Field Events

Changing data source field values or adding and deleting repeating form sections triggers the following three events:

  • OnBeforeChange Fires after an instruction to change a field value and prior to saving a new value to a field. If the event handler returns a false value to the ReturnStatus property of the DataDOMEvent argument, InfoPath cancels the field value change. Changing an XDocument node value triggers an OnBeforeChange event for deletion of the original value and insertion of the new value.
  • OnValidate Fires after OnBeforeChange and before OnAfterChange , and doesn t recognize return values. The DOM is read-only until execution exits your event handler, so this event is useful primarily for manipulating members of the Errors collection.
  • OnAfterChange Fires after changes have been applied to the cached copy of the data source. Like OnBeforeChange , the OnAfterChange event fires twice when you update a field value.

Adding field event handlers requires a data source and controls to change values. Follow these steps to convert the data source of your form to a simple XML document with fields of multiple data types, and add controls to the form s layout table.

Add a data source and controls to the form

  1. In the form s design view, choose Tools, Convert Main Data Source to start the Data Source Wizard.
  2. In the first wizard screen, click Browse, and open C:Microsoft PressIntroducing InfoPath 2003Chapter15IPEventsEventsData.xml. Click Next, and then click Finish to substitute the EventData document structure and its default values for the empty my:fields data source. Click Yes in the message box that asks whether you want to update expressions automatically. Replacing the data source adds several new namespaces to the Public Class IPEvents attribute.
  3. Open the Data Source task pane, change the data type of the date1 field to Date (date) and the dateTime1 field to Date And Time (dateTime), and change the remaining fields ending in 1 to the data type represented by their name . Leave all fields ending in 2 as the default Text (string) data type.
  4. Add a two-column, five-row layout table under the button, and drag the element fields to the table cells in left-to-right , top-to-bottom sequence. Drag the eventType attribute to the right of the button to add a label and text box.
  5. Click Preview This Form, click Yes if the message box asks whether you want to update expressions in the code, and then click Preview This Form again to build and run the project. Your form preview appears as shown here:

    click to expand

Responding to OnAfterChange Events

True/False (Boolean) fields are a good choice for an initial OnAfterChange event- handler coding exercise, because the code is very simple. The event handler updates the value of the Boolean 2 text box with a value that corresponds to the state of the Boolean 1 check box. You specify the target node ”an IXMLDOMNode object ”by applying the thisXDocument.DOM.selectSingleNode("/eventsData/boolean2") method and then setting the target node s text property value to the text property value of the event handler s e.Source parameter. The code detects the e.operation = Delete condition and exits, so only Insert operations are processed .

It s a good programming practice to add structured exception handling to any event handler that might generate a run-time error, because InfoPath projects disregard some run-time exceptions. In this case, your code fails silently, and you might overlook an occasional or even a repetitive exception. Adding a stack trace to the error handler s message supplies the line number on which the error occurred.

Follow these steps to complete the boolean1 event handler with a Try...Catch...End Try block for exception handling.

Add an event handler for the boolean2 field

  1. Close the preview window to return to design view. Right-click the boolean1 field in the Data Source list, and choose Properties from the shortcut menu to open its Properties dialog box. Click the Validation And Event Handlers tab, and select OnAfterChange in the Events drop-down list, as shown here:

    click to expand

  2. Click Edit to add the boolean1_OnAfterChange event handler to the code and return the focus to Visual Studio, as shown here:

    click to expand

  3. Remove the empty lines and, optionally , the comments, and add the following code from Boolean1.txt after the event handler s End If line to update the boolean2 field with the state of the Boolean 1 check box:

    If e.Operation = "Delete" Then
     Return
    End If
    Try
     Dim nodTarget As IXMLDOMNode = _
     thisXDocument.DOM.selectSingleNode("/eventsData/boolean2")
     nodTarget.text = e.Source.text
    Catch excBool As Exception
     thisXDocument.UI.Alert(excBool.Message + _
     excBool.StackTrace.ToString)
    End Try
    
  4. Press F5 to build and run the project and open a preview window, and test the event handler by clicking the Boolean 1 check box a few times.
  5. Give Visual Studio the focus, position the insertion point on the first If line, and press F9 to set a breakpoint.
  6. Give the preview window the focus, and then change the Boolean 1 check box s state and halt execution at the breakpoint. Press F11 to step through the procedure, observe that the event fires twice but is processed only once, and then clear the breakpoint by pressing F9 on the highlighted line or by choosing Debug, Clear All Breakpoints.

Nillable Date ( date ) and Date And Time ( dateTime ) fields present a challenge when you need to convert the Variant data type (Object) of dates returned by the event handler s e.Source.nodeValue property to the DateTime data type, which enables easy ISO 8601 formatting with the ToString( s ) method and date arithmetic. To avoid run-time errors, you must test for e.Source.text values that result from entering empty date values in the date picker s text box.

To create the date1_OnAfterChange event handler, follow these steps.

Add an event handler for the date1 field

  1. Repeat steps 1 and 2 for of the preceding procedure for the date1 field.
  2. Add the following code from Date2.txt after the event handler s End If line to update the date2 field with the date you select in the date1 date picker control:

    If e.Operation = "Delete" Then
     Return
    End If
    'Specify date1 as the field to be updated
    Dim nodTarget As IXMLDOMNode = _
     thisXDocument.DOM.selectSingleNode("/eventsData/date2")
    If e.Source.text = "" Then
     'Date is nil
     nodTarget.text = ""
    Try
     'Format the DateTime object as ISO 8601
     Dim strDate As String = _
     CType(e.Source.nodeValue(), DateTime).ToString("s")
     'Remove the time value
     nodTarget.text = Left(strDate, InStr(strDate, "T") - 1)
     'Select the eventsData node
     nodTarget = nodTarget.parentNode 
    'Set the attribute value
     nodTarget.attributes(0).text = "date1 Changed"
    Catch excDate As Exception
     'Catch runtime errors
     thisXDocument.UI.Alert(excDate.Message + _
     excDate.StackTrace.ToString)
    End Try
    
  3. Press F5 to build and run the project and open a preview. Select a date, and verify that the Date 2 text box displays an ISO 8601 date.
  4. Add a breakpoint at the second If statement, and clear the Date 1 text box. Press F11 to step through the procedure, which executes three times, and then clear the breakpoint.

If you want to see an exception-handling alert, comment the second Return statement, add a date value, clear the date value, and press Tab. You ll receive two error messages similar to the one shown in Figure 15-5.

click to expand
Figure 15-5: A common source of InfoPath event-handler exceptions is attempts to cast a nondate Variant value to the DateTime type, as illustrated by this alert.

Handling OnBeforeChange Events

The OnBeforeChange event lets you intercept changes, apply business logic to the proposed new value, let users decide whether to make the change with a confirm message box, send a ReturnMessage to an alert message box, or any combination of these actions. Your code must handle multiple events correctly to avoid reoccurring confirm message boxes. In this procedure, a blnHasChanges flag determines whether the value has been changed by a previous OnBeforeChange Insert event. This procedure s event- handler code isn t prone to run-time errors, so exception handling isn t implemented.

Follow these steps to add the dateTime1_BeforeChange event handler.

Add an OnBeforeChange event handler for the dateTime1 field

  1. In InfoPath design view, right-click the dateTime1 field in the Data Source task pane, and choose Properties from the shortcut menu to open its Properties dialog box. Click the Validation And Event Handlers tab, and select OnBeforeChange in the Events drop-down list.
  2. Click Edit to add the dateTime1_OnBeforeChange event handler to the code and return the focus to Visual Studio.
  3. Remove the empty lines and, optionally, the comments, and add a Private blnHasChanged As Boolean statement immediately after the Private thisApplication As Application statement.
  4. Add the following code from DateTime2OBC.txt after the event handler s End If line to display a confirm message box with Yes/No buttons and an alert if the user elects to abandon the changes:

    If e.Operation = "Delete" Then
     Return
    End If
    If blnHasChanged Then
     blnHasChanged = False
     Return
    End If
    If thisXDocument.UI.Confirm("Do you want to update " + _
     "dateTime2 and dateTime1?", XdConfirmButtons.xdYesNo) = _
     XdConfirmChoice.xdYes Then
     e.ReturnStatus = True
    True
     blnHasChanged = 
     'Cancel the update
     e.ReturnStatus = False
     blnHasChanged = False
     e.ReturnMessage = _
     "DateTime updates were canceled by the user."
    End If
    
  5. Press F5 to open a preview, and change the Date Time 1 date picker value to open a confirm message box. Click No to display the alert with the return message.
  6. Add a breakpoint at the first If statement, change the date, and trace execution to verify that the event fires twice but is processed only once. If you delete the date in the text box and press Tab, the event executes three times, but the flag prevents the confirm message from appearing twice.

Taking Action Based on the Value of Another Field

The following procedure displays ISO 8601 “formatted date and time values for local time or Universal Time Coordinate (UTC) in the Date Time 1 text box, depending on the state of the Boolean 2 check box. The code is similar to that for the date2_OnAfterChange event handler, except for addition of the boolean2 field value test and code to change local to UTC time, as shown here:

Dim datNodeValue As DateTime = _
 CType(e.Source.nodeValue(), DateTime)
Dim strNodeValue As String
'Get the value of the boolean2 node
Dim nodIsUTC As IXMLDOMNode = _
 thisXDocument.DOM.selectSingleNode("/eventsData/boolean2")
If nodIsUTC.text = "true" Then
 'Use Universal Coordinated Time
 strNodeValue = datNodeValue.ToUniversalTime.ToString("s")
Else
 'Use local time
 strNodeValue = datNodeValue.ToString("s")
End If

To add the dateTime1_OnAfterChange event handler, follow these steps.

Add an OnAfterChange event handler for the dateTime1 field

  1. Close the preview window to return to design mode. Right-click the dateTime1 field in the Data Source task pane s list, and choose Properties from the shortcut menu to open its Properties dialog box. Click the Validation And Event Handlers tab, and select OnAfterChange.
  2. Click Edit to add the dateTime1_OnAfterChange event handler to the code and return the focus to Visual Studio.
  3. Paste the code from DateTime2OAC.txt after the event handler s End If line to set the value of the dateTime2 field.
  4. Test the event handler with Date Time 2 date picker values and empty dates. Clicking the Boolean 1 check box to change the date format. The form, with a UTC date and time, appears as shown here:

    click to expand

  5. Optionally, set a breakpoint, and trace execution of the code when you change a Date Time 1 value.


Adding Managed Code to an Existing Form

Creating a new InfoPath project from an existing template is a simple, two-step process if your form doesnt incorporate JScript or VBScript code. Moving to managed code disables the script, and you must rewrite all event handlers in Visual Basic .NET or C#. If your template contains more than 100 lines of script, conversion probably isnt justified unless you need to implement features that the .NET Framework supports and script doesnt. As an example, you need the .NET Framework and the Microsoft Web Services Enhancements (WSE) 2.0- add-on to connect to secure Web services that implement SOAP message encryption and require digital signatures. Digitally signed SOAP messages supplementbut dont replacedigital signatures applied to forms.

RSS 2.0 data documents have a repeating item section with a pubDate field that requires a RFC1123-formatted date string. Repeating sections introduce you to the use of the IXMLDOMNodeList object, which contains a collection of repeating IXMLDOMNode elements. The objects length property returns the number of instances of the repeating section. You can specify the instance you need by an index thats less than the length valuefor example, NodeList1(NodeList1.length -1) points to the last section.

Adding the current time in RFC1123 format when inserting a new section improves data entry efficiency and minimizes typographic errors. The DateTime.UtcNow property returns the current UTC time, and the ToString(R) method returns the RFC1123 pattern. Its a common practice to add RSS 2.0 items in reverse date/time order (last in, first out) with Insert Above operations, but users can insert new sections in any arbitrary sequence. Thus your code must test all sections for the presence of a pubDate field value and add the current date/time value if its missing.

To add the RFC1123 date and time to a copy of the Rss2v4.xsn template from Chapter 10, Adding Views to a Template, follow these steps.

Create the Rss2v4Events project and add the event-handling code

  1. Start Visual Studio, and choose File, New, Project to open the New Project dialog box. Click the InfoPath Form Template icon, type Rss2v4Events as the Name and, if you didnt set the default folder, type C:IPProjects as the Location.
  2. Click OK to open the Microsoft Project Wizard. Select the Open Existing Form Template option, click Browse, navigate to C:Microsoft PressIntroducing InfoPath 2003Chapter15Rss2v4Events, and double-click Rss2v4 (Ch10).xsn.
  3. Click Finish. In the message box that appears, assuring you that the original template wont be modified, click OK to open the FormCode.vb window and an InfoPath design mode instance.
  4. Add Option Explicit On the Option Strict On as the first two lines of code.
  5. Activate the Data Source task pane, right-click the item section in the Data Source task pane list, and choose Properties from the shortcut menu to open the Properties dialog box. Click the Validation And Event Handlers tab, select the OnAfterChange event, and click Edit to add the item_OnAfterChange event handler.
  6. Add the following code from Rss2v4Events.txt, which is located in the same folder as the original template, below the End If statement:

    If e.Operation = "Delete" Or e.Site.nodeName <> "item" Then
     Return
    End If
    Try
     Dim strXML As String = e.Source.xml
     'Create a list of pubDate node(s)
     Dim lstItems As IXMLDOMNodeList = _
     e.Source.selectNodes("//pubDate")
     'Check all pubDate nodes
     Dim intItem As Integer
     For intItem = 0 To lstItems.length - 1
     Dim nodLastItem As IXMLDOMNode = lstItems(intItem)
     nodLastItem.selectSingleNode("//pubDate")
     If nodLastItem.text = "" Then
     'Get current system time as UTC if pubDate is empty
     Dim datNow As DateTime = DateTime.UtcNow
     'Add the RFC1123 date
     nodLastItem.text = datNow.ToString("R")
     End If
     Next intItem
    Catch excInsert As Exception
     thisXDocument.UI.Alert(excInsert.Message + _
     excInsert.StackTrace)
    End Try
    
  7. Press F5 and click Yes to build the project and open a preview window. Insert sections above, below, and between other sections to verify that the event handler performs as expected, as shown here:

    click to expand

The e.Site.nodeName <> "item" test in the first statement verifies that the event originated from inserting an item node and not from the change to the pubDate field value. Events lower in the XML documents hierarchy percolate to the root element, a process called event bubbling . For more information about the Site object and event bubbling, search the InfoPath SDK Documentation for the term bubbling (include the quotation marks).


Managing Project Relocation and Deployment

The following sections show you how to handle errors that occur when you open a form from a project template in a location other than the ProjectName folder, change the location of the InfoPath project files, create a release version of your template, and publish production templates.

Dealing with Template Cache Conflicts

You can create and save a sample data document from the Fill Out A Form task pane in the project s InfoPath design window. In this case, InfoPath use the manifest.xsf file in the project folder as the template and adds it to the local form template cache. Alternatively, you can emulate opening a production Form1 by double-clicking the template file that contains the project s assembly DLL ”IPEvents.xsn for this example ”in the ... ProjectName inDebug folder. Opening Form1 from this folder displays the Form Conflict dialog box shown in Figure 15-6. If you re developing the form template, click the Keep Form On Your Computer button to use the manifest.xsf version. After you complete the form s design, click the Replace Form On Your Computer button to use the FormName.xsn template.

click to expand
Figure 15-6: This message box appears when you attempt to open a new Form1 from the template s .xsn file in the ...inDebug folder and the manifest.xsf version of the template is in the local cache.

Copying an InfoPath Project to a New Location

Visual Studio users appreciate easy XCopy deployment of their Windows and Web forms projects; moving an entire InfoPath project to a new folder is as easy as using Save As with a conventional template. You can copy the entire project folder to another location and continue development without making any changes to the project. When you open the project, you might receive a warning message that advises you to publish the form from its new location. You can ignore the warning message prior to creating a release version of the project and publishing the template for production use.

Creating a Release Version of the Project

By default, Visual Studio creates and runs InfoPath projects in debug configuration. The debug version of the assembly ( ProjectName .dll) is slightly larger than the release version, and debug versions of large projects execute more slowly than release versions. The debug symbols (.pdb) file adds unnecessary bulk to the template file. Before you publish a production form, create the release version by choosing Build, Configuration Manager to open the Configuration Manager dialog box. Select Release in the Active Solution Configuration drop-down list, as shown in Figure 15-7, and click OK.

click to expand
Figure 15-7: Changing the InfoPath project s configuration from Debug to Release generates a production version of the project without a ProjectName .pdb file.

Run the project to create a ... ProjectName inRelease folder, which contains release versions of your template and its assembly. The completed projects in your C:Microsoft PressIntroducing InfoPath 2003Chapter15IPEventsIPEvents and ...Rss2v4EventsRss2v4Events folders have debug and release versions. Debug is the default configuration for these projects.

Publishing Forms with Managed Code

The process of publishing an InfoPath template with managed code to shared folders, Web sites, and SharePoint forms libraries is identical to publishing a template with or without script. Choose Tools, Publish Form to build the form and start the Publishing Wizard. Complete the wizard s steps, as described in Chapter 12, Publishing Form Templates. The template file contains the assembly DLL. InfoPath publishes your template s release version, if it exists; if not, InfoPath publishes the debug version.

Like forms containing script or ActiveX controls, Domain is the default security mode for forms containing managed code. If your code accesses local computer resources outside of the form, requires cross-domain permissions, or includes references to custom .NET assemblies that aren t signed by Microsoft, you must specify Full Trust as the security mode and specify a code signing certificate to digitally sign the form on the Security tab of the Form Options dialog box. Alternatively, you can deploy a custom-installed template to users computers.


Summary

InfoPath projects substitute .NET managed code for script to implement business logic that declarative programming cant handle. You must have Visual Basic .NET 2003 Standard or Visual Studio .NET 2003 Professional or later and the Toolkit for InfoPath 2003 installed to create InfoPath projects with Visual Basic .NET code. This book uses Visual Basic .NET for all programming examples, because Office developers can leverage their VBA skills to write InfoPath event handlers and utility functions or subprocedures.

The Toolkit creates an event-handling subprocedure stub with default code when you specify an event handler by choosing Tools, Programming. Clicking Edit with an event selected on the Validation And Event Handlers tab of a field or sections Properties dialog box also generates a stub. You add code to implement business logic to the stub to complete the event handler. Adding structured exception handling to the code you write ensures that you catch run-time errors that otherwise might not be evident.

Debug is Visual Studios default configuration for InfoPath projects. To publish a production InfoPath project, you use the Configuration Manager to change to Release configuration, and rebuild your project. You publish the project by choosing Tools, Publish Form in Visual Studio to run InfoPaths Publishing Wizard. The resulting .xsn file includes the .NET assembly that contains the projects MSIL code. Users must have the .NET Framework 1.1 runtime installed on their computers to JIT-compile the MSIL to executable code.


Q A

1.  

Does InfoPath trigger more than the three events discussed in this chapter?

yes, but onbeforechange , onvalidate , and onafterchange are the most frequently used event handlers in infopath projects. the programming option on infopath s tools menu provides on load event, on switch view event, on context change event, and on sign event items, which generate the corresponding event handlers. the onsubmitrequest and onversionupgrade events let you write code to customize the form submission and upgrade processes. sp-1 adds several more events to infopath s repertoire; the next two chapters have code examples for the events not covered in this chapter.

2.  

Why do InfoPath projects require programming MSXML objects rather than .NET s more versatile System.Xml classes?

infopath 2003 sp-1 is a conventional windows application that exposes com objects to provide access to application and xdocument objects. you re limited to manipulating infopath com objects that managed code accesses through the infopath pia. infopath, not msxml, provides the ixmldom interfaces that you program with .net code. sp-1 exposes its classes and interfaces as automation objects, so visual basic 6 or vba code can manipulate infopath objects by adding a reference to the microsoft infopath 1.0 type library.

3.  

Can I use .NET s System.Xml classes to manipulate the data document independent of InfoPath?

yes, you can retrieve the cached xml document s contents as a string at any point in the editing process with a thisxdocument.dom.xml instruction. after you add a reference to system.xml.dll and an imports system.xml statement to infopath s default formcode.vb, you can populate an in-memory xmldocument instance with a docxml.loadxml(thisxdocument.dom.xml) statement. you can modify docxml , navigate it with an xpathnavigator object, import it to a dataset (if the document is relational), and transform it with extensible stylesheet language transformation (xslt). your form must be fully trusted to save the modified document to an .xml file with the xmltextreader class.

4.  

Are there any other InfoPath UI objects that I can program with .NET code?

yes. the xdocument.ui object provides a showmodaldialog method that displays a dialog box that you define using a conventional html file, which can contain script. the form must be fully trusted to open the dialog box. the infopath 2003 sdk s documentation offers additional implementation details for the method; type showmodaldialog as the search term and follow the links. you also can display the e-mail message and signature dialog boxes with the showmailitem and showsignaturedialog methods.

Answers

1.  

Yes, but OnBeforeChange , OnValidate , and OnAfterChange are the most frequently used event handlers in InfoPath projects. The Programming option on InfoPath s Tools menu provides On Load Event, On Switch View Event, On Context Change Event, and On Sign Event items, which generate the corresponding event handlers. The OnSubmitRequest and OnVersionUpgrade events let you write code to customize the form submission and upgrade processes. SP-1 adds several more events to InfoPath s repertoire ; the next two chapters have code examples for the events not covered in this chapter.

2.  

InfoPath 2003 SP-1 is a conventional Windows application that exposes COM objects to provide access to Application and XDocument objects. You re limited to manipulating InfoPath COM objects that managed code accesses through the InfoPath PIA. InfoPath, not MSXML, provides the IXMLDOM interfaces that you program with .NET code. SP-1 exposes its classes and interfaces as Automation objects, so Visual Basic 6 or VBA code can manipulate InfoPath objects by adding a reference to the Microsoft InfoPath 1.0 Type Library.

3.  

Yes, you can retrieve the cached XML document s contents as a String at any point in the editing process with a thisXDocument.DOM.xml instruction. After you add a reference to System.Xml.dll and an Imports System.Xml statement to InfoPath s default FormCode.vb, you can populate an in-memory XmlDocument instance with a docXML.LoadXml(thisXDocument.DOM.xml) statement. You can modify docXML , navigate it with an XPathNavigator object, import it to a DataSet (if the document is relational), and transform it with Extensible Stylesheet Language Transformation (XSLT). Your form must be fully trusted to save the modified document to an .xml file with the XmlTextReader class.

4.  

Yes. The XDocument.UI object provides a ShowModalDialog method that displays a dialog box that you define using a conventional HTML file, which can contain script. The form must be fully trusted to open the dialog box. The InfoPath 2003 SDK s documentation offers additional implementation details for the method; type showmodaldialog as the search term and follow the links. You also can display the e-mail message and signature dialog boxes with the ShowMailItem and ShowSignatureDialog methods .


On Your Own

Heres an additional exercise that uses the Rss2v4Events.xsn template to demonstrate event-handling code reuse:

  1. Open the Default Values dialog box, and select the item field check box to make one item instance required.
  2. Open a preview window, and observe that the Pub Date text box is empty, because the OnAfterChange event doesnt fire in this case.
  3. Choose Tools, Programming, On Load Event to add an OnLoad event-handling stub.
  4. Copy the Try...Catch...End Try block only from the item_OnAfterChange event handler to the OnLoad stub. The OnLoad event fires once when you open the form, so you dont need the tests that precede the Try statement.
  5. The DocReturnEvent parameter doesnt provide an OnLoad property, but it does have an XDocument property that serves a similar purpose. Change the Dim lstItems As IXMLDOMNodeList = e.Source.selectNodes("//pubDate") statement to Dim lstItems As IXMLDOMNodeList = e.XDocument.DOM.selectNodes ("//pubDate") to substitute XDocument for Source .
  6. Open a preview window, and verify that the Pub Date text box now displays the current date and time.




Introducing Microsoft Office InfoPath
Introducing Microsoft Office InfoPath 2003 (Bpg-Other)
ISBN: 0735619522
EAN: 2147483647
Year: 2006
Pages: 248

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net