>
Blog
Book
Portfolio
Search

7/18/2006

4634 Views // 0 Comments // Not Rated

InfoPathology - Part 3 - Managed Code Tips And Tricks

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.

Event Raisers

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.

Raw Data Manipulation

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:

  1. In a web service, identify not only the group of values to be returned, but also a character that can be used to delimit them.  If need be, you can come up with a creative string that acts as the delimiter.  For example, I use semicolons whenever I can.  However, there are situations when semicolons can actually be part of the data, so instead I’ll use “<SEMICOLON>” to delimit the items in my list.
  2. Use a System.Text.StringBuilder to append each value followed by the delimiter to a string.  Then transmit this string to the form.  Finally, store this “raw data” in a hidden textbox.
  3. When the list needs to be enumerated somewhere in the code behind, simply perform a String.Split(“<delimiter>”) on the value of the textbox, and store the result in a string array.  Now you can loop though the data and access all members.
  4. Keep your forms nice and trim.  Whenever a form is saved, clear this data by simply setting the textbox’s value to String.Empty.  Keeping this data around will kill form load and save times.  So always clear it, and repopulate it only when it is necessary; users will rather wait a few moments for a button click to execute than a few additional seconds for a form to load.

1 Tag

No Files

No Thoughts

Your Thoughts?

You need to login with Twitter to share a Thought on this post.


Loading...