Showing posts with label Basics. Show all posts
Showing posts with label Basics. Show all posts

Sunday, October 14, 2012

Add error-handling to an InfoPath form

Problem: You have written code for an InfoPath form template and want to add error-handling to it.

You can add Try-Catch blocks to all public methods in the FormCode class and use a central error-handler to handle all errors that might take place.

To add error-handling to an InfoPath form:

1 - Add a button control to the view of the form template

2 - Add the following private method to the FormCode class

Private Sub HandleErrors(ByVal ex As Exception)

     System.Windows.Forms.MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK,    MessageBoxIcon.Error)

End Sub

3 - Add the following code to the button clicked event handler

  Try
                Dim mainDS As XPathNavigator = MainDataSource.CreateNavigator
                Dim noValue As String = mainDS.SelectSingleNode("//my:field1", NamespaceManager).Value
            Catch ex As Exception
                HandleErrors(ex)
            Finally
                'Perform any operation for clean up here
   End Try

In the code above "field1" does not exist on the main data source so after previewing the form you will get the following error message "Object reference not set to an instance of an object".

The code above works for an InfoPath Filler form but for a Browser form, modify the HandleErrors() method to log a message to the Windows Event log as follows:

Private Sub HandleErrors(ByVal ex As Exception)

            Dim source As String = "Infopath Browser Form"

            If Not System.Diagnostics.EventLog.SourceExists(source) Then
                System.Diagnostics.EventLog.CreateEventSource(source, "Application")
            End If

            Dim log As New System.Diagnostics.EventLog("Application")
            log.Source = source
            log.WriteEntry(ex.Message, System.Diagnostics.EventLogEntryType.Error)

  End Sub

If you get a request permission error when the form is trying to log the error than set the permission of the form to Full Trust and you will see the error logged on the Windows Event Log.

Monday, October 8, 2012

Setting fields to their original values

Problem: You want to restore an InfoPath form to the state it had when it was opened for the very first time.

You can save the state of a form when it initially opens and then restore to this state by replacing all the values on the fields with the data you initially stored.

The method to do this is a little different between an InfoPath Filler or browser form.

1 - Design a form and add as many fields as you like.
2 - Add a button to the form and label it RESET
3 - Add the following code to the FormCode class

For InfoPath Filler:

Private initialData As String

For Browser Forms

Private Property initialData() As Object

            Get
                Return FormState("initialData")
            End Get
            Set(ByVal value As Object)
                FormState("initialData") = value
            End Set
 End Property

4 - Add the following code to the FormEvents_Loading() event handler

initialData = MainDataSource.CreateNavigator().SelectSingleNode("/my:myFields", NamespaceManager).InnerXml

5 - Add the following code to the Clicked() event handler of the button

MainDataSource.CreateNavigator.SelectSingleNode("/my:myFields", NamespaceManager).InnerXml = initialData.ToString

Preview the form and change the default values of the fields. Notice that once you click the Reset button the value goes back to their original values.

The innerXML property of an XPathNavigator object gets or sets the markup that represents the child nodes of the current node. By using this property you can store the entire XML contents of the myFields group node in the variable or property.

Clear a field on a form

Problem: You want to clear a text box on a form.

You can set the value of the field that is bound to a text box control to be equal to an empty string to clear it.

In order to clear a text box called "Field 1" do the following:

- Add a text box field called "Field 1" and a button to the form. Set the ID of the button to "ClearTextButton"

- On the ClearTextButton_Clicked event handler add the following code

Dim dsMain As XPathNavigator = MainDataSource.CreateNavigator
Dim Field1 As XPathNavigator = dsMain.SelectSingleNode("/my:myFields/my:field1", NamespaceManager)

Field1.SetValue(String.Empty)

Set the value of a field II

Note that a few controls in InfoPath such as for example date picker controls have a nil attribute set o the fields they are bound to when they are empty. This nil attribute must be removed before you can set the value of such fields, otherwise you will get the following error when you try to set the field's value through code:

Schema validating found non-data type errors

In order to remove the nil attribute from a date picker control add the following code:

Dim mainDS As XPathNavigator = MainDataSource.CreateNavigator
Dim StartDate As XPathNavigator = mainDS.SelectSingleNode("/my:myFields/my:StartDate", NamespaceManager)

If StartDate.MoveToAttribute("nil", NamespaceManager.LookupNamespace("xsi")) Then
    StartDate.DeleteSelf()
End If

StartDate.SetValue("2012-10-08")

The following InfoPath controls typically have nil attributes on the fields they are bound to:
  • Text Box with the Whole Number (integer) data type
  • Text Box with the Decimal (double) data type
  • Text Box with the Time (time) data type
  • Date Picker
  • Date and Time Picker
  • File Attachment
  • Picture (when a picture is included in the form instead of as a link)
  • Ink Pickture
You can find out whether a control supports the nil attribute by adding a control to the form template, previewing the form, leaving the control empty, saving the form locally on disk, opening the XML file for the form in Notepad, and then looking for:

xsi:nil="true"


Saturday, October 6, 2012

Set the value of a field I

Problem: You have a text box control on a form and you want to set its component to be equal to a piece of text.

Create a form, add two text boxes named field 1 and field 2. After that set the default value of field 1 to "This is my value".

Finally add the code below to the FormEvents_Loading() event handler

Dim mainDS As XPathNavigator = MainDataSource.CreateNavigator

Dim Field1 As XPathNavigator = mainDS.SelectSingleNode("/my:myFields/my:field1", NamespaceManager)


Dim Field2 As XPathNavigator = mainDS.SelectSingleNode("/my:myFields/my:field2", NamespaceManager)


Field2.SetValue(Field1.Value)

Preview the form and you will see that field 2 now has the same value as field 1

Get the value of a field

Problem: You want to retrieve the contents of a text box on a form.

In InfoPath create a form and add a TextBox, name it "Field 1" and set it's default value to "Hello, this is my default value".

On the field task pane, select "Field 1" right click and select "Copy XPath".

Add the code below on FormEvents_Loading() event handler:

Dim mainDS As XPathNavigator = MainDataSource.CreateNavigator
Dim Field1 As XPathNavigator = mainDS.SelectSingleNode("/my:myFields/my:field1", NamespaceManager)

Dim val As String = Field1.Value

Set a breakpoint on the line after the last line of code and press F5. Verify that the variable "val" has the same value as Field 1.

Access the Main & Secondary Data Source

Main Data Source
If you would like to write code that access data on an InfoPath form, the first step to access data stored within a form is to get a reference to the main source of the form.

Add the following code to the FormEvents_Loading() event handler

Dim mainDS As XPathNavigator = MainDataSource.CreateNavigator()

Secondary Data Source
If you have a form that has one or more secondary data sources associated with it and you want to access the data from one of those data sources.

In the case below you would like to access a secondary data source called "Employee" for example.

Add the following code to the FormEvents_Loading() event handler

Dim secDS As XPathNavigator = DataSources("Employee").CreateNavigator()

The DataSources property of the Xmlform object is a DataSourceCollection object, which contains DataSources Objects corresponding to each data source of the form with the Main data source of the form listed as the first data source in the colllection. You can access a DataSource object either by its position in the collection or by its name. For example:

Dim mainDS as DataSource = Datasources(0)
or
Dim mainDS as DataSource = DataSources("")
or
Dim mainDS as DataSource = MainDataSource

They all would return a DataSource object for the Main data source of a form.

Dim EmployeeDS as DataSource = DataSources(1)
or
Dim EmployeeDS as DataSource = DataSources("Employee") 

Would return a DataSource object for the Employee secondary data source.

Once you have retrieved an XPathNavigator object, you can use its methods to manipulate the data stored in the data sources.


About Me

My photo
Toronto, Ontario, Canada
MBA, M.Sc. & MCP