Programmatically move items between two lists in InfoPath using C# code
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.
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.
- 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:
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. -
Construct a Main data source as shown in the following figure:
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. - 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.
- 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>
- Add a Receive data connection to the XML file and name the data connection officeapplication.
- On the Tools menu, click Programming, and then click Loading Event.
-
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("");
-
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());
}
-
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());
}
-
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();
}
-
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();
}
- In InfoPath, double-click on the Move Right button to open its Properties dialog box.
- On the Properties dialog box for btnMoveRight, click Edit Form Code to add a Clicked event handler.
- 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("");
- In InfoPath, double-click on the Move Left button to open its Properties dialog box.
- On the Properties dialog box for btnMoveLeft, click Edit Form Code to add a Clicked event handler.
- 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("");
- 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:
