Programmatically move items between two lists in InfoPath using C# code

Applies to: InfoPath 2007

Learn how to copy items from a secondary data source to a list in the Main data source of a form and then move items between two lists which are bound to two repeating groups in the Main data source of the form template.

ADVERTISEMENTS

Problem

You have two list boxes on an InfoPath form. You populate (fill) the left list box with items from a secondary data source. Now you would like to select an item from the left list, click a button, and move that selected item to the right list. Similarly, you would like to select an item from the right list, click another button, and move that selected item to the left list.

Solution

Bind each list box to a repeating group in the Main data source of the form template, copy all items from a secondary data source to the repeating group that is bound to the left list, and write code in the Clicked event for button controls to add and delete items to and from the repeating groups that the list boxes are bound to.

Before You Begin

You should know how to do the following:

Discussion

In Programmatically add items to a drop-down list box in InfoPath 2007 I explained that a drop-down list box in InfoPath consists of a field that stores the value of the selected item and a repeating node in the Main or a secondary data source, which the drop-down list box is bound to.

A list box in InfoPath follows the same concept as that of a drop-down list box, so you can apply the same logic to it.

  1. Create a new blank InfoPath form template, and add two List Box controls and two Button controls to it as shown in the following figure:

    The InfoPath form template in Design mode with two list boxes
    Figure 1. The InfoPath form template in Design mode with two list boxes.

    Name the list boxes leftListSelectedItem and rightListSelectedItem, and name the button controls btnMoveRight and btnMoveLeft.
  2. Construct a Main data source as shown in the following figure:

    The Main data source of the InfoPath form template with two list boxes
    Figure 2. The Main data source of the InfoPath form template with two list boxes.

    where leftListSelectedItem and rightListSelectedItem represent the list boxes on the form template.
  3. On the Properties dialog box of leftListSelectedItem, bind the list box to the leftListItem repeating node and on the Properties dialog box of rightListSelectedItem, bind the list box to the rightListItem repeating node.
  4. Create an XML file with the following contents: <?xml version="1.0" encoding="UTF-8" ?>
    <officeapplications>
    <officeapplication>
    <id>1</id>
    <name>Access</name>
    </officeapplication>
    <officeapplication>
    <id>2</id>
    <name>Excel</name>
    </officeapplication>
    <officeapplication>
    <id>3</id>
    <name>InfoPath</name>
    </officeapplication>
    <officeapplication>
    <id>4</id>
    <name>PowerPoint</name>
    </officeapplication>
    <officeapplication>
    <id>5</id>
    <name>Word</name>
    </officeapplication>
    </officeapplications>
  5. Add a Receive data connection to the XML file and name the data connection officeapplication.
  6. On the Tools menu, click Programming, and then click Loading Event.
  7. Add the following C# code to the Loading event: XPathNavigator secDSNav = DataSources["officeapplication"].CreateNavigator();

    // Retrieve the rows of the secondary data source
    XPathNodeIterator rows = secDSNav.Select("/officeapplications/officeapplication",
    NamespaceManager);

    // Loop through the rows of the secondary data source and fill the left list with items
    while (rows.MoveNext())
    {
    string name = rows.Current.SelectSingleNode(
    "name", NamespaceManager).Value;
    string value = rows.Current.SelectSingleNode(
    "id", NamespaceManager).Value;

    // Add the item to the left list
    AddLeftListItem(name, value);
    }

    // Remove the empty item from the left list
    DeleteLeftListItem("");
  8. Add the following private function to add an item to the left list: private void AddLeftListItem(string name, string value)
    {
    XmlDocument doc = new XmlDocument();
    XmlNode group = doc.CreateElement("leftListItem",
    NamespaceManager.LookupNamespace("my"));

    XmlNode field = doc.CreateElement("leftListItemName",
    NamespaceManager.LookupNamespace("my"));
    XmlNode node = group.AppendChild(field);
    node.InnerText = name;

    field = doc.CreateElement("leftListItemValue",
    NamespaceManager.LookupNamespace("my"));
    node = group.AppendChild(field);
    node.InnerText = value;

    doc.AppendChild(group);

    MainDataSource.CreateNavigator().SelectSingleNode(
    "/my:myFields/my:leftList",
    NamespaceManager).AppendChild(doc.DocumentElement.CreateNavigator());
    }
  9. Add the following private function to add an item to the right list: private void AddRightListItem(string name, string value)
    {
    XmlDocument doc = new XmlDocument();
    XmlNode group = doc.CreateElement("rightListItem",
    NamespaceManager.LookupNamespace("my"));

    XmlNode field = doc.CreateElement("rightListItemName",
    NamespaceManager.LookupNamespace("my"));
    XmlNode node = group.AppendChild(field);
    node.InnerText = name;

    field = doc.CreateElement("rightListItemValue",
    NamespaceManager.LookupNamespace("my"));
    node = group.AppendChild(field);
    node.InnerText = value;

    doc.AppendChild(group);

    MainDataSource.CreateNavigator().SelectSingleNode(
    "/my:myFields/my:rightList",
    NamespaceManager).AppendChild(doc.DocumentElement.CreateNavigator());
    }
  10. Add the following private function to delete an item from the left list: private void DeleteLeftListItem(string value)
    {
    XPathNavigator domNav = MainDataSource.CreateNavigator();
    XPathNavigator leftListItemNav = domNav.SelectSingleNode(
    "/my:myFields/my:leftList/my:leftListItem[my:leftListItemValue='" + value + "']",
    NamespaceManager);

    if (leftListItemNav != null)
    leftListItemNav.DeleteSelf();
    }
  11. Add the following private function to delete an item from the right list: private void DeleteRightListItem(string value)
    {
    XPathNavigator domNav = MainDataSource.CreateNavigator();
    XPathNavigator rightListItemNav = domNav.SelectSingleNode(
    "/my:myFields/my:rightList/my:rightListItem[my:rightListItemValue='" + value + "']",
    NamespaceManager);

    if (rightListItemNav != null)
    rightListItemNav.DeleteSelf();
    }
  12. In InfoPath, double-click on the Move Right button to open its Properties dialog box.
  13. On the Properties dialog box for btnMoveRight, click Edit Form Code to add a Clicked event handler.
  14. Add the following C# code to the Clicked event handler of btnMoveRight: // Retrieve value of the selected item in left list
    XPathNavigator domNav = MainDataSource.CreateNavigator();
    XPathNavigator selItemNav = domNav.SelectSingleNode(
    "/my:myFields/my:leftListSelectedItem", NamespaceManager);
    string value = string.Empty;
    if (selItemNav != null)
    value = domNav.SelectSingleNode(
    "/my:myFields/my:leftListSelectedItem", NamespaceManager).Value;

    // If no item was selected, exit
    if (String.IsNullOrEmpty(value))
    return;

    // Look up the name of the selected item in the left List in the Main data source
    string name = domNav.SelectSingleNode(
    "/my:myFields/my:leftList/my:leftListItem[my:leftListItemValue = '" +
    value + "']/my:leftListItemName", NamespaceManager).Value;

    // Add the item to the right list
    AddRightListItem(name, value);

    // Delete the item from the left list
    DeleteLeftListItem(value);

    // Clear the selected item in the left list
    domNav.SelectSingleNode(
    "/my:myFields/my:leftListSelectedItem", NamespaceManager).SetValue("");

    // Delete the empty item in the right list if it exists
    DeleteRightListItem("");
  15. In InfoPath, double-click on the Move Left button to open its Properties dialog box.
  16. On the Properties dialog box for btnMoveLeft, click Edit Form Code to add a Clicked event handler.
  17. Add the following C# code to the Clicked event handler of btnMoveLeft: // Retrieve value of the selected item in right list
    XPathNavigator domNav = MainDataSource.CreateNavigator();
    XPathNavigator selItemNav = domNav.SelectSingleNode(
    "/my:myFields/my:rightListSelectedItem", NamespaceManager);
    string value = string.Empty;
    if (selItemNav != null)
    value = domNav.SelectSingleNode(
    "/my:myFields/my:rightListSelectedItem", NamespaceManager).Value;

    // If no item was selected, exit
    if (String.IsNullOrEmpty(value))
    return;

    // Look up the name of the selected item in the right List in the Main data source
    string name = domNav.SelectSingleNode(
    "/my:myFields/my:rightList/my:rightListItem[my:rightListItemValue = '" +
    value + "']/my:rightListItemName", NamespaceManager).Value;

    // Add the item to the left list
    AddLeftListItem(name, value);

    // Delete the item from the right list
    DeleteRightListItem(value);

    // Clear the selected item in the right list
    domNav.SelectSingleNode(
    "/my:myFields/my:rightListSelectedItem", NamespaceManager).SetValue("");

    // Delete the empty item in the left list if it exists
    DeleteLeftListItem("");
  18. Save your work, build the code, and test the form.

Now when you open the form, the left list will contain the items from the XML file and when you select an item from the left list and click on the Move Right button, the item will be added to the right list and removed from the left list. Similarly, if you select an item from the right list and then click on the Move Left button, the item will be added to the left list and removed from the right list.

 


Related InfoPath Articles:

 

Copyright: This article may not be used on web sites (whether personal or otherwise), copied, disseminated, altered, printed, published, broadcasted, or reproduced in any way without an expressed written consent. The techniques demonstrated in this article may be used within any Microsoft InfoPath project. This article is provided without any warranties. Copyright for this article is non-transferrable and remains with the author.

InfoPath 2013 Cookbook: 121 Codeless Recipes for Beginners

InfoPath 2013 Cookbook 2: 121 Codeless Recipes for SharePoint 2013

InfoPath 2010 Cookbook: 101 Codeless Recipes for Beginners

InfoPath 2010 Cookbook 2: 101 Codeless Recipes for SharePoint 2010

InfoPath 2010 Cookbook 3: 101 Code Recipes for C# Developers

InfoPath 2010 Cookbook 4: 101 Code Recipes for VB Developers

InfoPath 2010 Cookbook 5: Integrating InfoPath with Excel and Excel Services