If code-behind is the chosen path for your solution, you have in your arsenal all of the big guns the .NET Framework provides. But before going into some of the tips and tricks I use to push the envelope on InfoPath, there is one important realization to needs to be made: having code-behind doesn’t mean that InfoPath rules and web services will not be used.
My approach is to actually use “straight InfoPath” as much as I can, and have my code act as a crutch to support InfoPath when I want to do the things that it wasn’t necessarily meant to do on its own. Too much code will bog down your form; the last thing we want to do is go through all the trouble of implementing code-behind only to have it hinder our overall user experience.
So let InfoPath take of the things that InfoPath is good at: updating the properties of controls based on events in the form, using rules to implement quick pieces of logic, and calling web services to query outside data sources to update the form’s values. Then when you run into a wall, stop coding with our mouse and start coding with your keyboard; use .NET, in other words, to pick up where InfoPath left off. Following are some of the problems that I’ve needed code behind to solve.
This little mechanism is my favorite way to invoke .NET code “in between” rules defined for a control. Remember that a control, when its value is changed, will execute its rules before the OnChange event will fire code. This is important since a lot times you will find that you need to squeeze some code between InfoPath actions that can only happen inside of rules.
First, create a “hidden” textbox with a data value of integer. Do this by adding conditional formatting that hides the control whenever it is present. Make sure to also set the default value to zero. I like to place these textboxes at the end of my form, so they don’t clutter up the designer.
Then, in the rules of the control that we are dealing with, add a “Set a Field’s Value” action. The field is the hidden textbox, and value would be to set the value of the textbox equal to itself plus one. This will immediately start to execute the rules of the hidden text box, and then fire its OnChange event. Doing it this way alleviates us of having to worry about the task of resetting or clearing values of our Event Raisers later.
In this event is where the code you need to execute will go. After it runs, the next action InfoPath will take is to continue executing the rules of the original control. The code in the hidden textbox can do things such as error validation or setting values that will influence the conditions under which subsequent rules will be executed.
There is no clean, intuitive way to store collections of data behind the scenes in an InfoPath form. The System.Data.DataSet object in the .NET Framework is famous when it comes to accessing databases and managing multidimensional sets of data. Web services can return datasets to InfoPath, who, in turn, knows how to handle them and display them to user.
However, storage is another issue. I’ve found that repeating controls generate some messy XML, and keeping datasets in the results of secondary data sources produce a lot of overhead. There is no reason to keep re-calling expensive web methods to be able to reuse their data.
So what is a good way to store collections or arrays in a form? Raw data. I consider “raw data” to be basically one long, well-delimited string that is actually just a liner representation of a vertical list of values. Here’s what I do: