Microsoft InfoPath 2010
The official blog of the Microsoft InfoPath team

  • Microsoft InfoPath 2010

    Creating Complex InfoPath Controls in C#


    One of the problems with InfoPath controls is their limited availability. For example, there is no such control like the NumericUpDown control in WinForms. Or you may have a predefined complex UI, which you want use multiple times.

    In these circumstances, what we need is a mechanism for control extensibility. Today, InfoPath provides two different control extensibility mechanism: Template parts and ActiveX controls.

    Basically, template parts are predesigned InfoPath form templates, that can be imported into other templates. This mechanism provides a good way of reusing the same controls again and again, but on the dark side, you are still restricted with the control set of InfoPath.

    Other mechanism, which is extensibility via ActiveX controls lets you go beyond the control set of InfoPath and use whichever ActiveX control you want. In this blog, we will drill down into using a Windows control in InfoPath forms, and more importantly provide a way of binding data to these controls. This blog will give details of using WinForm controls that are registered for COM Interop, inside InfoPath forms. Two mainly used types for binding ActiveX controls to InfoPath data sources are 'Simple Binding', ‘Stream Binding’ and 'Node Binding'. In this article we will cover node binding. You can find more information about types of binding between ActiveX controls and InfoPath data source here:


    Simple Binding

    If your external control needs to be bound to a single field in InfoPath main data source, then you can use single binding between your ActiveX control and data source. An excellent simple binding example by InfoPath team can be found here: Creating an InfoPath Custom Control using C# and .NET. I highly recommend you to read this article first both to understand how to register our Windows Forms controls for Com Interop, and how simple binding is done for a primitively typed single field. Rest of the article will assume you read and applied the principles told in this article.

    Node Binding

    When binding to a single field or attribute is not enough, or you need your ActiveX controls to interact with data coming from different fields, node binding is the way to go. A classical example would be an ActiveX control capable of showing an Address type complex structure composed of Street, City, State and ZipCode fields.

    In this case, you need an Xml node in InfoPath form template as a data source that obeys the schema of Address object.

    InfoPath form

    We will design the data source of InfoPath first. Let's just write a schema file that corresponds to the structure of Address class. A simple schema file just including address data would be similar to this:

    <xsd:schema xmlns:xsd="">

          <xsd:element name="fields">



                            <xsd:element ref="address" minOccurs="0"/>




          <xsd:element name="address">



                            <xsd:element ref="street" minOccurs="0"/>

                            <xsd:element ref="city" minOccurs="0"/>

                            <xsd:element ref="state" minOccurs="0"/>

                            <xsd:element ref="zipCode" minOccurs="0"/>




          <xsd:element name="street" type="xsd:string"/>

          <xsd:element name="city" type="xsd:string"/>

          <xsd:element name="state" type="xsd:string"/>

          <xsd:element name="zipCode" type="xsd:integer"/>


    Start to design a new InfoPath form template from XmlSchema and use this schema as your source. InfoPath should parse the schema, and should create the data source entries in Data Sources tab in design task pane for you. At this point, let's create 4 text boxes that will display each of these fields. For the educational purposes of demo, do not drag and drop the whole address node onto the surface. Instead, drag and drop individual fields on to the design surface. This is because, after designing the ActiveX such that it is bound to whole DOM node, we will get a binding structure like this:



    Since we finished the main part of the form template, let's start to prepare the ActiveX object that we will use in the template. Assuming you read the article Creating an InfoPath Custom Control using C# and .NET, I will just touch the points not told there.

    Design the control
    Simply drag and drop four Labels and four TextBoxes on to the user control for each of the fields in Address type.

    Register for ComInterop

    As told in the article, we will need a Guid attribute for Visual Studio to register the control for Com Interop. What is not told in the article is, we need one more attribute to be able to register the control via Visual Studio: ComVisible. Although, UserControl class is donated with ComVisible(true) attribute in .Net framework, we have to state it explicitly one more time, because ComVisible attribute is created with AttributeUsage(…, Inherited = false), which prevents the value of the attribute to be inherited to children classes. So, our control should look similar to this for a successful registration:



    public class ComplexUserControl : UserControl

    After building this code, a quick search through registry for Guid, will prove that class is really registered.

    You should import the IObjectSafety interface exactly as told in the article. Before discussing IPropertyNotifySink, let's first take a look at the control interface, that will define the Value and Enabled property. In simple binding example, we had a primitive property in ICOMControl interface. Since we are no longer binding to a primitive field, we have to define a new interface.

    Let's define an IComplexControl interface similar to IComControl interface in the article. For Value property, we will use IXMLDOMNode type defined in Microsoft.Office.Interop.InfoPath.Xml.dll assembly that you will find in your Office 12 installation directory. This corresponds to a node in InfoPath main DOM data source. At the end, our interface should be similar to this:


    public interface IComplexCOMControl



        IXMLDOMNode Value { get; set; }



        bool Enabled { get; set; }


    As stated in the article, Constants.DISPID_VALUE should be 0, and Constants.DISPID_ENABLED should be 1, in order for InfoPath to correctly communicate with our control.

    Now let's inspect IPropertyNotifySink interface. One of the main differences between Simple Binding and Node Binding is the type of the Value property. Simple binding deals with primitive types, whereas node binding deals directly with DOM. In simple binding a rough sequence of events would be like this:

          Property change in data source --> … -->Set Value property of ActiveX

    And the other way around:

          Property change in ActiveX --> Raise OnChanged -->InfoPath queries for Value property --> … -->Set Value property of ActiveX

    However, since InfoPath sends the whole DOM node as our Value property by reference, we don’t need to set an intermediary Value property. Instead we can directly change DOM values from DOM node reference. So we can safely ignore RaiseOnChanged and InfoPath queries for Value property steps. Since IPropertyNotifySink interface is used mainly for property change notification purposes will not implement it in this demo. If you care about Enabled property changes, you still have to implement this interface and notify InfoPath when Enabled property changes.


    Value property implementation

    When InfoPath first calls the setter of Value property after instantiating our control, it will pass in the IXMLDOMNode representing the main DOM of InfoPath. We have to keep this node in our control, in order to be able to change the data values corresponding to changes in UI.

    In the getter of the property, since we are not changing the reference of DOM node, it is safe to return this kept value.
    Whenever some field (or subfields in our group field)changes in DOM, InfoPath will call the setter of our Value property. In the setter, we should query the DOM according to XPaths of our fields, and then update the UI according to the values if necessary. At the end, our Value field should look like this:

    private IXMLDOMNode domNode = null;

    public IXMLDOMNode Value




          return domNode;




            if (domNode != null)


                ChangeUI(streetTbx, domNode.selectSingleNode("/fields/address/street").text);

                ChangeUI(cityTbx, domNode.selectSingleNode("/fields/address/city").text);

                ChangeUI(stateTbx, domNode.selectSingleNode("/fields/address/state").text);

                ChangeUI(zipCodeTbx, domNode.selectSingleNode("/fields/address/zipCode").text);





    private void ChangeUI(TextBox tbx, string text)


       if (tbx.Text != text)


        tbx.Text = text;



    At this point we have completed the one direction of binding, originating from data source and going to UI. Now, let's handle the other way around, from UI to data source. In order to do this, we have to create a simple event handler that will catch change events in UI. Then register for all four text boxes' TextChanged events, such that each of them will be handled by this event handler. Code should look like this:

    public ComplexUserControl()




        // Register for UI change events

        this.streetTbx.TextChanged += this.HandleChangesInUI;

        this.cityTbx.TextChanged += this.HandleChangesInUI;

        this.stateTbx.TextChanged += this.HandleChangesInUI;

        this.zipCodeTbx.TextChanged += this.HandleChangesInUI;



    private void HandleChangesInUI(object sender, EventArgs e)


        TextBox senderTbx = (TextBox)sender;

        if (senderTbx == this.streetTbx)

            this.ChangeDOM("/fields/address/street", this.streetTbx.Text);

        else if (senderTbx == this.cityTbx)

            this.ChangeDOM("/fields/address/city", this.cityTbx.Text);

        else if (senderTbx == this.stateTbx)

            this.ChangeDOM("/fields/address/state", this.stateTbx.Text);

        else if (senderTbx == this.zipCodeTbx)

            this.ChangeDOM("/fields/address/zipCode", this.zipCodeTbx.Text);



    private void ChangeDOM(string xPath, string value)


        if (domNode != null)


            IXMLDOMNode singleNode = domNode.selectSingleNode(xPath);

            if (singleNode.text != value)


                singleNode.text = value;





    In order to be able to use the ActiveX Control in the design of a form template, we have to make one final trick: Placing the .ict file that describes the control and its binding, to our controls directory. In order to add custom controls design task pane in InfoPath, generally you first go to the Controls tab, then click Add or Remove Custom Controls at the bottom of this tab, select to add a new ActiveX control, and finally select the ActiveX you want to add from the list of registered controls. If you have ever done this before, there should be a directory named

    C:\Documents and Settings\username\Local Settings\Application Data\Microsoft\InfoPath\Controls

    In this directory there should be a .ict file for each of the ActiveX controls that you have done this operation for. We have to create a new .ict file for our control. If above directory does not exist, create it. Then create a file with name "{yourClassGUIDHere}.ict". This file should be in this format:

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>

    <ict:control name="Complex C# Control, v1.0" xmlns:ict="" xmlns:xsd="" xmlns:xdSdl="" xmlns:ict2="ict2" xmlns:xd="">





                <ict:controlPackage classid="{yourClassGUIDHere}"/>



                <!--default shape-->






               <ict:controlObject bindingProperty="Value" bindingType="xmlNode" enabledProperty="Enabled" enabledValue="true"/>



    Note the bolded text. You should place the correct GUID for your control, and note that we are actually specifying 'xmlNode' as bindingType. Rest of the file is almost standard except the iconBitmap part, which specifies the icon that will be displayed next to your control in design task pane.

    Since we have a ready control now, we can safely use it in our form template. Open the InfoPath form you have designed in design mode again. Go to Controls tab in design task pane. At the bottom, under Custom section, you should see the 'Complex C# Control, v1.0' with icon I have copied from Microsoft Forms Progress Bar control. Drag and drop this control to design surface. According to your security settings, it may ask you if you want to run ActiveX control. If so, press 'Yes' and continue. Since we have already defined a data source in the form, InfoPath will ask which field or group do we want our control to bind to. Choose address here. Now you should see the control on the surface, and its binding field is specified as /fields/address. Press Ctrl+Shift+B to preview the form. You should see the corresponding InfoPath TextBoxes and our UserControl's TextBoxes are synchronized, because they are bound to same data source fields.

    Now we have a functional complex WinForm UserControl, that we can display in an InfoPath form template, and even better, this UserControl is bound to InfoPath main DOM.

    Improving ActiveX Discrepancies

    If you played with the form a few minutes, you must have noticed that there is something weird going on. If you are changing the text value of InfoPath TextBoxes, you see a flicker in the UserControl before data is reflected to it. Similarly, if you change the value of a TextBox in your UserControl, you also see a flicker in the UserControl, and focus is continuously given to first TextBox added to UserControl.

    Main reason for this issue is, whenever a data field that is bound to your ActiveX is changed, InfoPath destroys your control and create a new one. This is mainly because InfoPath has to apply your view xsl to your data source to create the view you see on the display. Every time data source changes, InfoPath re-applies the xsl file and creates the view from scratch for controls that are bound to changed data fields. If you are debugging the form, you can easily see this by putting a breakpoint in the constructor of UserControl. Clearly, this leads us to write stateless controls, since each time the controls are destroyed, state is destroyed too. Or, as a second approach, we can take advantage of a helper interface, InfoPathControl interface, to save the state to some persistent storage just before destruction, and retrieve it after re-creation. Let's inspect how this approach works.

    InfoPathControl interface is defined in Microsoft.Office.Interop.InfoPath primary interop assembly. Add a reference to this assembly to your project and implement the interface on your UserControl. I advise you to read the explanation of all four methods of the interface, and how they are used in MSDN. Here, we will only concentrate on two of them, which are Init and SaveState methods.

    SaveState is called by InfoPath, just before the destruction of the older control, which makes it a perfect point to save the state to some storage. Init is called after creating the new control, which lets us to use it to retrieve the saved state and apply it to our control.

    Init method takes a parameter of type InfoPathControlSite. This interface gives us the main DOM node and XDocument of InfoPath form template, which basically enables us to access pretty much all of the object model of InfoPath. So, we don't have to wait for the setter of Value property anymore. We can cache the domNode here in Init method. We will also cache the XDocument for storing the state in, since we will need a persistent storage for our state while we are destroyed. In general, Init method body should be similar to this:

    private XDocumentClass xDocument = null;

    public void Init(InfoPathControlSite pControlSite)


      this.domNode = pControlSite.Node;

      this.xDocument = (XDocumentClass)pControlSite.XDocument;



    We will inspect RestoreState method after SaveState method.

    For simplicity, we will assume that we only want to keep which control has the focus in UserControl and give focus to that control after re-creation. Saving the name of the active control should be enough for state restoration. In reality in a control like this we should also keep the location of the cursor inside the TextBox as well as which TextBox is active.

    We said that we will use XDocument to save the state. This is because XDocument lives with the form template, so it is persistent during the lifetime of our control, and XDocument has a property bag that we can use for this purpose. We can update this property bag by calling SetNamedNodeProperty and querying it by calling GetNamedNodeProperty method on XDocument object. At the end, SaveState and RestoreState methods should be similar to this:

    public void SaveState()


        if (this.xDocument != null)


            this.xDocument.SetNamedNodeProperty(this.domNode, "ActiveControl", this.ActiveControl.Name);




    private void RestoreState()


        if (this.xDocument != null)


            Control activeControl = this.Controls[this.xDocument.GetNamedNodeProperty(domNode, "ActiveControl", this.Controls[0].Name)];

            if (activeControl != null)






    In the call to GetNamedNodeProperty in RestoreState method, third parameter is the default value, which will be returned back if specified property name can't be found in property bag. This will be the case when control is first created.

    Now, each time data source has changed, we save which control was active in UserControl before it is destroyed. Then InfoPath instantiates a new instance, we restore the state if there is any. Then InfoPath sets the Value property with updated fields.

    Saving the whole state in a WinForm control is a non-trivial task and maybe somewhat cumbersome. I'm optimistic about this re-creation of ActiveX controls will be optimized by InfoPath team in the next release.

    At the end, our code will look like this attached file.

    Deniz Demircioglu
    Software Design Engineer

  • Microsoft InfoPath 2010

    Behind the Scenes of Administrator-Approved Form Templates


    If you’re a server administrator for Microsoft Office InfoPath Forms Services 2007, there may be a time when you’re tried to perform some action on a form template and received an error message that looks like the following:

    “Form template was deployed as part of the 9b518781-2fcd-40fe-a1f4-964b2cd4c0b8 feature”

    This feature name probably doesn’t mean a whole lot to you, and the error message could be a bit more actionable, right?  What the heck is this feature thing that the message refers to?  You might also have come across other IDs or other weird timing issues on a multiple server farm.

    Starting the Tour

    So, to shed some light on this, let’s go back-stage to see a little of what’s going on behind the scenes.  The stage is Windows SharePoint Servers Central Administration, where you will find 5 options in the Microsoft Office InfoPath Forms Services group on the Application Management landing page. This tour will mainly be concerned with the Upload Form Template page and a little bit with the Manage Form Templates page. 

    Let’s start at the Upload Form Template page, which is how a form template gets approved by the administrator.  Each new form template uploaded to the farm also adds a new FormTemplate object to the FormsService.FormTemplates which is the singleton FormTemplateCollection object for the farm’s administration object model.  This FormTemplate object allows the same manipulation that is available through the UI.  It also contains a lot of information used only internally to InfoPath Forms Services.  The most important internal property is the converted file, which is essentially a compiled version of the form template that can quickly render as a form template in the browser.

    When InfoPath form templates are uploaded to a server, the Windows SharePoint Services solution deployment and featurization infrastructures are being used to turn the form template into an administrator-approved form template..  Behind the simple click of the Upload button, InfoPath Forms Services creates a feature to deliver the form template (.xsn file).  The feature is then wrapped in a Windows SharePoint Services solutions package which is a .wsp file (just a renamed .cab file) that contains the feature and some other packaging information.

    The Solution Package

    This solution package is the means of deployment to all of the servers in a farm.  All Web front-end servers will have the form template propagated to their file systems, via the solution’s package.  So, there may be a delay in showing up on a multiple-server farm, hence the ellipsis in the “Installing…” status which remains until the form template is deployed to all machines in the farm.  These are propagated via the SPTimerv3 service which runs on each box and is scheduled to pick up jobs from servers running the central administration Web Application (where the Upload took place) and it uses the SPAdmin service to install the solution on the machine, via the administrator account.  So, InfoPath Forms Services deployment needs these services running on each machine, just like WSS solution deployment, because it’s actually the same thing.  Once deployment is completed, the form template is marked with “Ready” status.

    [Side Note: An implementation just like what we use for solution deployment is also available to you.  Our shipping documentation covers how to create features and solutions from scratch.  You might want to do this to bulk deploy many form templates at the same time, to indicated InfoPath form templates in other features or solutions, or to create a custom workflow that contains custom InfoPath form templates.  These custom-created solutions are still registered into the InfoPath Forms Services OM, but will be treated a little differently in IPFS, for instance, you cannot activate/deactivate/remove/upgrade these form templates through IPFS management, because that might invalidate the overall solutions that were constructed.  The whole features must be activated the same way that other custom features are activated (see Ready for Activation, below).]

    Ready For Activation

    The Ready status indicates that the form template can be used and is in normal operation.  The feature created, is a site collection-scoped feature (that’s SPSite-scoped in WSS OM-speak), which can be activated on an site collection like most other site collection-scoped features.  If you are a site collection owner, navigate to Site Settings, and see Site Collection Features under the Site Collection group heading.  Every form template that was administrator-approved through the upload page is available here along with the other site collection scoped features.

    You can also activate and deactivate features from the Manage Form Templates page in Central Administration.  This is exactly the same thing, and is provided as a courtesy for farm administrators who are also site collection owners.

    Behind the Scenes of Activation and Invocation

    An activated form template is added as an item in the Form Templates library at the root site of the site collection (SPSite.rootWeb) in the /formservertemplates path.  The form template is not actually present in the content database for the library, it is stored as a ghosted entry.  A user invoking the form template with the Microsoft Office InfoPath 2007 rich client is actually pulling the form template from the file system of the Web front-end server where it was placed by solution deployment.  Invoking the form template via the browser will pull the converted file from the FormTemplate object in the administration object model.

    The Form Templates library is special in a few ways.  The most important special aspect is that activated form templates cannot be unghosted.  This is to ensure that the converted file version and the on-disk version cannot be different, so that no matter what client you fill the form in, it’s the same form. 

    Be a Better IPFS Admin with this Knowledge

    Our hope is that this article will make our behavior more clear and expose a few tricks to help you be better Administrators.  Here are a few tricks in how to use that information to your advantage.

    Handle the error:  “Form template was deployed as part of the 9b518781-2fcd-40fe-a1f4-964b2cd4c0b8 feature”

    If you receive this, you most likely want to remove the form template and start over.  Here’s the action to take, and it’s only available from the command line:
    "%ProgramFiles%\Common Files\Microsoft Shared\web server extensions\12\BIN\STSADM.EXE" -o uninstallfeature -filename 9b518781-2fcd-40fe-a1f4-964b2cd4c0b8\feature.xml

    Form template’s status never leaves “Upgrading…” or “Removing…” states

    These states seem to indicate that you're running a multiple-machine server farm, and on your server farm, you're running into some issues in propagating changes to all of the machines.  If you have not done so already, I highly recommend turning on the following services on each machine: SPAdmin, and SPTimerV3 You can do this by running:
                    net start SPTimerV3
                    net start SPAdmin
    On each machine.  Net start is a ensure semantic, so this will not inadvertently toggle or cause any damage if run on a machine where the service is already started.  Now that that's done, you can go on to correcting the problems that you have.

    From Central Administration, go to the Operations page, under the Global configuration group, click on Timer Job Status.  On that page, look for timer jobs that have the name in the following formatting.  If you filename is FOO.xsn, it will look like:
    Windows SharePoint Services Solution Deployment for "form-FOO.wsp"

    See if there was a failure.  If so, go back a page, and go to Timer Job Definitions.  Drill down in the timer job definition that you care about and you can perform the following:

    >> For the case of status stuck on “Uploading”:
    1.       Try to restart the job if that is available.
    2.       If restart is not available, delete the job, then attempt to upgrade again.

    >> For the case of status stuck on "Upgrading":
    1.       Try to restart the job if that is available.
    2.       If restart is not available, delete the job, then attempt to upgrade again.

    >> For the case of status stuck on "Removing":
    1.       Try to restart the job if that is available.
    2.       Else, Remove the job. (continue to step 3)
    3.       Then, go back to the Manage Form Templates and try again to Remove the form template.

    Ed Essey
    Program Manager
    Alexei Levenkov
    Software Design Engineer
  • Microsoft InfoPath 2010

    Digital Signatures: Layout Tricks


    Folks frequently ask whether it is possible to customize the InfoPath user interface around digital signatures. Some want to show the signature at the very bottom of the form; others want to show signatures side-by-side; others want to disable form submissions when the document wasn't digitally signed. In this article, we'll look at different ways you can tweak the form design to make it happen.

    Trick 1: Display signature at the bottom of the view

    InfoPath lets you show digital signature UI ("click here to sign this form") under a signable section; however, this section doesn't have to include any controls! This means that you can have your signable section with controls at the top of the form, some extra content in the middle, and then another section bound to the same nodes in the data source without any controls in it.

    Your design view would look like this:

    Note how the signableGroup here is multiply bound; the first section has the "allow users to digitally sign this section" checkbox unchecked:

    The second one has it checked, which makes the "click here to sign this form" show up; this is how the end result looks at edit-time:

    Trick 2: Disallow Submit if form was not signed

    InfoPath digital signatures are appended to form XML, just like form data. For example, in the form above, nodes under signature1 will store the digital signature when the user adds it:

    Using this fact, we can enforce business rules in our form: for example, what if we don't want to allow form submissions for cases when form is not signed? Let's go to Tools | Submit Options and create two rules:

    1) Show must-sign warning:

        - condition: signatures2 node is blank (this will evaluate to true when no signature was added)

        - action: show a dialog box message "you must sign the form before submitting it"

        - check "stop processing rules when this rule finishes"

    2) Submit to main data source:

        - condition: always applies (unless the first rule fired - we wouldn't get to this execution point then)

        - actions: submit to main data source + show dialog box message "submission was successful"

    Trick 3: Show signatures side-by-side

    Challenge: make a form that has signatures side-by-side at the bottom; additionally, person 3 should only be able to add their signature if previous signer (person 2) already signed the document.

    We already know how to make the signatures appear at the bottom of view (trick 1); we also know how to determine if a signature was added to the document (trick 2). Let's put all of these tricks together into one powerful solution:

    - Create 3 different signed data blocks, one for each person that will be signing the form. Second data block needs to signing a superset of data that the first one signed, etc.  Your data source task pane will look like this: 

    - Place empty sections bound to the items that you want to sign in the columns of that table.
    - Use containing conditionally-formatted sections to show the signing UI only when necessary.

    The resulting layout will look like this:

    I'm attaching a sample form template that has this trick implemented (works in InfoPath 2003 or 2007; save the XSN to your computer before opening it).

    Alex Weinstein
    Program Manager

  • Microsoft InfoPath 2010

    Programmatic Selection in InfoPath


    InfoPath supports two methods on the View OM object - "SelectText" for data entry controls and "SelectNodes" for structural controls - in order to enable programmatic selection.

    Data entry controls that can be programmatically selected (using View.SelectText):

    • Text Box
    • Rich Text Box
    • Date Picker

    Structural controls that can be programmatically selected (using View.SelectNodes):

    • Optional Section
    • Choice Section
    • Repeating Section (items)
    • Repeating Table (rows)
    • Repeating Recursive Section (items)
    • Bulleted, Numbered & Plain List
    • File Attachment

    Programmatically setting focus to these controls is not supported:

    • Drop-Down List Box
    • List Box
    • Check Box
    • Option Button
    • Button
    • Picture (Linked or Included)
    • Ink Picture
    • Hyperlink
    • Expression Box / Vertical Label
    • ActiveX
    • Section


    Steps to select rows in a repeating table using SelectNodes:

    In order to set selection extending the 1st two rows of a repeating table you can do the following steps:

    1. Insert a "repeating table" from the controls task pane

    2. Insert a "button" from the controls task pane

    3. Double click on the button control to bring up Button Properties

    4. Click on the "Edit Form Code" button

    [you may be asked to install Microsoft Script Editor if you don't already have it installed]

    5. This should bring up script.js file in Microsoft Script Editor with a function such as

    function CTRL5_5::OnClick(eventObj)


    // Write your code here


    6. Insert the following code inside the above function

    var nodeSelStart = XDocument.DOM.selectSingleNode("/my:myFields/my:group1/my:group2[1]")

    var nodeSelEnd = XDocument.DOM.selectSingleNode("/my:myFields/my:group1/my:group2[2]")

    XDocument.View.SelectNodes(nodeSelStart, nodeSelEnd)

    [This assumes that the repeating table is bound to my:group2. You can figure the XPath by looking at the Data Source task pane after selecting the appropriate repeating table.]

    7. Now you should be able to preview the form and verify that clicking on the button causes the expected selection. Please note that you have to have at least two rows in the table in order to select the first two rows. Otherwise you will see an error.

    Steps to select text in a text box using SelectText:

    In order to select text in a text box you can do the following steps:

    1. Insert a "text box" from the controls task pane

    2. Insert a "button" from the controls task pane

    3. Double click on the button control to bring up Button Properties

    4. Click on the "Edit Form Code" button

    [you may be asked to install Microsoft Script Editor if you don't already have it installed]

    5. This should bring up script.js file in Microsoft Script Editor with a function such as

    function CTRL2_5::OnClick(eventObj)


    // Write your code here


    6. Insert the following code inside the above function

    var nodeSelText = XDocument.DOM.selectSingleNode("/my:myFields/my:field1")


    [This assumes that the text box is bound to my:field1. You can figure the XPath by looking at the Data Source task pane after selecting the appropriate text box.]

    7. Now you should be able to preview the form and verify that clicking on the button causes the expected selection.

  • Microsoft InfoPath 2010

    Designing browser-enabled forms for performance in InfoPath Forms Services (Part 4)


    Part 4 – Browser Rendering Issues

    Welcome to the fourth article in our series on optimizing the performance of InfoPath browser-enabled forms. In our previous articles we defined performance in terms of responsiveness, listed a number of conditions that cause postbacks, and looked at some of conditions that make postbacks more expensive, reducing the responsiveness and scalability of a form system. In this article we’ll examine some of the issues that affect form rendering performance in the browser. We’ll also take a quick look at using the Design Checker to monitor browser compatibility issues while designing a form template in the InfoPath Designer.

    Conditions that slow form rendering in the browser

    There a several conditions that can reduce form-rendering performance in the browser. The main effect of these conditions is that the user experiences delays and sluggishness when working with the form. The reduced performance experienced because of slow form rendering in the browser generally occurs at the following times:

    • When the form initially loads

    • When the form is updated and re-rendered after a postback response

    • When there is a change to the display of the form in the browser that does not involve a postback

    If the designer can reduce or eliminate conditions that are more expensive for the browser to render, the form will render more quickly, and feel more responsive to the user. As with other design issues we’ve examined that affect postbacks and server performance and scalability, addressing performance issues that affect browser rendering must be balanced with your unique design and business requirements.

    • Rich Text Box control

      The Rich Text Box control creates HTML elements for the content added to a rich text field. Depending on the amount of content and formatting added by the user it can end up creating a large number of HTML elements, which can impact browser performance. One issue with using a rich text field is that you cannot predict how much data a form user might add to the field. For example, a user could paste a large rich text selection into your form from just about any source. Although the Rich Text Box control for a browser-enabled form does not allow embedded images, only linked images, the content could still be quite large.

      Unfortunately, for browser-enabled forms the InfoPath Designer does not provide a way to limit the amount of data entered. Consequently, you should consider carefully how your users are likely to use any rich text fields you add to the form and limit the number of rich text fields that are visible in a view. If you need multiple rich text fields, consider using multiple views rather than putting them all on a single view. As an alternative, consider using a Multi-line Text Box control instead.

    • Nested Tables

      Rendering HTML code for tables is a relatively expensive operation for a browser. Nesting tables by inserting one table inside another, especially if they are nested several levels deep, compounds the complexity and is generally slow for a browser to render. For better rendering performance, consider using adjacent non-nested tables rather than nested tables.

    • Conditional formatting

      We looked at conditional formatting in an earlier article, touching on the interaction with postbacks to the server and how conditional formatting expressions fire each time the form is re-rendered. Since the browser must manipulate all the data, whether it is visible or not, this can be an expensive operation that makes the form display feel less responsive. While conditional formatting can be a useful design tool, there are times when the performance cost may outweigh the benefits. For example, if a form contains a large amount of data and a substantial part is hidden, the conditional formatting can slow the form display even though some of it isn’t rendered.

      In this case, designing the form with multiple views might improve the form’s display performance compared to the single view with hidden content. Although it will cause a postback each time there is a switch to another view, the user’s interaction with each of those views in the browser may feel more responsive. This is because each view has a smaller amount of data to render than the single view containing hidden data. The tradeoff you need to consider here is between the browser-side responsiveness of the form display and the server-side scalability of your form system as it processes postbacks: using conditional visibility might slow form display, but reduce the number of server requests, while using multiple views improves form display, but increases server requests and reduces scalability.

      As another example of how subtle performance tradeoffs can be, as noted in the earlier article, it is also possible to have a design where the form display is more responsive if it uses conditional formatting to hide some data. This is happens in a situation where the browser actually takes longer to render all the elements than it takes to process the conditional formatting and hide some.

      If you suspect you have a situation where conditional formatting could either help or hinder your form’s performance in the browser – or your server scalability – try alternate designs and test them to determine which design best meets your requirements.

    • Drop-Down List Box controls with many items

      Drop-Down List Box controls can generate a large amount of HTML, especially when there many items provided in the list. The amount of HTML balloons when the list control is contained in a repeating section or table. For example, if you include 50 items in a list, and the list is repeated 50 times, the underlying HTML code will grow very rapidly and slow down rendering of the form! Try to limit the number items in lists that are used in repeating elements or limit the number of repeating elements. Alternatively, you can try using conditional formatting, putting the repeating elements containing drop-down lists into a section that is hidden by default. Because they are not supported in browser-enabled forms, some of workarounds you might consider using if you are familiar with InfoPath rich-client forms, such as a Master-Detail control or one of the other list controls, are not available. About the only other alternative might be to emulate the list using a repeating table with each item on a row (and some fancy formatting). One situation to watch out for is using an external data source to provide the list items. If you need to do this, then you also need to make sure the number of items provided by the data source is limited to a reasonable number. As with any design, it is always a recommended best practice to test alternative designs for expected (and exceptional) data sizes to determine how your form designs perform.

    • Many visible controls

      Forms that have a large number of InfoPath controls visible in a view will reduce browser performance. Again, this is amplified when the controls are in repeating sections or tables. The first suggestion is to use multiple views so that each view has fewer controls to be rendered. If you use multiple views, make sure that controls are only bound once in the view in which they are used (use the Design Checker). Once again, you can also use conditional formatting to hide some of the controls, but this will typically achieve a smaller gain in browser performance compared to using multiple views. Because there are a number of important variables that determine browser rendering performance, your design alternatives should be tested in the common user environments you expect (data size, browser type, user's machine configuration) to determine acceptable number of controls and the relative performance of each design.

    • Calculations that use large data sets

      If you design a form that includes calculations and the data for the calculations is loaded from an external data source, then that data will be downloaded to the browser so that the calculation can run in the browser without a postback to the server. Normally this strategy improves overall performance by reducing postbacks. However, if the data set is large, the benefit of eliminating postbacks can be overtaken by the performance cost of handling the data in the browser. First, it is more expensive to load a large data set; second, it is expensive to run after it is loaded.

      If you find that the browser is too slow when running calculations with large data sets, you can force a postback so that the calculation runs on the server instead. In the InfoPath Designer, for the field that runs the calculation, add a button and change the postback setting to always require a postback. When the user clicks the button to run the calculation, it will postback to the server to evaluate the calculation and return the result to the browser for display. Like most performance suggestions, you need to balance performance in the browser with the performance and scalability of your form server system.

    • Reporting scenarios

      InfoPath is primarily designed to address form-filling scenarios. Although it can also be used to display data in a reporting scenario, this can have a negative impact on browser performance as the amount of data downloaded for display increases. If there is a possibility that the amount of data could be very large, then you can expect performance problems not only in the browser, but also on the server. Depending your ability to predict and limit the amount of data in a reporting form, it might be possible to maintain acceptable performance by using multiple views and read-only controls. However, if the data is too large or cannot be limited practically, you should consider an alternate reporting solution.

    • Internet Explorer 6

      If you have form users that are using Internet Explorer 6, they will experience reduced browser performance compared with other browsers due to known issues with IE6 JavaScript performance. You might consider providing a statement on your site about browser support, and if you know you have a substantial number of users running IE6, then it is a good practice to include IE6 performance testing in your development plans.

    Use the Design Checker to monitor browser compatibility issues

    The InfoPath Designer allows you to design forms that run in both the rich-client and a browser. When you are designing browser-enabled forms, and especially when you want your form to support running in both environments, you need to be careful about browser compatibility issues. As you are designing a form template in the InfoPath Designer, you can use the Design Checker task pane to monitor any browser compatibility issues detected by InfoPath, including those that affect performance.

    Among the messages displayed by the Design Checker are warnings for controls that will trigger postbacks to the server (these messages are hidden by default; to view them, select "Browser Optimization Messages" from the Options button at the bottom of the Design Checker). One or messages can appear for each control that will post back to the server when the value of the control changes.

    Sometimes the postback occurs because of a calculation, binding, or other expression on that control. Occasionally a control will post back to the server not because of a property on that control, but because that control is contained inside a section or a table where some other control forces a postback, or the control contains a section, table, or other controls inside it that cause a postback. In these cases, the warning messages indicate that you should look for another control marked as a primary cause of the postback; examining the messages for that control can help you locate, understand, and control postbacks caused by related controls.

    If having other controls bound to the same element or group are causing unwanted postbacks, consider using separate views, with the control bound once in each view.

    To resolve issues where the binding of the control requires server evaluation, or a node is listed as only available on the server, you might need to simplify your schema.

    You can change the default postback behavior for an individual control using the Postback settings options on the Browser forms tab in the Properties window for the control. There are three options available: Never, Always, and Only when necessary for correct rendering of the form (recommended). You can reduce the number of postbacks by changing the setting to Never. If you select Never, then the control will not send data to the server on change; the data will only go to the server and formatting, calculations, etc. will only run when the form user saves or submits the form, or another control in the form causes a postback to the server. For controls you want to change, you must change the postback setting option on each control individually; changing the option on a section or group control does not automatically change the value for every control inside it.

    Note that you should carefully consider the effect of changing postback behavior to ensure that the result is acceptable for your environment. Be careful about suppressing postbacks that affect the user’s form-filling experience to avoid issues where displayed data could be incorrect. You never want to sacrifice data integrity for a potential gain in performance. If you make any change to the postback settings, it should be thoroughly tested to ensure the form behaves correctly.

    What’s next?

    The next article in our series provides information on some of the useful performance monitoring counters that can help you evaluate the performance of your form system.

  • Microsoft InfoPath 2010

    Extended data validation for the Multiple-Selection List Box in InfoPath 2010


    Hi, Frank Mueller from the InfoPath development team here. The Multiple-Selection List Box (MSLB) control was introduced in InfoPath 2007 to enable users to select multiple items from a list when filling out forms. In this post, I will explain the different ways you can restrict and validate the data entered using this control in InfoPath 2010. I will also cover some advanced tips and tricks.

    In this post:

    Data Validation

    Special behavior in SharePoint List Forms

    Removing Blank Default Values

    Example Usage:

    First let’s look at a scenario where you may want to use the MSLB control. Say, for example, you are building a form for customers to order your company’s products. To be able to more effectively spend the company’s marketing budget in the future, the marketing department would like to know how your customers found the company’s web site. So you’ve added a Multiple-Selection List Box to gather responses to that question.

    Multi-select list box

    Your customers can now select one or more options. If a customer heard about the web site through a channel that is not specified in the Multiple-Selection List Box control, he/she can select the last checkbox and just type in a custom response.

    Data validation

    The marketing department is pleased with the new order form, but many customers do not bother responding to the “How did you hear about us?” question. With InfoPath 2010, solving this problem is very easy.

    In InfoPath 2010, there are two main ways that form designers can restrict and validate the data entered using the MSLB control.

    1. Require that at least one item be selected (At least one selection required) (NEW in InfoPath 2010)
    2. Require that every selected item have a value (Cannot be blank)

    Multi-select list box Properties

    Require that at least one item be selected (At least one selection required) (NEW in InfoPath 2010)

    New in InfoPath 2010, we can now enforce that users select at least one non-blank item by setting the “At least one selection required” property. In most cases, this is the setting that you will want to use.

    When you preview the form, you will notice a red asterisk in the upper right corner of the control, indicating that a selection is required.

    Multi-select list box If you select a blank custom value, an asterisk will appear in the top right hand corner of the custom value text box.

    Multi-select list box All asterisks will disappear as soon as you select an option that is not blank, or you select the custom value text box and type in a value.

    Technical Details

    The new type of data validation is only applicable to repeating fields that are bound to Multiple-Selection List Box controls.

    When setting the property at the field-level (instead of on the control), you will notice that it’s called “Non-empty occurrence required”. This is because the field can be bound to a control other than the MSLB, in which case users do not make selections when using the control.

    You may set any repeating field to “Non-empty occurrence required”, but you will only see an effect when the field is bound to a Multiple-Selection List Box control. “Non-empty occurrence required” is not implemented as an XSD constraining facet, but rather as a special Validation Rule that is stored in the manifest.xsf of your form template. This has the benefit that you can set the data validation even if you are designing a form template based on a locked schema.

    Require that every selected item have a value (Cannot be blank)

    In most cases, the “At least one selection required” property will do you what you need to ensure that users enter the required data.
    In InfoPath 2010, we still support the legacy “Cannot be blank” property. When this property is set, it requires that every item that a user selects from the list has a value. It does not however require that users select an item in the first place.
    When you preview the form, you will notice a red asterisk, whenever you select the checkbox of the custom value text box. This indicates that if the user wants to select this option, a value has to be typed in the text box before the form can be submitted. Once you type some text in the custom value text box, the asterisk will disappear.

    Multi-select list box

    Technical Details

    When a field in an InfoPath form is set to “Cannot be blank”, a minLength constraining facet is applied to the XSD element, which requires that corresponding XML nodes contain at least one character.

    <xsd:element name="field1" type="my:requiredString"/>   
             <xsd:simpleType name="requiredString">
                      <xsd:restriction base="xsd:string">                           
                              <xsd:minLength value="1"/>

    This makes sense for text fields, when the form designer wants to ensure that the person filling out the form has to enter data into the field before it can be submitted for further processing.
          First Name
    The Multiple-Selection List Box control is bound to a repeating field in the form’s data source. When the user fills out the form and makes selections in the control, a new XML node is created for each selection made. If you mark the repeating field that the control is bound to as “Cannot be blank”, InfoPath will ensure that all options selected or entered through the custom value textbox are not blank. However, if no selections are made in the control, no XML nodes are created, and hence the constraining facet of the field is not violated, and the user is not forced to make a selection.

    When would I want to use “Cannot be blank” instead of “At least one selection required”?

    If you want to ensure that users do not select any item that does not have a value then the “Cannot be blank” property can be used.

    In the example below, both “At least one selection required” and “Cannot be blank” are set. The data is not valid because the custom selection is blank.

    Multi-select list box

    In the example below, only the “At least one selection required” is set. The data is valid because at least one non-blank item is selected.

    Multi-select list box

    Advanced Information:

    Special behavior in customized SharePoint list forms

    In a SharePoint list, when you mark a Choice column as required, it requires users to select at least 1 item and for all selected items to have values.

    SharePoint Column Settings

    Marking the field as required in SharePoint, has the same effect as setting both the “Cannot be blank” and “At least one selection required” properties in InfoPath.  For consistency with SharePoint, when customizing a SharePoint list form in InfoPath 2010, only one data validation option, “Cannot be blank” is available.

    Removing Blank Default values

    When designing the order form described above, InfoPath will by default insert a blank default value node for each repeating field. As you preview the form you will notice that the custom value text box at the bottom of the Multiple-Selection List Box control will be checked by default.

    Multi-select list box

    If you wish there to be no default selection at all in the control, you need to remove the default value node.

    1. Click on the File button
    2. Select Form Options under the Form Information tab
    3. Select the Advanced category in the Form Options dialog
    4. Click on the Edit Default Values … button
    5. Click on the pluses in front of the fields to expand the data source until you can see the repeating field that is bound to the Multiple-Selection List Box control
    6. Uncheck the checkbox in front of the repeating field

      Edit Default Values

    7. Click OK to close both opened dialogs
    When you preview your form now, you will notice that the custom value checkbox is not selected by default.

    Multi-select list box

    Frank Mueller
    InfoPath Developer

  • Microsoft InfoPath 2010

    Designing browser-enabled forms for performance in InfoPath Forms Services (Part 2)


    Part 2 – Postbacks and conditions that cause them

    Welcome to the second article in our series on optimizing the performance of browser-enabled forms designed with Microsoft Office InfoPath 2007. In our first article, we defined performance in terms of responsiveness. In this article, we’ll focus on postbacks, one of the most common causes of reduced performance

    Postbacks are probably the most important factor affecting form performance because the effect of other conditions is amplified with each postback. There are two significant aspects of postbacks which we’ll examine in this series. First, which form features cause postbacks? Those features are the subject of this article. Second, what kinds of postbacks are more expensive to process, thus imposing an additional burden on the performance and scalability of the form system? We’ll examine those factors in the next article.

    What is a postback?

    Certain form controls, actions, and features require the browser to communicate with the server during the form-filling session. This exchange of data during the session is called a postback, and usually occurs when a form feature needs to send data to the server for processing. After sending the postback request, the browser must then wait for a response before it can update and re-render the form with the new data. In the case of a full-page postback, the browser must stop rendering completely until the whole updated page is returned, blocking user interaction with the form until it has been re-rendered. Alternately, to improve the user experience in the browser, some features use a partial postback, where only a specific part of the form is updated. This allows the user to continue interacting with other parts of the form while the update happens in the background. In either case, however, unnecessary postbacks impose an additional load on both the browser and the server. If you can reduce or eliminate postbacks as you design, develop, and test your forms, you can improve the performance and scalability of your entire form system.

    Browser-enabled form handling compared with InfoPath client forms

    To better understand the effects of postbacks on performance, it is helpful to compare basic form handling of the InfoPath-rich client with InfoPath Forms Services and browser-enabled forms. Whether you are new to InfoPath, or you are familiar with rich client forms but new to InfoPath Forms Services and browser-enabled forms, understanding these basic differences will help you improve your form design and troubleshooting strategies.

    The major difference between the InfoPath-rich client and browser-enabled form systems is that the InfoPath client doesn’t need to communicate with the form server as frequently as the browser does. This is because the InfoPath client processes most forms locally on the user’s computer. In contrast, the browser form relies on the server for a variety of form processing operations, requiring more communication to exchange data between the browser and the form server. Communication in the form of postbacks is a fundamental feature that allows InfoPath to support browser-enabled forms on the Web, but postbacks also make browser forms more sensitive to performance issues.

    Let’s look at two form loading and editing scenarios that further illustrate the difference between form processing in the InfoPath client and browser-enabled form systems.

    In the InfoPath-rich client scenario, when the user opens the form from a SharePoint form library, InfoPath first determines that the form should be opened in the client rather than the browser. After the initial download of a copy of the requested form template, InfoPath opens and renders an instance of the form on the user’s computer for editing. The form instance in the client is an XML document that the client renders in HTML for display. As the user interacts with the form, the InfoPath client processes and renders changes, and might run some custom form code, all within the context of the client running on the user’s computer. Generally, the only time the client needs to connect back to the server is to make additional data connection requests to query from or submit to a data source, to save a partially completed form, or to submit the final form.

    In the case of the browser-enabled form, when InfoPath Forms Services receives an initial request for the form from the browser, the server starts a session for that user’s form-filling session, allocates server resources, and processes the browser-enabled form template to load an instance of the form XML for the session. In addition, if the form requires it, the server might load and run custom form code and load data from a data source. After this initial processing, the server assembles the JavaScript and HTML that represent the form instance to be downloaded to and rendered by the browser.

    Finally, the server sends the response through a Web Front End server over the network to the browser on the user’s computer, which renders the initial download into the form view that the user interacts with. As the user interacts with the form in the browser, some form processing happens in the browser, but more complex form elements and events require a postback to the server for processing.

    During the transmission and processing of the form data, the browser instance of the form must wait for a response and then re-render the updated form. In this communication cycle, each postback request and response set constitutes a roundtrip. Each roundtrip affects the performance and scalability of the form system in terms of throughput, responsiveness, and resource utilization. This impacts both the browser side and the server side, as well as the network.

    As you can see from these two scenarios, a form-filling session in the browser-enabled form system requires substantially more communication than a similar session in the InfoPath client. In addition, more of the browser-enabled form processing is concentrated on the server, especially when multiple form-filling sessions are being served. In contrast, with an InfoPath client form, the form processing is distributed to the user systems. Consequently, reducing the number and complexity of postbacks as you’re designing browser-enabled forms can substantially boost performance.

    Ten common causes of postbacks

    1. Complex calculations

      A calculation can cause a postback when there is a condition that cannot be evaluated in the browser and requires processing by the server. For example, if a calculation requires data that is not loaded in the DOM, then the browser must send a postback to the server and wait for the result. Another condition that will invoke a postback involves any calculation that is out of the context of the current node. For example, you could create an expression such as .\.\.\my:field1+. When the expression is invoked in the form, because it requires traversing up the tree several levels from the current node, it must be sent to the server for evaluation.

    2. Data adapters

      The function of a data adapter is to make a query connection to an external data source, such as an XML file, a database, a SharePoint list, or a Web service, so that a form can receive and be updated with some data from the data source. If a form invokes a data adapter when the form loads, the browser must wait for the data connection, increasing form load time. If the form invokes a data adapter after the form loads, a postback containing the query request is first sent to the form server, which executes the data connection request on behalf of the browser form, adding additional time to the roundtrip.

    3. Multiple binding: data bound to multiple controls

      Multiple binding happens when one piece of data in the form is bound to two or more controls in the same view. This is usually done so that the same data can be displayed in multiple places. For example, you might design a report with several sections to include a single non-repeating field, such as "Report Date", inside a repeating section so that the same date is displayed in each report section. If you design a form this way, then changing the "Report Date" field in one location will update it everywhere because it is multiply bound. Unfortunately, the cost of this multiple binding might be a roundtrip to the server if the binding is more complex than the browser can resolve. In this case, server analysis is required to reliably identify all the controls bound to the same piece of data. In addition, if something is both multiply bound and out of context, then user edits to form fields will always require roundtrips. Other form actions that will cause roundtrips to the server when there is multiple binding include insertion or removal of repeating tables and repeating or optional sections.

    4. Out-of-context binding

      Out-of-context binding describes a situation where a control inside a repeating or optional section is bound to a node that is in a different part of the XML data source tree, outside the group node that contains the repeating or optional section control. When an out-of-context situation occurs in a form, the correct binding may be too complex to determine within the browser. If either the validity or the kind of action—such as a calculation—cannot be determined in the browser, the out-of context binding will trigger a roundtrip to the server to resolve the binding.

      You are most likely to encounter this problem as you’re designing a form in the InfoPath Designer if you first insert a group or control, and then later decide to move that group or control into an optional section. To avoid creating an out-of-context binding, after you drag and drop the control into the optional section, in the data source pane, drag the node the control is bound to into the group for the new optional section. The group or control will then be bound to the correct context.

    5. View switching

      Multiple views are often used to present a specific view to a specific user audience in a workflow. Multiple views are also commonly used to improve the performance of a form; by careful grouping of related items and limiting the number of controls in each view you can improve the form loading and rendering performance compared to placing everything in a single view. However, each time the view is switched, there is a full postback to send the user’s changes to the server, get the new view, and reload it in the browser. If possible, try to group the items on a view so that any controls that might postback do so when the view is switched. Then only one postback occurs when switching the view. A good example of this is using a button to invoke a query connection that returns data for a list, an operation that requires a postback. If the view is also switched when the button is clicked, you improve the efficiency of the postback. Another benefit of this design is that it makes the view switch a user-invoked action, which improves the user’s perception of the form response. By coordinating the postback of controls in the view with a view switch, you not only improve the responsiveness of the form, but also reduce stress on the server and network by eliminating extra postbacks. When designing your form there is no formula for when to use multiple views, so you will need to balance your use of multiple views with the potential design and performance advantages and costs in your user scenarios.

    6. Conditional formatting

      Conditional formatting is commonly used to hide part of a form from view until some condition is met. However, conditional formatting expressions fire every time the form is rendered whether hidden or not. Additionally, all of the data, calculations, and expressions used by fields that are conditionally hidden are still downloaded and can cause extra performance overhead. Thus if anything else invokes a postback, your form will incur this additional overhead. Similarly, if the conditional formatting requires a postback, then there is a postback each time the form is rendered. Although the primary reason for using conditional formatting has more to do with your form design and presentation, there may also be a slight increase in the responsiveness of the form if it uses conditional formatting. This is possible because it can be slower to render something in the browser than to execute the conditional formatting. However, if you need to substantially limit the presentation, consider using multiple views instead of conditional formatting because multiple views generally perform better.

    7. Digital signatures

      For forms that are filled out in Internet Explorer, signing a form uses an ActiveX control that communicates with the server using out-of-band postbacks. The signature operation involves 3 main steps:

      1. Gather client-specific information to be used by the signature data
      2. Server preprocessing to prepare the stored XML document for signing
      3. Apply the final signature

      Each step causes a postback, the first and the last being relatively expensive. This is because the first postback sends, among other things, the data corresponding to the non-repudiation image to be stored in the signature. The last is a full postback that refreshes the browser with the new signed document that has been prepared on the server.

    8. Business logic event handling

      Normally, when a user changes the values of several controls in the browser form, the JavaScript form logic in the browser can optimize the changes, batching them together to avoid a postback for each change. This reduces the number of postbacks to one. However, this optimization is not possible if the form has code or other logic, such as rules or conditional formatting, that listens to data changes in parts of the XML DOM. For example, if a control is bound to a particular DOM element and a listener is present, changes in that control are immediately communicated to the server and the corresponding event handler invoked. The number of extra postbacks depends not only on the number of event handlers, but also on the XPath they use to listen to DOM events. This is because InfoPath XML events bubble. For example, if some form code has business logic with an event handler that listens to a node close to the root node, there will be relatively more postbacks. This is because any browser change affecting one of the descendants of that node will trigger a postback to the server. Consequently, if your form uses form code or any other construct that involves listening to changes, it is important for performance and scalability that you understand and carefully scope events to reduce unnecessary postbacks and server stress.

    9. Custom hosting pages and external page events

      If you are using advanced form techniques such as developing your own ASP.NET page to host the InfoPath Form control, then there are a couple of things you should be aware of. Submitting to a custom hosting page requires full page postback because the XmlFormView control resides on the server and it involves rebuilding the page controls by ASP.NET. In addition, when submitting the form, before the submit is finalized, data is sent back to the browser with a pending submit action added. This pending submit action must then be sent back to the server in another postback to actually complete the submission. If the page is hosted on a SharePoint site, it also must initialize the SharePoint page infrastructure as well. Also, if an XmlFormView control is hosted on a custom ASPX page and the page listens to events from the control, then every operation triggering an event in the XmlFormView control will require full page postback.

    10. Complex XPaths

      In some advanced form design scenarios, you might build your own complex custom expressions or calculations using the "Edit XPath (advanced)" option. Although most common expressions or calculations can run in the browser, those that require more complex XPaths to evaluate may need to postback to the server. The following complex XPath conditions will cause extra postbacks:

      • More than one possible context for a filter
      • Complex XPath that is not used as a filter
      • XPath where the user input  is not a filter
      • XPath filter or rule that references an element that is not in the current view
      • XPath filter that is position-based
      • XPath with inline functions
      • XPath that includes an unrecognized function
      • XPath that includes an extension function that is not supported by the browser
      • XPath has an inner expression
      • Expressions containing inner nodes


    What’s next?

    In our next article we’ll examine some of the conditions that make postbacks more expensive and that affect the performance and scalability of a server system running InfoPath Forms Services.



  • Microsoft InfoPath 2010

    Digitally Signed Fully Trusted Form Templates


    In the InfoPath 2003 Service Pack 1 Preview you can create a fully trusted form template by signing the XSN with a code signing certificate.  Here’s what you do:


    • While in the InfoPath designer, select Tools | Form Options | Security
    • Uncheck the “Automatically determine security level based on form’s design
    • Select Full Trust
    • Click the Sign this form button

    At this point, you need to choose a certificate that can be used for code signing.


    If you do not have a certificate, you can choose the Create Certificate button.  This will create a test certificate – not a certificate that has been authenticated by a certificate authority.


    While you are developing your form template, you will not be able to preview with full trust permissions unless you register the form template. 


    The first time your users fill out the form that you have signed with a certain certificate, they will see a Security Warning dialog that notifies them that the form template is digitally signed and asks if they trust the publisher.  Once they have checked the box to trust the publisher, they will be able to open any form template that asks for full trust and is signed with that same certificate.


    You can view the list of trusted publishers in the SP1 version of InfoPath by selecting Tools | Options and clicking on the Trusted Publishers button.


    If users find that the option to trust the publisher is disabled, that means that the root of the certificate used is not trusted on the user’s machine. 


    When you received your code-signing certificate, you asked the CA (Certificate Authority) for it. What the CA delivered to you is a certificate that is now in your personal folder that is trusted by you and by anybody who trusts the CA that issued it.  So, for example, if you get a code signing certificate from Verisign, any user will have the option to trust you as a publisher as long as they also have Verisign in the list of Trusted Root Certification Authorities on their machine.  Once a user has trusted the root of a certificate, the option to trust the publisher will be enabled in the Security Warning dialog that is displayed when they fill out a fully-trusted, signed form.


    Users can trust the root of a certificate through the Security Warning dialog that comes up when they open a form template.  When the Security Warning dialog is open:


    • Click on the Details button
    • Click on the Certification Path tab
    • Click on the CA Root Certificate
    • Click View Certificate button
    • Click Install Certificate
    • Follow through the Certificate Import Wizard
    • After the import is successful, close out of all of the dialogs
    • Open the form to fill out again and when the Security Warning is displayed the option to trust the publisher should be enabled.



  • Microsoft InfoPath 2010

    Sorting Repeating and Tabular Data


    InfoPath is a great way to easily gather and present XML data to the masses. But what about efficiently presenting a massive amount data? Tons of data (e.g., a list of hundreds product names) usually find their ways into lists that we’ll find on SharePoint, in a database, or just sitting in an XML file. Controls like Repeating Sections and Tables are useful mechanisms for displaying lists of data. But their usefulness is limited to how efficiently the user of your form can find and work with such large lists of data. An easy solution to effectively present large lists of data to your users is through sorting that data.

    No Sorting Options in InfoPath
    Try scouring the Repeating Table or Repeating Section controls’ properties dialogs for anything related to “sort”. Sorry to say, you’ll come up empty handed. That’s why we thought you’d find this blog entry handy. Our goal is to show you how to sort any repeating data and to do so in many different ways: sort by string, sort by number, sort ascending or descending, and even sort by different fields (or columns) in the repeating data. What we’ll show you, in both the code and the design of the view, is designed to be browser-compatible. This means you can publish this form template to a SharePoint server running Forms Services 2007 and fill out the form in a Web browser. Let’s get started.


    Figure 1: Filling out the SortingPeople sample form template

    The sample form template is attached; download the ZIP to your desktop, expand it, then right-click the XSN and select "Open in Design Mode". This sample requires InfoPath 2007, and will work in the browser when published to InfoPath Forms Services.

    The View for the SortingPeople Form Template
    To show you how to sort data in your form, we’ll use a concocted example to sort a list of people. As you can see in Figure 1, there are various options to sort the data. Clicking the “Sort” Button triggers the sort otherwise the data is not sorted automatically (more on this later). You can also sort by clicking any of the “Sort by this column” Buttons in the header and footer of any column. There are three columns in the Repeating Table representing our repeating data: Last Name, First Name, and Age. (The string data type is used for the first two columns and an integer data type for the last column.) In Figure 1, we’ve filled out the form with names of famous architects. (Their ages are fictitious.) While we’re not working with enough data to really justify a sort, this example is simply for demonstrative purposes. As you might expect, we can sort the Repeating Table data by any column and by any direction (ascending or descending). At any time we can change the existing data or even add or remove rows. But we would need to invoke the sorting functionality to put things into place again.

    The Data Source for the SortingPeople Form Template
    To begin designing this form template we started with controls and the data source. We inserted a Repeating Table control and renamed its data source groups and fields to map with our people example. The main data source is shown in Figure 2. To accommodate the various sorting options that we expose via controls at the top of the view (e.g., the Sort By Drop-Down List Box), we’ve added attribute fields under the SortingPeople document element. These attribute fields remember, for example, whether we’re sorting by the Last Name or the Age column.

    Figure 2: Data source for the SortingPeople sample form template

    Considerations When Sorting Data
    Now we’ll look at how we implemented sorting functionality behind this form template. This is accomplished through C# code behind the form. While we could have opted for an easier XSL-based implementation to sorting data, it would not have been compatible with Forms Services. So we’re left to actually sorting the data. There are advantages as well as disadvantages to our approach. Sorting the data is preferred when you want to persist the sorting in the saved or submitted form. While the initial cost is much higher to sort the data in the data source instead of the view, there is much less processing that occurs on subsequent visits to that data because it will already be sorted. If your form template has multiple views, switching to and from a view that performs an XSL sort is very expensive. On the contrary, a sorted data source adds no additional processing requirements on view switches. A final reason why you may want to sort the data in the data source instead of the view: submitting sorted data to a database or Web service may be optimal (or even a requirement) for that backend system.

    Sorting Data with C# Form Code
    To best understand how we designed the code behind form template to support sorting, we’ll be talking about its C# form code and how it interacts with the main data source. Let’s start by looking at some of the supporting form code that will make it easier for us to implement the sort feature. The properties are used within the sort itself to read the options at the top of the view about how to sort the data. The methods are very useful helpers that we use throughout our sample code.

    /// <summary>

    /// Returns the "Sort By" Drop-Down value.

    /// The value returned by this property MUST match with an item within the Repeating Table.

    /// </summary>

    private string SortBySelection


        get { return GetValue("@my:SortBy").Replace(" ", string.Empty); }



    /// <summary>

    /// Does the user want the SortBy by number (true) or string (false)?

    /// </summary>

    private bool SortAsNumber




            return 0 == GetValue("@my:SortAs").CompareTo("number");




    /// <summary>

    /// Does the user want an ascending (asc) or descending (des) sort?

    /// </summary>

    private bool SortAscending




            return 0 == GetValue("@my:Order").CompareTo("asc");




    /// <summary>

    /// Helper to wrap an int within brackets.

    /// </summary>

    /// <param name="intToWrap"></param>

    /// <returns></returns>

    private string WrapAsIndexer(int intToWrap)

    { return WrapAsIndexer(intToWrap.ToString()); }


    /// <summary>

    /// Helper to wrap a string within brackets.

    /// </summary>

    /// <param name="strToWrap"></param>

    /// <returns></returns>

    private string WrapAsIndexer(string strToWrap)

    { return "[" + strToWrap + "]"; }


    /// <summary>

    /// Helper to get an XPathNavigator's value.

    /// </summary>

    /// <param name="xpath"></param>

    /// <returns></returns>

    private string GetValue(string xpath)


        return Root.SelectSingleNode(xpath, NamespaceManager).Value;



    /// <summary>

    /// Helper to set an XPathNavigator's value.

    /// </summary>

    /// <param name="xpath"></param>

    /// <param name="value"></param>

    private void SetValue(string xpath, string value)


        Root.SelectSingleNode(xpath, NamespaceManager).SetValue(value);



    /// <summary>

    /// Helper to get the document element of the main data source.

    /// </summary>

    private XPathNavigator Root


        get { return CreateNavigator().SelectSingleNode("/my:SortingPeople", NamespaceManager); }


    Next, let’s take a look at the code behind all of the Buttons in our form template. We created these event handlers through each Button’s properties dialog. Their implementations are quite trivial. You can see that adding additional sorting columns to the Repeating Table is a simple task. If you wanted to add a column that doesn’t need to be sorted, there’s nothing to do beyond adding the column in the Table!

    public void SortButton_Clicked(object sender, ClickedEventArgs e)





    public void LastNameSort_Clicked(object sender, ClickedEventArgs e)


        SetValue("@my:SortBy", "Last Name");




    public void FirstNameSort_Clicked(object sender, ClickedEventArgs e)


        SetValue("@my:SortBy", "First Name");




    public void AgeSort_Clicked(object sender, ClickedEventArgs e)


        SetValue("@my:SortBy", "Age");



    Now the million dollar question: what’s behind the SortList method? Let’s look and then we’ll explain how it works.

    /// <summary>

    /// Bubble sorts the list of people.

    /// </summary>

    private void SortList()


        string sortBy = SortBySelection;

        string itemsToSort = "my:People/my:Person";

        System.Globalization.CultureInfo currentThreadCulture =



        int numPeople = Root.Select(itemsToSort, NamespaceManager).Count;


        // basic bubble sort implementation

        for (int i = 1; i < numPeople; i++) // xpath is 1-based


            for (int j = i + 1; j <= numPeople; j++) // keep j ahead of i; we can index [numPeople]


                // swap (i,j) if necessary

                string iValue = GetValue(itemsToSort + WrapAsIndexer(i) + "/my:" + sortBy);

                string jValue = GetValue(itemsToSort + WrapAsIndexer(j) + "/my:" + sortBy);


                // Do we sort by number or string?

                if (SortAsNumber)


                    int iNum, jNum;

                    if (!Int32.TryParse(iValue, out iNum) || !Int32.TryParse(jValue, out jNum))


                        // Let InfoPath take care of the invalid datatype with its own validation, we'll keep sorting the rest




                    if ((SortAscending && iNum > jNum) || (!SortAscending && iNum < jNum))


                        Swap(itemsToSort + WrapAsIndexer(i), itemsToSort + WrapAsIndexer(j));



                else // SortAsString


                    if ((SortAscending && String.Compare(

                        iValue, jValue, true /*ignoreCase*/, currentThreadCulture) > 0)

                        || (!SortAscending && String.Compare(

                        iValue, jValue, true /*ignoreCase*/, currentThreadCulture) < 0))


                        Swap(itemsToSort + WrapAsIndexer(i), itemsToSort + WrapAsIndexer(j));



            } // end inner-for

        } // end outer-for


    Analyzing the C# Form Code
    Let’s break down what we’re doing in this SortList method. First we get the column to use for sorting, the XPath to the repeating group that we want to sort, and the culture of the thread so we respect the current locale when sorting. Next we get the number of people that we’ll be sorting. We need this number because we’ll use it for our bubble sort implementation.

    The two nested for-loops implement the bubble sort algorithm. We chose bubble sort because of its simplicity and for demonstrative purposes. (We’d recommend you use the most efficient sorting algorithm based on your requirements.) The variables i and j iterate through the people. We use the iValue and jValue variables to select the data pointed at by i and j to determine if a swap is necessary as part of the sort loop.

    Next, we have an if-else statement that checks if the sort is by string or by number. A sort by number will attempt to parse out 32-bit integer values from the iValue and jValue fields. If the parse fails for any reason, we skip this specific comparison and continue trying to sort the rest of the data. Once we have integers, we do a simple comparison and swap if needed. If we’re sorting by string instead of numerical value, we use the static .NET library String.Compare method to make a culture sensitive comparison. A swap is performed if it’s necessary. (Note that we could have combined some code in the SortList method to make it more compact. We left the structure of the code unoptimized for maximum readability.)

    The last bit of code we have not yet revealed is the Swap method. This method, as its name suggests, simply swaps the positions of two XPathNavigator objects as identified by their XPaths. (An XPathNavigator is a pointer into an XML tree of data. You can read more about the XPathNavigtor class on MSDN.)

    /// <summary>

    /// Swaps two XPathNavigators at xpath1 and xpath2.

    /// </summary>

    /// <param name="xpath1">First XPath.</param>

    /// <param name="xpath2">Second XPath.</param>

    private void Swap(string xpath1, string xpath2)


            XPathNavigator item1 = Root.SelectSingleNode(xpath1, NamespaceManager);

            XPathNavigator item2 = Root.SelectSingleNode(xpath2, NamespaceManager);


            // Make a copy of item1

            XPathNavigator item1Clone = item1.Clone();

            // Move item2 to item1


            // Make the original item2 be item1 that we cloned earlier



    Sorting Automatically
    One of the things you might ask is why we decided against sorting the data automatically. The most important reason is user experience and then followed by form responsiveness. Think about what would happen if the Repeating Table rows sorted themselves whenever data changed that required a sort. Say you were entering data into a new row. You start by typing a person’s last name and then either hit tab or click into the First Name field. If the form is sorting by the Last Name field, the row may have jumped to another location relative to the other rows in the Repeating Table! You would expect that you could fill in all of the data for a new row before it sorts itself. There are also other weird cases that automatic sorting would spoil. For example, you would not see a new row added within the middle of the Repeating Table. Why? As soon as you added it, it immediately jumped to the top (or bottom) of the Repeating Table as sorted data. Let’s consider for a moment why we didn’t automatically sort because of form responsiveness; for now let’s assume that we somehow worked out all of the kinks with the user model. Obviously the form will be less responsive in InfoPath, especially on a slow computer, with so much sorting. But the real problem is realized when filling out such an intense form template in a Web browser. Every time code runs while a form is filled out in a browser, the form data is posted back to the server for processing. Postbacks themselves can take several seconds or even minutes depending on many variables including the network connection speed as well as the client and server machines’ performance capabilities. As you can see, an automatically sorting form isn’t necessarily a better form.

    Hagen Green
    Software Design Engineer in Test

  • Microsoft InfoPath 2010

    Consuming Excel Data using InfoPath Database Data Connections


    InfoPath data connections can be one of the most powerful features of the product.  However, sometimes the out-of-box support for various data sources just doesn't seem to cut it when you get out into the field.  How in the world can I get data from an Excel spreadsheet  into my InfoPath form?  A typical response might include externally automating Excel via COM or the managed PIA to create InfoPath forms.  Or you might try using the Excel 2003 XML spreadsheet file format with the InfoPath XML data connection.  While both solutions are feasible, they can be a bit clunky to manage multiple files generated from your spreadsheet…
    Here is your question answered!  Access 2007 provides support for linked tables, virtual tables that pull data from a data source external to an Access database.  Since InfoPath has a built-in database data connection that can query data directly from an Access database, Access 2007 can effectively act as a router for data sources that aren't directly supported by InfoPath.  In this post, we'll step through setting up an InfoPath database data connection that queries data from an Excel spreadsheet.
    Prepare your Excel spreadsheet
    Once you've added all the necessary data to your Excel spreadsheet, save the Excel workbook to a shared network location that will be accessible to all users filling out your InfoPath form.
    Create the Access database to link the Excel data
    Launch Access 2007 and create a new blank database.  When you create a blank database, a default table will be created.  Go ahead and delete the table (just closing the query view should remove the table.)
    Switch to the "External Data" tab in the Ribbon


    Click the "Excel" icon in the "Import" chunk to launch the "Get External Data - Excel Spreadsheet" wizard.
    Browse to the Excel workbook that you saved in the "Prepare your Excel spreadsheet" section, above.
    Select "Link to the data source by creating a linked table" and then click "OK".


    Choose the Sheet or Named Range that you want to import, then click "Next >". If the first row of the spreadsheet contains column headers, check the "First Row Contains Column Headings", then click "Next >".

    Type a name for the linked table (I'll call it "Spreadsheet" for this post), then click "Finish".
    Click "OK" when Access tells you it's done linking the table.  When the dialogs close, you'll see the linked table listed in the "All Tables" task pane


    Save the Access database to the same directory where the Excel file was saved, then close Access.
    Design the InfoPath Form Template to Query the Linked Table
    Design an InfoPath Form Template based on a "Database" (you could also add the data connection as a secondary database data connection in an existing form template).


    Once you've clicked "OK", the "Data Connection Wizard" will open.  Click "Select Database…" to open the "Select Data Source" file browser dialog.

    Click "New Source…"

    NOTE: At this point, it's tempting to just browse to the Access database as you normally would.  However, the default provider used in that case does not support linked tables, so InfoPath will see no tables in the database.  In order to select the appropriate provider, you have to click "New Source…"


    Select "ODBC DSN", then click "Next >".
    Select "MS Access database", then click "Next >".

    Browse to the Access database that you created in the "Create the Access database to link the Excel data", above, then click "OK".

    NOTE:  This browse dialog can be a bit confusing.  If you get mixed up by the unusual browsing experience, you can just type or paste the full path to the database in the "Database Name" field (boxed in green in the screenshot below).


    Select the name of the linked table, then click "Next >"
    Finish the data connection wizard as you would for any other database data connection.
    At this point, you're good to go.  The data connection to your Excel data will behave the same as a query-only Access database data connection.

    - Forrest Dillaway, InfoPath Test


  • Microsoft InfoPath 2010

    Where do UDC files come from?

    Where do UDC files come from? - I knew you’d ask. (For those of you who are wondering what a UDC file is, you should go read my post entitled "Making data connections work in browser forms.")
    There are a couple of ways to go about it. UDC files are just xml files with a specific namespace and schema, so once you have a few examples you can probably get around handily with notepad and cut and paste. However, we’ve made it easier than that with the new Convert functionality on the Manage Data Connections dialog. (For those intrepid souls who prefer the notepad route, a schema reference is being prepared for publication.)
    If you start out by designing your data connection the way you normally would, you can then use the Convert button to change the connection from settings in the form template to settings in a data connection file. (In fact, you can open any existing form template in InfoPath 2007 and convert existing data connections the same way.)
    To start with, make sure you have write permissions to a data connection library (henceforth "DCL") on the Microsoft Office SharePoint 2007 server you’re going to publish your form to. Then, using InfoPath 2007 Beta 2 or later, create your data connection or open a form template with an existing data connection. Make sure the connection is to a source supported by UDC. (E-mail connections, connections to a Microsoft Access database, or connections to an XML file in the form template cannot be converted to UDC connections.)
    Here’s the data connections dialog showing a few connections I threw together (you can get to this dialog off of the "tools" menu in InfoPath design mode):
    Click the Convert button and specify the path to your data connection library. If you click "Browse...", InfoPath will suggest a filename based on the name you gave the data connection when it was created.
    If you choose a data connection file that already exists, InfoPath will use the settings in the file you chose - don’t expect it to overwrite the original file with new settings. This could have unexpected results if the file that’s already in the library is a different connection type or returns data that does not conform to the schema your form template expects.
    For most cases, you want to leave the default connection link option. Choosing "centrally managed connection library" will cause InfoPath and Forms Services to look for the UDC file in the "Manage data connection files" library in SharePoint central admin. This is fine, but it means that you need to copy the file from the DCL where you created it to that location before you can use it. This presumes you have access to SharePoint Central Admin. See my last blog post entitled "Making data connections work in browser forms" for more information on this option.
    Once you click "OK" on this dialog, your UDC file will be created and saved to the location you specified, and the connection in the form template will be modified to retrieve settings from the UDC file rather than from the form template.
    NOTE: There’s a known issue in the Beta 2 release where you will see an "invalid URL" dialog at this point. This is benign and is no longer seen in the technical refresh.
    You now have a UDC file in your DCL, but you’re not quite done. By default, a DCL will require content approval before anyone other than the file’s owner can use the UDC file you uploaded. Unless the content approval requirement has been removed, a site administrator or someone else with the content approval right will need to set the file’s status to "approved."
    Adding Authentication
    InfoPath does not automatically configure server-only authentication options for you. However, when creating a UDC file, InfoPath automatically creates an authentication block within the UDC file that is preconfigured to use Office Single Sign-on. In order to use this authentication option, you’ll need to uncomment the authentication block within the file and add both the SSO application ID and the CredentialType. Most of the time, you’ll want to use the SSO credential to log onto Windows, for which you’ll need to specify "NTLM" as the CredentialType. The full list of possible credential types is as follows:
    Credentials will be embedded in a database connection string for authentication against a SQL server.
    Credentials will be used to impersonate a Windows user
    Credentials will be used to impersonate a Windows user using Kerberos
    The username will be used to impersonate a Windows user using Constrained delegation
    Credentials will be used to perform HTTP Basic authentication
    Credentials will be used to perform HTTP Digest authentication
    Reusing existing UDC files
    Once you’ve created your UDC file, you may want to use the same connection for other form templates. Among other things, this has the benefit of sharing settings for multiple forms in a common location. Changing the settings in the UDC file will cause all of the related forms to pick up the changes the next time they are used.
    There are several places in InfoPath where we expose the ability to re-use data connection settings exposed as UDC files in a data connection library. Here are a few examples:
    All of these entry points lead to this dialog:
    When you specify one or more SharePoint sites to search, this dialog allows you to browse available UDC files containing in DCLs on those sites. Based on the context, this dialog is filtered to show only applicable connections (for example, if you start from the "Design a form" dialog, this dialog will only show Web service and database connections).
    Once you’ve specified the UDC file to use, you may need to specify some properties for the connection that are not contained in the file (for example, for a SharePoint list connection, you’ll be asked to specify which columns to include in the data source), but otherwise, you’re done.
    - Nick Dallett
    Program Manager
  • Microsoft InfoPath 2010

    Data binding between Document Information Panel and Word document

    The Document Information Panel is a Microsoft Office InfoPath 2007 form that is hosted and displayed in a Microsoft Office Word 2007, Microsoft Office Excel 2007 or Microsoft Office PowerPoint 2007 document. It enables users to view and edit properties of a document or a content type that is associated to a document management server.
    In Microsoft Office Word 2007, users can add properties from Document Information Panel as content controls to document surface. This is also known as data binding between Document Information Panel and Word document. Users can bind Document Properties, Server Content Type Properties or Custom Properties. Once the data is successfully bound, users can edit the properties from Word document surface.
    This article will demonstrate two ways to bind data from Document Information Panels to Word document surface.
    Method 1: Binding Document Properties or Server Content Type Properties to document surface
    1. Launch Office Word 2007
    2. File | Open to open any Document Information Panel document
    3. Place IP in the document where you want the property control to be
    4. Click Ribbon UI Insert | Quick Parts | Document Property
    5. Choose the property you want to add:

    You now have a content control in Word surface that binds data to Document Information Panel property. Please note that this method also works for Server Properties, but you need to save or associate the document with the Server document library first. Then you will see Server Properties in Quick Parts | Document Property list.
    Method 2: Binding Custom Properties to document surface
    For non-document or non-server related properties, which are defined as Custom Properties in this blog, there is no UI to bind these properties directly to document surface. Users need to use Word Object Model to do the data binding.
    Assume the Custom Document Information Panel has the following data structure:
    Here are the steps to bind the costCenterID property to Word document.
    1. Launch Microsoft Word 2007
    2. File | Open to open a document that contains this custom Document Information Panel
    3. Press Alt+F11 to launch Microsoft Visual Basic editor
    4. Press Ctrl+G to launch the Immediate window
    5. In the Immediate window, add a Text content control by triggering the following command:
    ActiveDocument.ContentControls.Add wdContentControlText
    1. Set up this content control XML mapping to costCenterID node by triggering the following command:
    ActiveDocument.ContentControls(1).XMLMapping.SetMapping "//*[local-name(.)='costCenterID']",, ActiveDocument.CustomXMLParts(4)
    Here the SetMapping function takes three arguments. First input is the XPath of the node you plan to do a mapping.  Second one is PrefixMapping input. Last one is Custom XML Part source where the node belongs to. In this case, costCenterID node lives in 4th custom XML part.
    1. Switch back to Word active document window. The content control should get set up.

    Now you have successfully set up properties mapping between Document Information Panel and Word document. When you edit the properties from Word document, the value is updated in the Document Information Panel automatically or vice versa.
    If you'd like to know more about the Document Information Panel, be sure to check out this webcast.
    Emily Ching
    Software Design Engineer in Test
  • Microsoft InfoPath 2010

    Auto-Fill from List Box


    This came up on an internal mailing list:

    We have a secondary data source that holds a list of entries; part of the data in the list - a name field - is used to populate the items in a listbox in the view. When the user selects an item in the list, I want the rest of the data from that entry to be used to populate the form's main data source.

    Great scenario! It actually can be done with a combination of rules and filters (though I admit it’s not obvious), so you don’t have to write code for it.


    For this example, I will assume you have a form with:

    • A secondary data source with repeating items (for example, a list of people each with an ID, Name and Age)
    • A dropdown that lists the values in the data source (e.g. displays the name of each person and uses the ID as the value)
    • A set of nodes in your main data source that should be auto-populated when the dropdown changes (e.g. An age textbox that gets the age of the person selected in the dropdown)

    What you’ll need to do is create a rule on the dropdown. The rule will set the value in the textbox by filtering the corresponding value in the secondary data source down to one that matches the dropdown selection.


    Here’s how to do it:

    1. Double click the dropdown to open its Properties Dialog (it can be bound to a node in the main data source or in a secondary one, it doesn’t matter)
    2. Click the Rules button
    3. Click Add to add a rule
    4. Click Add Action
    5. For the Action, select Set a field’s Value
    6. For the Field, select the selectedAge node or whatever node you want to set automatically
    7. For the Value, click the Fx button
    8. In the Formula dialog, click Insert Field or Group
    9. In the Data Source dialog, select the secondary data source and then the age node or whatever node you want copy over
    10. Click the Filter button
    11. In the Filter dialog, set the filter to “secondary-data-source-ID is equal to main-data-source-ID”
    12. OK out of all dialogs, you’re done.

    Note that if your dropdown is inside a repeating section/table, then you will need to manually adjust the value in the formula dialog after step 11 to use the “current()” function so the filter works correctly.


  • Microsoft InfoPath 2010

    Upgrading InfoPath 2007 forms with Person/Group Pickers to InfoPath 2010


    Hi, this is Frank Mueller again and this is the second of two posts that I’ve written about the InfoPath 2010 Person / Group picker control. InfoPath 2007 form templates containing the Person/Group Picker control (formerly named Contact Selector) will continue to work in InfoPath 2010 the same way they used to as long as the form template remains in the InfoPath 2007 Form Template format. However, if you wish to upgrade your form template to InfoPath 2010 to take advantage of newly added functionality for the control (see this blog post for more details) or other exciting new features, you will have to perform the steps outlined in this post in order to use the Person/Group Picker.

    If you follow the steps outlined in this blog post to change your form template, you are changing the data schema of the form template. This means you will not be able to view any previously filled out forms with the new form template. In order to avoid data loss, you should create a new InfoPath 2010 version of your form template and publish it to a different location. This way you can continue to view previously filled out forms with the InfoPath 2007 version of your form template.

    Saving the form template in InfoPath 2010 form template format

    1. Click the File button and select Save As
    2. In the Save As dialog select the corresponding InfoPath 2010 Web Browser or Filler Form Template in the Save as type dropdown.
    3. Change the file name to be something different so that you don’t overwrite your existing form template
    4. Click Save

    Removing existing versions of the control from the form

    After the form template is saved in the new format, you will notice that each Person/Group Picker in your view will show the following error message when you hover your mouse cursor over it.

    Incompatibility error visual

    Also the Design Checker task pane appears, indicating that the version of the Person/Group Pickers in the view is not compatible with InfoPath 2010. For each Person/Group Picker in all views, do the following:

    1. Select the Person/Group Picker control in the view
    2. Notice that the XML node tree that the control is bound to will be highlighted in the Fields task pane (if the Fields task pane is not visible, click Show Fields on the Data tab in the Ribbon).
    3. Delete the highlighted XML node tree by deleting the root node in the Fields task pane (Right-click the node, and select Delete from the context menu)                                                   Fields Task pane
    4. Select the Person/Group Picker control in the view and delete it
    5. Use the Controls Gallery on the Home tab to insert a new Person/Group Picker at the position in the view where you just deleted the control
    6. Right-click the newly inserted control in the view and select Person/Group Picker Properties from the context menu
    7. In the Person/Group Picker Properties dialog select the SharePoint Server tab
    8. Type in the URL of the SharePoint site (If you don’t know the SharePoint site that the control used to connect to, please follow the optional steps at the end of this blog post.) Control Properties
    9. Click OK to close the dialog


    Testing the Person / Group Picker

    Preview the form in InfoPath Designer or publish the form to a SharePoint site (be sure to publish to a different location in order to be able to view previously filled out forms) and view the form, enter a name or logon alias, click the “Check Names” button and resolve the name! Alternatively you can click the “Address book” button to perform a search if you do not know the complete name of the user.

    Configuring advanced SharePoint list control properties (optional)

    To configure advanced control properties  that are new in InfoPath 2010, such as limiting the entities the control can pick, as well as requiring the control to contain data before the form can be submitted, follow the steps in this blog post.

    Determining the SharePoint site URL (optional)

    If you added the control to your InfoPath 2007 form template following the steps outlined in this blog post, you will have created a data connection called Context, which specifies the SharePoint site the Person/Group Picker should connect to. Follow these steps to recover the data connection XML file and obtain the URL of SharePoint site:

    1. Start InfoPath Designer 2010 and open your InfoPath 2007 form template
    2. Click the Data tab and select Resource Files Data Tab - Resource Files
    3. In the Resource Files dialog select Context and click on the Export button to save the data connection XML to a location on your hard drive.
    4. Open the XML file in a text editor (e.g., notepad)
    5. Write down the siteUrl to configure the Person/Group Pickers

    Frank Mueller

    InfoPath Developer

  • Microsoft InfoPath 2010

    Collapsible Sections


    Collapsible Sections


    Mark asks:


    How do I create a collapsible section? That is, a section that can show/hide child controls, whether they are required or not. I can't use an optional section, because it requires binding.


    The easiest way to do this is to this is using Conditional Formatting. Select the Section control, then pick Format | Conditional Formatting.... Add a rule where the formatting is “Hide this control”.


    Adding conditional visibility to a section


    We often call this “conditional visibility.” Like everything in InfoPath, the view state is driven entirely by the data, so you need something in your data which maps to the expand/collapse state. One common approach is to add an attribute field to the group element the section is bound to. It shows up in your data when saved, and the expand/collapse state is saved when users save the form.


    Designing a collapsible section


    Bind a checkbox to the attribute, and you now have UI which lets the user control the state. If you prefer a button, you can create a rule which sets the value of the attribute; use two buttons with more conditional visibility rules to swap the label (e.g. between a + and a – to look like a TreeView). You can also write code which modifies the value of the attribute, and the section will show or hide.


  • Microsoft InfoPath 2010

    Cool Forms! Task Form


    This week’s cool form was submitted by Sean Cantellay of Cantellay Consulting. The form allows the user to select a SharePoint task from the right and view it in the form on the page. The task has been broken up into four views and the tab buttons moves the user through the different views. The user can also Escalate the task to another SharePoint group by clicking the Escalate button and selecting the group.

    Click on images for larger pictures.





    If you have a “cool” form that you would like to share with us, please send an e-mail with the following details to -

    • Attach 1 or 2 screenshots of your form
    • Provide a brief description of the form
    • You may also attach the XSN file (optional)

    The most popular submissions will be featured on our blog in future posts.

    Check out other Cool Forms here.

  • Microsoft InfoPath 2010

    "Design Once" and the new InfoPath 2007 Object Model

    One of the main design principles for InfoPath 2007 and Forms Services 2007 is that you can create your form once, write code for it once, build and publish it once, and then have it work in both the browser and the client. We call this Design Once.
    To make this possible for form templates with code, we created a new object model that works on both the client and the server, so that the exact same assembly can work in both places. This is similar to what the Compact .NET Framework provides for mobile devices, where you can write a WinForm app that works on both the desktop and a Windows Mobile smartphone. Using the InfoPath object model you can write code for your form that will run the same way both on client, when opened in InfoPath, and on the server, when opened in the browser.
    Getting started with System.Xml
    If you've written code for InfoPath 2003, then you're used to writing code against the MSXML-based object model. For example, you might read and write a field's value like this in C# with the old object model:
    string xpath = "/my:myFields/my:field1";
    IXMLDOMNode field1 = thisXDocument.DOM.selectSingleNode(xpath);
    string oldValue = field1.text; // Read
    field1.text = "New Value";     // Write
    Here's how to do the same thing using the new object model:
    string xpath = "/my:myFields/my:field1";
    XPathNavigator field1 = MainDataSource.CreateNavigator().SelectSingleNode(xpath, NamespaceManager);
    string oldValue = field1.Value; // Read
    field1.SetValue(“New Value”);   // Write
    If we break that down, we see the following mappings:
    InfoPath 2003 OM
    InfoPath 2007 OM
    Read field1.text
    Read field1.Value
    Set field1.text
    Set using field1.SetValue()
    Compatibility: Using the old OM in InfoPath 2007
    InfoPath continues to open forms that used the old object model, so you don't have to upgrade them just to use InfoPath 2007. That said, if you want a form to work in the browser, you will need to upgrade to the new object model. If you upgrade the code, InfoPath will automatically update the project format and rebind all your events, but you will need to convert your custom functions to the new OM.
    Compatibility: Using the new OM in InfoPath 2003
    The new object model won't work in InfoPath 2003, so we also allow you to create forms that use the old object model in InfoPath 2007. You can choose which version of the object model you want to use in Form Options in the Programmability category. 
  • Microsoft InfoPath 2010

    Calling code/script from a Rule


    Rules are a quick way to add dynamic functionality to a form, so a lot of programmers choose to use rules even when they know how to write the code to do the same thing. However, sometimes after writing a complex set of rules they may realize that they need to do something rules doesn’t support, and we know they don’t want to rewrite all their rules in code just to add that one little bit.

    Alas, there’s no rules action type for “Call code”, but there is a roundabout way to call your code anyway.

    Let’s say you have the following function in your form template:

    Function Test(param)
      XDocument.UI.Alert("Param: " & param)
      Test = true
    End Function
    function Test(param) {
      XDocument.UI.Alert("Param: " + param);
      return true;
    Public Function Test(ByVal param As String) As Boolean
      thisXDocument.UI.Alert("Param: " & param)
      Test = True
    End Function
    public boolean Test(string param) {
      thisXDocument.UI.Alert("Param: " + param);
      return true;


    You can call that function from the condition of a rule by using the xdExtension namespace.

    For example, here’s how to call the function from a rule when the form is opened:

    1. Click Form Options on the Tools menu.
    2. On the Open and Save tab, click Rules.
    3. Click Add, name the rule, and then click Set Condition.
    4. Select The expression in the first drop-down list, and then enter: xdExtension:Test(“foo”)
    5. If you want the function to be conditional, then put the condition before the function call with an AND clause. For example, to get if foo>bar, then Test(“foo”), use foo>bar and xdExtension:Test(“foo”). (This is possible because conditions are evaluated using short-circuit boolean evaluation. In other words, they are evaluated one clause at a time, and if the first clause determines the result, then the rest of the conditions are “short circuited” and don’t get executed.)
    6. The Rule dialog box requires at least one action, but if you don’t have any actions to run in that rule, you can click OK if you select the Stop processing rules when this rule finishes checkbox. To avoid actually stop processing rules, make your condition always return false. For example: xdExtension:Test(“foo”) and false (“false” here is actually looking for the node named “false” which doesn’t exist, so returns the empty set, which is translated to false(). You could just as easily use “foobar” or anything else.)

    Finally, extract your form files and add the following attribute to the manifest.xsf file’s xDocumentClass element:


  • Microsoft InfoPath 2010

    Layout Tips & Tricks


    2D vs. Flow

    One of the first things that experienced form designers will notice when using InfoPath is that layout of controls is not on a 2D design surface – it’s what we call “flow-based”. Controls function like images – or even character glyphs – in an application like Word. You can drag them around and insert them between words and use blank lines or spaces for positioning. To those designers who are used to precise layout using pixel grids or absolute coordinates, this can be disconcerting.

    To experienced web designers, however, this model is very familiar. Web pages have to be designed to layout dynamically based on the target device. When you’re designing a web page you simply don’t know how wide the browser window which will eventually display the page is, how large the fonts are for the user viewing the page, or even what color settings are applicable. And, of course, different browsers display the same content differently even if all other variables are the same.

    InfoPath templates face a similar set of challenges – but in this case, it’s the data and the form that is dynamic. A variable number of records can appear, parts of the form can show and hide, and users can type different amounts of text into controls which grow. A fixed 2D layout for controls simply wouldn’t work.

    Couple that with a desire to have our views be compatible with web standards (XSLT outputting XHTML), and you can see why we built InfoPath with a flow-based layout mechanism.

    Layout Tables

    A lot of the coolest features in the various Office System applications are likely to fall into two buckets: either you’ve never heard of them, or you couldn’t live without them. Here are a few: Format Painter, Styles & Formatting, Fill Down, and Pivot Tables. Once you’ve used any of those, it’s hard to imagine not having them.

    Tables for layout are like that.

    Web designers know that the trick for good dynamic layout is to use tables. Rather than absolute positions, tables allow for 2D layout of controls by expressing constraints and relative positioning. Even tools like the WinForms designer in Visual Studio .NET are moving in this direction, encouraging the use of docking and panels instead of Top/Left/Width/Height. This makes layout tweaks easier and can even make things like localization much more straightforward.

    A few tips for creating layout using tables:

    • If you’re copying an existing paper form, try sketching out a grid for it using a pencil and a ruler. Count how many rows and columns you need, insert that table, and then start inserting controls into the appropriate cells.
    • InfoPath provides a Layout task pane in design-mode which helps you get started using tables, and exposes some of the actions like Merge and Split Cells in a more convenient fashion.
    • When you drag a control into a table cell its width will be set to 100% automatically. Consider using separate cells for static text and for controls.
    • If you are working from a schema, try dragging a group into the view – for example, “myFields”. One of the options should be Controls in Layout Table which automatically creates a two column table with a standard form layout, containing controls with width set to 100%. You can resize the controls automatically by resizing the layout table.

    In the InfoPath 2003 SP-1 Preview we’ve added a few more table features:

    • a “fly-out” Insert Table button on the toolbar to make getting just the right table into the view easier
    • Draw Table – which definitely fits in with the Format Painter as one of the lesser known but essential tricks in your form design arsenal

    If you’ve never used the Draw Table tool, you should try it. Select Table | Draw Table. This will show the Table toolbar, and enter a mode where you can drag out a rectangle using the mouse to create the first cell, and then draw lines across it to split the cell into two. Keep drawing lines to keep splitting cells. You can change the Border Style on the toolbar to change the style of the borders you create, or use the Eraser tool to erase borders – merging cells.

    Layout “Grid”

    Here’s a cool trick from the team. In the SP-1 Preview, there exists the availability to include a background image.  Here’s a sample grid image:

    Copy the above image and save it to your system as a bmp (no loss in fidelity).  Now go into the View properties dialog, click on ‘Use a background picture’.  In the ‘Files of type’ dropdown, select ‘All Files (*.*)’ and finally select the grid image you just saved.  Back in the View Properties dialog, check “Tile horizontally” and “Tile vertically”.  Click OK.

    Now you have yourself a grid by which to align your controls and text by – this is especially useful when aligning controls between layout tables, aligning tables themselves, or in cases where tables just aren’t appropriate.  When you are ready to publish the form, just go back to the properties dialog and take out the background image.   

  • Microsoft InfoPath 2010

    Template Parts 101


    So, you’ve heard about this new InfoPath 2007 feature called template parts. You may have even found the option to design one in the Design a Form Template dialog. But what you can do with it and why you would want to bother.. well that’s just a big mystery. So, I’m here to help you out.

    Template parts are simply mini form templates: you can add layout, controls, rules, data validation, conditional formatting and data connections. Once built, you can include template parts in other form templates so that you only have to build common components once. When you need to make changes, you change the template part and then update its version within the form templates using it. You don’t have to make the modification numerous times. Common scenarios for template part use include:

    • Company letterhead
    • Employee information (address, phone number)
    • Purchase order

    How to build a template part

    Template parts are built in the same way that form templates are built, though there is a slight difference in how you get started. Because there are some limitations in what you can put into a template part (see "What template parts don’t do" below), they are built in a separate mode from regular form templates. This allows you to be sure that whatever you put into the template part will function as intended. At the Design a Form Template dialog, select the Template Part radio button:

    Note that you can also choose whether or not the template part will be used in browser-enabled forms. If you aren’t sure, err on the side of caution and select “Enable browser-compatible features only”. This will ensure that you can use the template part in both client-based and browser-compatible forms.

    Click OK and you can now design your template part as you would any other form template. When you are finished, save the template part (you will end up with a file ending in .xtp) and send it out to whoever you would like to use it.

    How to use a template part

    To actually put a template part into a form, you must first install it on your machine. This sounds a whole lot scarier than it actually is. All you need to do is click on the “Add or Remove Custom Controls…” link at the bottom of the Controls task pane and follow the instructions that appear:

    Once you’ve done this, the template part will show up in the Custom Controls area of the Controls task pane. You can now insert the template part into your form as you would any other control. Once your template part has been inserted, you can also make modifications to it that are specific to that form.

    How to update a template part

    When you make changes to a template part that is already in use, you must redistribute the template part. The people using it must then install the new version (see “How to use a template part” above) and update the ones in their forms. Once the new version is installed, template parts in the form will automatically notice that there is a newer version available. You can then right-click on the template part and select Update. If you have made any changes to the template part within the form itself, these changes will be overwritten by the update.

    What template parts don’t do

    Here are some of the things that you can’t do with template parts:

    • Script and managed code
    • ActiveX controls
    • Submit data connections
    • IRM
    • Multiple views

    The more complete list is available on Office Online. The general pattern is that anything that would be a form-level property is not available in template parts.

    I hope you will find template parts to be useful and a mite less mysterious than they were before.

    Happy form designing,

    Bojana Marjanovic
    Program Manager

  • Microsoft InfoPath 2010

    MSDN WebCasts: InfoPath 2007

    In April, the InfoPath team will present three MSDN WebCasts introducing the new features available in InfoPath 2007. These three presentations will provide a high-level overview of InfoPath 2007. In the future, we will offer more detailed presentations that dive down into individual features of InfoPath 2007.
    We hope you will join us for the first three InfoPath 2007 presentations. Here is more information about the first three talks including the schedule.
    New Features in Office InfoPath 2007
    Time: Tuesday, April 11, 2006 12:00 PM – 1:00 PM (PST)
    Presenter: Gray Knowlton, SR. Product Manager - Office
    Description: This webcast presents an overview of the new features in Microsoft Office InfoPath 2007 and InfoPath Forms Services. Join us to learn how you can use InfoPath 2007 to automate and extend business processes by utilizing XML and integration standards to connect electronic forms to virtually any application or system.
    Developing, Deploying, and Hosting Rich Client and Browser Forms for Microsoft Office InfoPath 2007
    Time: Tuesday, April 18, 2006 12:00 PM – 1:00 PM (PST)
    Presenter: Kalpita Deobhakta, Program Manager - InfoPath
    Description: Were you aware that you can design Microsoft Office InfoPath 2007 forms for both the rich client and the browser in a single step? This webcast presents the design-once process for InfoPath 2007, and covers debugging, deployment, and improving the performance and scalability of forms. Find out how to host the InfoPath rich client in other applications, and how to tightly integrate InfoPath 2007 forms into Web pages. We also discuss best practices for using the hosted form control to build powerful but easy-to-use solutions.
    Developing InfoPath Forms for Office InfoPath 2007
    Time: Monday, April 24, 2006 10:00 AM – 11:00 AM (PST)
    Presenter: Nima Mirzad, Program Manager - InfoPath
    Description: This webcast presents an overview of Microsoft Office InfoPath 2007 programmability features including the managed object model, template parts, and provisions for third-party hosting. We also discuss techniques for using Microsoft Visual Studio 2005 Tools for Applications (VSTA) and Microsoft Visual Studio 2005 Tools for the Microsoft Office System (VSTO) to develop Office InfoPath 2007 forms.
    Scott Roberts
    Software Design Engineering Lead
    Microsoft Office InfoPath
  • Microsoft InfoPath 2010

    Introduction to Sandboxed Solutions - Sort data in repeating tables using managed code

    Hi. My name is Phil Newman and I'm a program manager on the InfoPath team. In this post, I'd like to introduce you to one of my favourite new features in InfoPath 2010 - Sandboxed Solutions. In InfoPath 2010, forms with code can now be published directly to SharePoint without requiring the farm administrator to approve and upload them! These forms run in a sandboxed environment which protects other resources on the SharePoint server from malicious code.

    In this short video demo, I show how you can add the ability to sort repeating tables in your forms using code.  I use picture buttons in the heading of the repeating table to trigger the code which sorts the table based on the values in the columns. 

    Get Microsoft Silverlight

    About the Code

    In a nutshell, the code puts the XML from the repeating table into an array, sorts the array using built-in .Net functionality, and then writes back into the XML to update the table.

    //Sorts a repeating table.  Takes the parent group node and the index of the column to sort by.

    private void SortTable(string xpathToSort, int columnToSortBy)


    //get the values in an array

    string[][] ValuesToSort = GetRepeatingTableValues(xpathToSort);

    //sort the array

    Array.Sort(ValuesToSort, new StringArrayComparer(columnToSortBy));

    //write the values back to the xml

    SetRepeatingTableValues(xpathToSort, ValuesToSort);


    //Takes an array of arrays and inserts it into a repeating table

    //Assumes that the array and table are the same size

    private void SetRepeatingTableValues(string xpathToSet, string[][] tableValues)


    //Create a navigator on main node supplied in the parameters

    XPathNavigator mainGroup = this.CreateNavigator().SelectSingleNode(xpathToSet, this.NamespaceManager);

    //Clone the first child node of the main navigator and populate it with data

    XPathNodeIterator tableRows = mainGroup.SelectChildren(XPathNodeType.Element);


    //iterate through the existing XML and update the values from the sorted array

    for (int i = 0; i < tableValues.Length; i++)



    XPathNodeIterator thisRow = tableRows.Current.SelectChildren(XPathNodeType.Element);

    for (int j = 0; j < tableValues[0].Length; j++)



    thisRow.Current.InnerXml = tableValues[i][j];




    //Returns an array of arrays of strings representing the values in a repeating table

    private string[][] GetRepeatingTableValues(string xpathToGet)


    XPathNavigator myNav = this.CreateNavigator();

    int rows, cols;

    XPathNodeIterator tableNodes;

    //figure out the dimensions of the table

    tableNodes = myNav.SelectSingleNode(xpathToGet, this.NamespaceManager).SelectChildren(XPathNodeType.Element);

                rows = tableNodes.Count;


    //move to the first row to count the columns


    cols = tableNodes.Current.SelectChildren(XPathNodeType.Element).Count;

    //create an array to store the values

    string[][] tableValues = new string[rows][];

    //get all the rows in the table

    tableNodes = myNav.SelectSingleNode(xpathToGet, this.NamespaceManager).SelectChildren(XPathNodeType.Element);

    //iterate through the rows and write the inner xml of each element in each row to the array

    for (int i = 0; i < rows; i++)



    XPathNodeIterator childNodes = tableNodes.Current.SelectChildren(XPathNodeType.Element);

    string[] rowValues = new string[cols];

    for (int j = 0; j < cols; j++)



    rowValues[j] = childNodes.Current.InnerXml;


    tableValues[i] = rowValues;


    return tableValues;


    //Comparison implementation for array or arrays

    class StringArrayComparer : IComparer


    private int iColumn;

    public StringArrayComparer(int iColumn)


    this.iColumn = iColumn;


    int IComparer.Compare(Object x, Object y)


    string[] xAsString = (string[])x;

    string[] yAsString = (string[])y;

    return xAsString[iColumn].CompareTo(yAsString[iColumn]);



    Requirements for publishing your forms with code as Sandboxed solutions:

    • The Sandboxed code service need to be enabled on the farm
    • You must be a site collection administrator on the site collection you’re publishing to
    • Your form must be domain trust
    • Your form template must be an InfoPath 2010 template
    • InfoPath 2007 form code needs to be upgraded to InfoPath 2010 form code

    Complete sandboxed solution documentation is available here.  Note that InfoPath takes care of packaging and activating the solution, all you need to do is publish your form to a document library or as a site content type.

    I look forward to hearing your comments about this new feature. Let me know what you think!


  • Microsoft InfoPath 2010

    Calculating new, default date and time values


    Similar to performing elapsed time calculations, creating a new date or time value based on a previous value used to require code – not anymore! With InfoPath 2007 you can use the new “addDays()” and “addSeconds()” functions to calculate a new date or time based on a previous value.

    To illustrate this, think of a daily task planner: you enter a start time for the first task and specify a duration time and interval. The starting value for the next task should be the prior tasks’ starting time plus the prior tasks’ duration. Using the addDays and addSeconds functions will allow you to specify the new starting date and time based on a duration specified in days, hours, minutes or seconds without writing any code!

    The following steps will create a sample Daily Task Planner to demonstrate how to implement these functions. A sample form template that implements this functionality is attached; make sure to save it locally before running it.

    1. Create the data structure

    a. Create a new browser-compatible form template
    b. Add a repeating group named: gpTasks to the myFields collection
    c. Add the following nodes to gpTasks:

    Name Data Type
    StartDateTime Date and Time (dateTime)
    TaskDesc Text (string)
    Duration Decimal (double)
    Interval Text (string)

    d. Add the following node to the myFields collection:

    Name Data Type
    NextStartTimeValue Date and Time (dateTime)

    Note: The “NextStartTimeValue” field is needed because using XPATH functions such as “preceding-sibling”, which could be used to get the prior elements values, are not supported in browser forms.


    2. Create the View

    a. Add gpTasks to the View as a Repeating Table
    b. Change the Interval Text Box to a Dropdown List Box
    c. Add the following entries to the Interval Dropdown list box:
    d. Add a new column to the right of the StartDateTime field and re-bind the newly created field to StartDateTime (this field will be used to display just the time value)
    e. Change the format of this new field to: *9:46 AM


    3. Add the expressions

    a. Set a default value for the StartDateTime field to the current date and time when the form is first launched (note - we don’t want the current date and time to be entered once we have rows of data:)
          Add a Rule to the Open event of the form
          Add the following Conditions to the Rule:
              - The “count” of gpTasks = 1 (i.e. count(my:gpTasks) = 1)
              - The NextStartTimeValue field is blank
          Add an Action to set the StartDateTime field to the “now()” function

    b. Add a “Set a field’s value” Rule to the Interval field to set the NextStartTimeValue field, with a condition that the rule should only fire if the Duration field is not blank. In the Value property for this Rule, we need to check the Duration and what Interval was selected so we can populate the NextStartTimeValue field with the correct date and time. Let’s take a look at how these expressions are created. (This information is based on using the advanced default value logic documented in this blog post)

    You can use the “concat”, “substring” and “string-length” functions to create an “if/else” type of statement. First, we want to see if the selected Interval was “Days” – to do this, we use the “contains” function along with the substring function.

    substring(xdDate:addDays(../my:StartDateTime, ../my:Duration), 1, contains(../my:Interval, "Days") * string-length(xdDate:addDays(../my:StartDateTime, ../my:Duration))

    You would actually interpret this expression right-to-left in this manner: “If the Interval field contains “Days” then use the addDays function to add the value in the Duration field to the value in the StartDateTime field.”

    We use a similar expression to check for the value of “Hours” in the Interval field and then use the “addSeconds” function to add the appropriate number of seconds:

    substring(xdDate:addSeconds(../my:StartDateTime, ../my:Duration * 60 * 60), 1, contains(../my:Interval, "Hours") * string-length(xdDate:addSeconds(../my:StartDateTime, ../my:Duration * 60 * 60))

    Lastly, if the Interval field does not contain Days or Hours then it must contain “Minutes”:

    substring(xdDate:addSeconds(../my:StartDateTime, ../my:Duration * 60), 1, contains(../my:Interval, "Minutes") * string-length(xdDate:addSeconds(../my:StartDateTime, ../my:Duration * 60))

    We then use the “concat” function to bring all of these expressions together to set the Value property:

    concat(substring(xdDate:addDays(../my:StartDateTime, ../my:Duration), 1, contains(../my:Interval, "Days") * string-length(xdDate:addDays(../my:StartDateTime, ../my:Duration))), substring(xdDate:addSeconds(../my:StartDateTime, ../my:Duration * 60 * 60), 1, contains(../my:Interval, "Hours") * string-length(xdDate:addSeconds(../my:StartDateTime, ../my:Duration * 60 * 60))), substring(xdDate:addSeconds(../my:StartDateTime, ../my:Duration * 60), 1, contains(../my:Interval, "Minutes") * string-length(xdDate:addSeconds(../my:StartDateTime, ../my:Duration * 60))))

    c. Add a “Set a field’s value” Rule to the Duration field to also set the NextStartTimeValue field – again, add a condition where we only want this rule to fire if the Interval field is not blank. Use the same expression as above to set the Value property:

    concat(substring(xdDate:addDays(../my:StartDateTime, ../my:Duration), 1, contains(../my:Interval, "Days") * string-length(xdDate:addDays(../my:StartDateTime, ../my:Duration))), substring(xdDate:addSeconds(../my:StartDateTime, ../my:Duration * 60 * 60), 1, contains(../my:Interval, "Hours") * string-length(xdDate:addSeconds(../my:StartDateTime, ../my:Duration * 60 * 60))), substring(xdDate:addSeconds(../my:StartDateTime, ../my:Duration * 60), 1, contains(../my:Interval, "Minutes") * string-length(xdDate:addSeconds(../my:StartDateTime, ../my:Duration * 60))))

    d. Add a “Set a field’s value” Rule to the Repeating Table to set the StartDateTime field to the value stored in the NextStartTimeValue field (this is what will set the Start Date and Time fields when a new row is added to the table)


    4. Test!

    Here is a sample completed Task Planner:

    NOTE: Because this is a “no code” solution, if you modify an existing start date or time there is no way to enumerate the balance of the nodes to reflect this change. A feature such as this would require code.

    Scott Heim
    Support Engineer

  • Microsoft InfoPath 2010

    Microsoft Office InfoPath 2003 Toolkit for Visual Studio 2005


    Visual Studio 2005, SQL Server 2005, and BizTalk 2006 all launched on Monday.

    That means the Microsoft Office InfoPath 2003 Toolkit for Visual Studio 2005 is now available as part of the Visual Studio 2005 Tools for the Microsoft Office System.

    To install the Toolkit, run setup from the CD labeled "Microsoft Office InfoPath 2003 Toolkit for Visual Studio 2005" that is included with the Visual Studio 2005 Tools for Office package, or from the separate related download for MSDN Subscribers.

    Find out more here:


  • Microsoft InfoPath 2010

    UDC File Authoring Tool


    Some time ago, we blogged about the reasons why you'd use UDC files and the anatomy of UDC files. You may be wondering, however, if it's possible to author these files in InfoPath - after all, UDC files are just XML files.

    You're right - this is definitely possible. Attached to this article is a form template that lets you author and edit UDC files. Here are the steps you need to take to make it work:

    1) Download the attached form template, save it to your desktop

    2) Right-click on the downloaded .xsn file, then select Design. Ignore any warnings about the published location.

    3) Go to File | Publish | Network Location, and republish the form template. Then open the form template from its published location.

    Enjoy, and let us know if you have any feedback on the tool.

    Nick Dallett
    Lead Program Manager
    Travis Rhodes
    Software Design Engineer in Test
Page 3 of 12 (298 items) 12345»