This post could also be called “BizSupportOnline Saves The Day Once Again”, as the benefits of and technique for converting a button to a Submit button came from there.
But first a little background. I have a form that used code-behind triggered by rules on submit to create new items in two lists and to update existing data in another list. The rules would toggle values in a secondary data source, which would trigger Change events to execute my data creation/update code.
In retrospect, it was a pretty naive approach. It worked well enough for me in testing, but when deployed to users, the fatal flaw became apparent. If there was a validation error on the form, the submit would fail, but the rules would still run to create/update my lists, resulting in duplicate entries when the form was successfully submitted.
I could have used some tricks to disable the Submit button, but the form was very complex and didn’t lend itself well to such a solution. I really wanted a programmatic way to determine the validation state of the form, but to date have not found one.
Instead, when researching the issue, I stumbled upon this article on BizSupportOnline, which directly addressed the inability to programmatically close the form after Submit, and indirectly addressed the validation issue.
The post describes how to convert a normal form button to a Submit button that can be configured to use code-behind to execute the data connections to submit the form.
When this is done, the Submit option to close the form after submit can be used to force the form to close. The Submit parameters are configured by clicking Submit Options… as shown above. One side-effect of this change to programmatic Submit is that it is no longer possible to use rules on the button, so it may be necessary to write some code to do some work that was being previously being performed by rules.
Making the change will add a FormEvents_Submit event handler and method to the code-behind project. In this method, you must call your Submit data connection’s Execute() method to submit the form, as well as any other data manipulation you want to perform. In my case, this includes the data creation/update code that I described earlier.
In the above snippet, the comments above the try block are boilerplate that is added when you configure programmatic Submit. It describes how to manipulate the SubmitEventArgs to allow or prevent submission by setting the Cancel property to true or false.
For testing, I commented out my data connection’s Execute() method call (which I had to add manually) and returned Cancel = true to prevent the form from closing so that I could watch it in the debugger. What I found is that I get Form-Level validation of required data “for free”, because this method never gets called if the form fails validation!
This effectively solves the problem that I described above, i.e. preventing my custom code from executing when the form is invalid. It’s not perfect, because something can still fail in my custom code, but I redesigned that so that any exceptions will bubble up to this method. By doing this, I can use the CancelableArgs.Message property to return more detailed information to the user about what went wrong, and then they can grab a screenshot to hopefully help with troubleshooting.
The next logical extension of this process would be to attempt to rollback any partial updates that occurred when a custom code exception occurred, but for now I will leave this alone, as the custom code seems pretty reliable.
Filed under: C#, Form Design, InfoPath, Programming Tagged: Button, InfoPath, Programmatic, Submit, Validation
