Form Events, Properties, and Methods


Data source events prove very useful for ensuring that data constraints are maintained and taking action when the user makes changes to data. InfoPath also provides a form object model that you can use to customize the behavior of your form further. Some of the scenarios the form object model enables are as follows:

  • Consider the earlier example of a form that displays interest-rate quotes to the user filling out the form. You might want to create an Administrator view of the form that allows authorized people to change the quoted interest rates.

  • You might want to integrate context-sensitive help as the user navigates through your form.

  • You might want a custom task pane to extend and further customize the experience of filling out the form.

  • You might want to customize how your forms are saved and submitted. Instead of submitting via a data connection or allowing a user to save to any location, you could restrict where the form is saved.

The remainder of this chapter examines the form object model and discusses how to create a custom task pane for a form. The InfoPath forms object model contains many events, properties, and methods. This book discusses only some of the most commonly used parts of the InfoPath forms object model.

Button Events and View Switching

A view is a surface on which you insert controls and form content in the designer; it is what the user looks at while filling out the form. Lengthy forms are often composed of multiple views. In addition, data being edited can be displayed in multiple views. You may have a timecard that can be viewed in a less-detailed view for someone who wants to enter information quickly, for example, and a more-detailed view may be available for a manager trying to generate end-of-pay-period reports. You can find a list of available views for the data being edited in InfoPath's View menu. A user can switch between views at will.

Switching between views might not be the desired behavior, especially if your views are supposed to be sequential or have dependencies. While designing your form, you have an option to remove the name of a view from the View menu and to prevent users from choosing a particular view. Then the code behind the form can switch views programmatically by using the XDocument.View.SwitchView method.

Suppose that you have a mortgage application with two views. The first view allows the user to fill out contact information: name, phone numbers, and so on. When all the required contact information is filled out, the user can click the Go to Mortgage Details button. You can add a button to the form by selecting the Controls task pane in the InfoPath form design view and dragging a button onto the form designer. If you right-click the button and choose Properties, you can open the Properties dialog box, shown in Figure 12.10.

Figure 12.10. Creating a button with the form designer.


We want this button to switch to another view to display the mortgage details, but only if the first-name and last-name text boxes are filled on the contact information view. We can do this by clicking the Edit Form Code button in the Properties dialog box, which causes Visual Studio to emit an event handler for the OnClick event raised by the button.

Listing 12.7 shows code for the OnClick event handler that switches the view. Because this is not a data event but a forms event, the event argument object DocActionsEvent does not refer to the data nodes that we are interested in checking before we switch the view. The code gets to the data nodes by querying the XML data source using an XPATH query and then verifies that the strings that come back are valid before changing views.

Listing 12.7 uses the XDocument object's DOM property to access an IXMLDOMDocument object. Then it uses the IXMDOMDocument object's selectSingleNode method to get a node by passing the XPATH query strings to get to FirstName and LastName. Finally, it examines the retrieved node's text property to see whether the FirstName and LastName fields have been filled in.

Listing 12.7 also uses two other methods from XDocument. The XDocument object's UI property returns a UI object. The UI object's Alert method displays a simple message box within InfoPath. The XDocument object's View property returns a View object. The View object represents the currently active view in the form. Listing 12.7 uses the View object's SwitchView method to change to another view if the FirstName and LastName data nodes have been entered.

Listing 12.7. An OnClick Event Handler for a Button That Switches the View

<InfoPathEventHandler(MatchPath:="GoToDetailsButton", _   EventType:=InfoPathEventType.OnClick)> _ Public Sub GoToDetailsButton_OnClick(ByVal e As DocActionEvent)   Const FirstNameXPath As String = "/my:myFields/my:FirstName"   Const LastNameXPath As String = "/my:myFields/my:LastName"   Dim mainData As IXMLDOMDocument = thisXDocument.DOM   If String.IsNullOrEmpty( _     mainData.selectSingleNode(FirstNameXPath).text) Or _     String.IsNullOrEmpty( _     mainData.selectSingleNode(LastNameXPath).text) Then     thisXDocument.UI.Alert("Please fill in first and last name.")   Else     thisXDocument.View.SwitchView("Mortgage Details")   End If End Sub 


The OnContextChange Event and the Custom Task Pane

Another way to write code to handle form changes is to use the XDocument object's OnContextChange event. Exactly what do we mean by context?

The user can be interacting with only one control at a time; mouse clicks or key presses are handled by the control that has the focus. The context of a form is the data source node bound to the control that has the focus.

Consider the example of a contact-information form. Each text box is bound to a particular node in the data source. As the user filling out the form uses the mouse or keyboard to move the focus from one control to the next on the form, context changes to a different data node, and the XDocument object's OnContextChange event is raised.

You could have more than one control bound to the same data node. In that case, if the user were to change the focus from one control to another bound to the same data node, the context change event would not raise, because context has not changed. In a repeating control, the OnContextChange event is raised when focus is changed from row to row. The OnContextChange event does not indicate the new row position, however.

Creating a Custom Task Pane

A common way to use the OnContextChange event is to integrate a dynamic help system into a form. By detecting when the form is editing a different data node, we can provide help for the data node being edited in the task pane. The first thing we need to do is enable the custom task pane for this form. Choose Form Options from the Tools menu of the InfoPath designer window, and select the Advanced tab of the Form Options dialog box, as shown in Figure 12.11.

Figure 12.11. Enabling and adding resources to the custom task pane.


Using the Advanced tab, you can enable the custom task pane and add HTML files as resource files that can be displayed in the task pane. Click the Resource Files button to bring up the Resource Files dialog box. Click the Add button to add HTML files as resources to the InfoPath form. For this example, we add three HTML files: one named generalHelp.htm, a second named nameHelp.htm, and a third named phoneHelp.htm. Note that as you add the HTML files, they display in Solution Explorer in Visual Studio.

After you have added several HTML files to the form, you can handle the OnContextChange event to display the appropriate HTML file in the task pane for a particular context. To generate a handler for the OnContextChange event, choose the On Context Change Event command from the Programming menu in the Tools menu of the InfoPath designer window. Listing 12.8 shows an OnContextChange event handler that switches among generalHelp.htm, nameHelp.htm, and phoneHelp.htm in the task pane, depending on the current data node.

Listing 12.8. An OnContextChange Event Handler That Switches the HTML Shown in the Task Pane

<InfoPathEventHandler( _   EventType:=InfoPathEventType.OnContextChange)> _ Public Sub OnContextChange(ByVal e As DocContextChangeEvent)   If e.Type = "ContextNode" Then     Dim helpTaskPane As HTMLTaskPane = _       CType(thisXDocument.View.Window.TaskPanes(0), HTMLTaskPane)     Dim navigateTo As String = "generalHelp.htm"     Dim thisNodeName As String = e.Context.nodeName      If thisNodeName = "my:FirstName" Then       navigateTo = "nameHelp.htm"     ElseIf thisNodeName = "my:LastName" Then       navigateTo = "nameHelp.htm"     ElseIf thisNodeName = "my:HomePhone" Then       navigateTo = "phoneHelp.htm"     ElseIf thisNodeName = "my:WorkPhone" Then       navigateTo = "phoneHelp.htm"     End If     helpTaskPane.Navigate(navigateTo)   End If End Sub 


If you preview this form, you will see that as you select different text boxes, the task pane displays the appropriate HTML files, as shown in Figure 12.12.

Figure 12.12. The custom task pane at runtime.


The code in Listing 12.8 checks the DocContextChangeEvent object's Type property to verify that it is "ContextNode". InfoPath supports only a type of "ContextNode" as of Service Pack 1, but other values may be introduced in future versions of InfoPath. As a result, the check for "ContextNode" is recommended for forward-compatibility reasons.

You probably noticed that the InfoPath object model exposes an array of task panes. The custom task pane is always located at index 0. Other indices reference built-in task panes available while filling out a form. Index 4, for example, is the Help task pane.

Note

Forms in the restricted security level can access the task panes collection, but reading the Context property requires at least the domain security level.


Focus Versus Selection

What if you want to determine the current context in some event handler other than an OnContextChange handler? The XDocument's View property returns a View object. The View object has a GetContextNodes method that can be called from any event handler. It returns a collection of all the XML nodes that are in contextnot just the node bound to the control with the focus, but all its parent nodes in the data source tree as well.

The View object also provides a GetSelectedNodes method that returns the collection of XML nodes bound to the selected controls. This is a subtle distinction: Only one control can have the focus at any time, but a user can select multiple controls.

You might be tempted to use the GetSelectedNodes or GetContextNodes method in a button-click handler. Unfortunately, this does not work; as soon as the user clicks the button, the focus and selection change to the button itself.

Note

GetContextNodes and GetSelectedNodes both require at least the domain security level.


Setting Selection

Two other useful methods on the View object are the SelectNodes and SelectText methods. SelectText takes a single IXMLDOMNode, and SelectNodes takes two IXMLDOMNodes (to define the start and end of a range) to determine what to select. Consider the example earlier in this chapter in which we wrote an OnClick event handler for a button to ensure that the FirstName and LastName fields were not blank before switching views. You could use the SelectText method to select the text box that was blank so that the user could simply start typing in the blank text box to fix the error.

Overriding Submit, Confirm, and Save

So far you have seen how to use data source and form events to ensure that data entered by users is valid, reacts to users navigating around the form, and so on. This chapter has not yet discussed what happens to the data in the form when all the information is entered and validated. Somehow, the data must be saved to disk or submitted to a server somewhere.

Suppose that you want to prevent the user from specifying a destination for the saved data. Rather, when the user is done with the form, you want to ensure that the data is always saved to a particular shared directory on your intranet. You can accomplish this by handling the OnSubmitRequest event and writing code to force the data to be saved to that location.

The first thing you need to do is to disallow users from saving. In the InfoPath designer window, choose Form Options from the Tools menu to show the Form Options dialog box; then click the Open and Save tab. Uncheck the Save and Save As check box, as shown in Figure 12.13.

Figure 12.13. Disabling Save and Save As for a form.


The next step is to handle the OnSubmitRequest event. This event is raised when the Submit action is invoked when filling out the form. To handle this event, choose Submitting Forms from the InfoPath Tools menu to display the Submitting Forms dialog box. Select the Enable Submit Commands and Buttons radio button; then pick Custom Submit Using Form Code from the Submit To drop-down list, as shown in Figure 12.14.

Figure 12.14. Creating a custom event handler for the OnSubmitRequest event.


When you click the OK button, an event handler is generated for you in Visual Studio. In the OnSubmitRequest event, use the XDocument object's SaveAs method to save the form to a specific network share and filename. In Listing 12.9, the code saves the form to the network share \\myShare and names the file using the user's first and last names. Listing 12.9 also uses the XDocument object's UI object. It calls the UI object's Confirm method to ask users whether they are sure that they want to save. The code also uses the Application object's Window object and calls the Window object's Close method to close the window associated with the form after the form is saved.

Listing 12.9. An OnSubmitRequest Event Handler That Forces the Form to Be Saved to a Particular Network Share

<InfoPathEventHandler( _   EventType:=InfoPathEventType.OnSubmitRequest)> _ Public Sub OnSubmitRequest(ByVal e As DocReturnEvent)   ' If the submit operation is successful, set   ' e.ReturnStatus = true   ' Write your code here.   Dim submitChoice As XdConfirmChoice   If thisXDocument.Errors.Count > 0 Then     submitChoice = thisXDocument.UI.Confirm( _       "Errors exist on the form. Continue submitting?", _       XdConfirmButtons.xdYesNo)   Else     submitChoice = thisXDocument.UI.Confirm( _       "Are you sure you want to submit?", _       XdConfirmButtons.xdYesNo)   End If   If submitChoice = XdConfirmChoice.xdYes Then     Dim firstName As String     firstName = thisXDocument.DOM.selectSingleNode( _       "/my:myFields/my:FirstName").text     Dim lastName As String     lastName = thisXDocument.DOM.selectSingleNode( _       "/my:myFields/my:LastName").text     Dim fileName As String = firstName + "_" + lastName + ".XML"     thisXDocument.SaveAs("\\myShare\forms$\" + fileName)     thisXDocument.UI.Alert("Thank you, " & _       firstName & "! You will be contacted shortly.")     thisApplication.ActiveWindow.Close(True)     ' No need to set ReturnStatus because InfoPath closes   Else     e.ReturnStatus = False   End If End Sub 


InfoPath uses the ReturnStatus flag to determine whether the OnSubmitRequest event succeeded. It is not necessary to set the ReturnStatus flag to true in this example when closing the form window, because the runtime is immediately shut down when the form window is closed.

Note

The call to Confirm requires the domain security level, and the call to SaveAs requires the full-trust security level. Therefore, we will need either to sign digitally or register the form template to get full-trust permissions.





Visual Studio Tools for Office(c) Using Visual Basic 2005 with Excel, Word, Outlook, and InfoPath
Visual Studio Tools for Office: Using Visual Basic 2005 with Excel, Word, Outlook, and InfoPath
ISBN: 0321411757
EAN: 2147483647
Year: N/A
Pages: 221

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