Visual Studio Tools for Office: Using Visual Basic 2005 with Excel, Word, Outlook, and InfoPath

InfoPath uses a declarative, per-form, event-driven approach to programming customized forms. That is, code consists of declarations that define which event handlers are to be invoked when form elements or data elements source events. Code in InfoPath is always written behind a specific form template; it is not possible to write "application-level" code that is executed for all form templates. Code runs when events are raised that have been declaratively handled by event handlers.

There are two "root" objects in the InfoPath object model. The Application object is the root of the runtime object model; every programmable object in InfoPath can be accessed through the Application object. The other "root" object is the ExternalApplication object. The ExternalApplication object is useful for automating InfoPath by an automation executable rather than from code behind a form, as shown in Listing 12.1. This chapter, however, discusses only how to create code behind a form and does not cover automation executables further.

When you create an InfoPath form template project in VSTO, Visual Studio automatically generates a FormCode.vb file for you to add the code behind the form. It generates some boilerplate code for you to get started containing methods called when the InfoPath form starts and shuts down, as shown in Listing 12.2.

Listing 12.2. The FormCode.vb File

Namespace PurchaseOrder ' <Attribute omitted)> _ Public Class PurchaseOrder Private thisXDocument As XDocument Private thisApplication As Application Public Sub _Startup(ByVal app As Application, _ ByVal doc As XDocument) thisXDocument = doc thisApplication = app ' You can add more initialization code here. End Sub Public Sub _Shutdown() End Sub End Class End Namespace

When the InfoPath form starts, InfoPath calls the _Startup method and passes in an Application and XDocument object. By default, the managed class that represents the InfoPath form stashes away references to these objects in thisApplication and thisXDocument so that your event handlers and other code can use them later. The same Application object is passed to all executing forms. The XDocument object is a specific instance that refers to the form to which it is passed.

Note

Although you now have references to the Application and XDocument objects in the _Startup method, do not make any InfoPath object model calls yet. Calling the InfoPath object model is not allowed in either the _Startup or _Shutdown method. During these methods, calls to the object model are unavailable because the form is either still in the process of being created or is being terminated.

Event-Based Programming

While users are filling out the form, various user actions directly or indirectly trigger events. Take the OnLoad event, for example. To handle (that is, register an event handler to be called when the event occurs) the OnLoad event, select Tools > Programming > On Load Event in the InfoPath designer window. Notice that the InfoPath designer automatically creates a code stub and handles the event. Whenever you add an event handler to an InfoPath form, you always do it using the InfoPath designer window and its associated menusnever by using any commands within Visual Studio.

The code below shows a code stub generated by InfoPath to handle the OnLoad event:

<InfoPathEventHandler(EventType:=InfoPathEventType.OnLoad)> _ Public Sub OnLoad(ByVal e As DocReturnEvent) ' Write your OnLoad event handler code here End Sub

You will notice immediately that an InfoPath event is not connected in the traditional .NET way of creating a new delegate and adding that delegate to an object that raises the event using the WithEvents, Handles, or AddHandler. Instead, InfoPath events are connected via attributes; the InfoPath runtime reflects on the attributing of methods in your code to determine events that are handled by your code and the methods to call when an event is raised. In this case, the attribute InfoPathEventHandler is added to your OnLoad event handler. This attribute is constructed with EventType:=InfoPathEventType.OnLoad, which tells the InfoPath runtime to raise the OnLoad event on this attributed method.

Let's add some code to our OnLoad handler to restrict users from creating a new form outside business hours. (Note that this does not restrict editing existing formsjust creating new ones.) Listing 12.3 shows the new OnLoad handler.

Listing 12.3. On OnLoad Handler That Restricts Creation of New Forms Outside Business Hours

<InfoPathEventHandler(EventType:=InfoPathEventType.OnLoad)>_ Public Sub OnLoad(ByVal e As DocReturnEvent) If (DateTime.Now.Hour < 8 _ Or DateTime.Now.Hour > 17 _ Or DateTime.Today.DayOfWeek = DayOfWeek.Saturday _ Or DateTime.Today.DayOfWeek = DayOfWeek.Sunday) _ And thisXDocument.IsNew Then thisXDocument.UI.Alert("Sorry, you can only create a new" & _ " mortgage application 8am-5pm, Monday through Friday.") e.ReturnStatus = False End If End Sub

Note

The IsNew property and the UI.Alert method both require the domain security level.

All form events in InfoPath are cancelable through code. In this OnLoad event example, setting the ReturnStatus property to False on the DocReturnEvent object e tells InfoPath to fail the OnLoad event (and, thus, fail loading the form) when the event handler has returned. The default value is true.

Previewing

Press F5 or choose Start from the Debug menu in Visual Studio, and the code in Listing 12.3 will be compiled and start running in InfoPath's preview form mode. Depending on what time and day you run the code in Listing 12.3, you may not be able to fill out the form!

Suppose that you are working latelater than 5 p.m., at least. The OnLoad handler will not allow you to create a new form, because thisXDocument.IsNew always returns TRue when you press F5 or choose Start from the Debug menu. How can you force the form to look like an existing form? If you double-click the template.xml file (located in the Visual Studio project folder), you will start InfoPath and cause InfoPath to think that it is opening an already created form. The template.xml file is used internally by InfoPath when creating a new form after you double-click the .XSN form template. Opening this file directly, however, tricks InfoPath into thinking that it is opening an existing or previously saved form.

Previewing is a very useful technique when designing and debugging a form, but it is important to realize that previewing a form causes the following side effects:

  • If you choose the Tools menu and then the Preview submenu, you will see a With Data File menu item. Previewing with a data file is never considered to be creating a new form. Instead, it is considered to be viewing an existing form.

  • Previewing does not allow the user to save changes.

  • InfoPath will not grant the full-trust security level to a previewed formonly the domain or restricted security level.

So in addition to previewing, you should use your form in a production environment with InfoPath running by itself to verify that everything works properly.

Категории