Programmatically removing the first row actually removes 2 rows - InfoPath Dev
in

InfoPath Dev

Use our Google Custom Search for best site search results.

Programmatically removing the first row actually removes 2 rows

Last post 03-25-2009 04:27 PM by Hilary Stoupa. 3 replies.
Page 1 of 1 (4 items)
Sort Posts: Previous Next
  • 03-25-2009 02:02 PM

    Programmatically removing the first row actually removes 2 rows

    I've built an InfoPath form that queries WMI data and displays it in the form so that we can submit the info to a SharePoint list.

    I'm putting on the final touches and am having problems with one small section.  When i query the RAM, i have it display the information into a repeating table.  The problem is when i create the repeating table for some reason it duplicates the first row.  I found an article on how to remove the first row (http://www.bizsupportonline.net/infopath2007/programmatically-delete-first-row-repeating-table-infopath.htm)

    I use this same bit of code to remove the first row from another section and it works just fine, but for some reason when i do this very same thing it deletes the first 2 rows.  I can't figure out why it works fine in one section but not in the other section, i copied and pasted the same bit of code so it should work the same.  If someone could help me figure out what's going on here i'd appreciate it.

    code sample:

    using Microsoft.Office.InfoPath;

    using System;

    using System.Xml;

    using System.Xml.XPath;

    using System.Management;

    using System.Net.NetworkInformation;

    namespace Inventory_Rev1

    {

    public partial class FormCode

    {

    // Member variables are not supported in browser-enabled forms.

    // Instead, write and read these values from the FormState

    // dictionary using code such as the following:

    //

    // private object _memberVariable

    // {

    // get

    // {

    // return FormState["_memberVariable"];

    // }

    // set

    // {

    // FormState["_memberVariable"] = value;

    // }

    // }

    // NOTE: The following procedure is required by Microsoft Office InfoPath.

    // It can be modified using Microsoft Office InfoPath.

    ManagementObjectSearcher searcherMemory =

    new ManagementObjectSearcher("root\\CIMV2",

    "SELECT * FROM Win32_PhysicalMemory");

    public void InternalStartup()

    {

    EventManager.FormEvents.Loading += new LoadingEventHandler(FormEvents_Loading);

    }

    public void FormEvents_Loading(object sender, LoadingEventArgs e)

    {

    foreach (ManagementObject queryObj in searcherMemory.Get())

    {

    int counter = 1;

    {

    string slot = queryObj["DeviceLocator"].ToString();

    string capacity = queryObj["Capacity"].ToString();

    string speed = queryObj["Speed"].ToString();


    // Create an XPathNavigator to walk the main data source

    // of the form.

    XPathNavigator xnMyForm = this.CreateNavigator();

    XmlNamespaceManager ns = this.NamespaceManager;

    // Set the fields in the form.

    xnMyForm.SelectSingleNode("/my:myFields/my:Memory/my:Ram/my:slot", ns)

    .SetValue(slot);

    xnMyForm.SelectSingleNode("/my:myFields/my:Memory/my:Ram/my:capacity", ns)

    .SetValue(capacity);

    xnMyForm.SelectSingleNode("/my:myFields/my:Memory/my:Ram/my:speed", ns)

    .SetValue(speed);


    // Increment the counter

    counter++;

    // Add the item to the repeating table

    AddItemMemory(slot, capacity, speed);

     

    // Remove the first empty item from the repeating table

    DeleteFirstEmptyItemMemory();

    }

    }

    }

    private void AddItemMemory(string slot, string capacity, string speed)

    {

    XmlDocument doc = new XmlDocument();

    XmlNode group = doc.CreateElement("Ram",

    NamespaceManager.LookupNamespace("my"));

    XmlNode field = doc.CreateElement("slot",

    NamespaceManager.LookupNamespace("my"));

    XmlNode node = group.AppendChild(field);

    node.InnerText = slot;

    field = doc.CreateElement("capacity",

    NamespaceManager.LookupNamespace("my"));

    node = group.AppendChild(field);

    node.InnerText = capacity;

    field = doc.CreateElement("speed",

    NamespaceManager.LookupNamespace("my"));

    node = group.AppendChild(field);

    node.InnerText = speed;

    doc.AppendChild(group);

    MainDataSource.CreateNavigator().SelectSingleNode(

    "/my:myFields/my:Memory",

    NamespaceManager).AppendChild(doc.DocumentElement.CreateNavigator());

     

    }

    private void DeleteFirstEmptyItemMemory()

    {

    XPathNavigator domNav = MainDataSource.CreateNavigator();

    XPathNavigator itemNav = domNav.SelectSingleNode(

    "/my:myFields/my:Memory/my:Ram[1]",

    NamespaceManager);

    if (itemNav != null)

    itemNav.DeleteSelf();

    }

    }

    }

    Filed under: , ,
  • 03-25-2009 02:41 PM In reply to

    Re: Programmatically removing the first row actually removes 2 rows

    Hi -- I'm wondering if it is because you are calling your DeleteFirstEmptyItemMemory() method inside your for each loop. It is set to delete the first node, whether it is blank or not, so I'd imagine it would delete a row each time you went through the loop.... might be safer to do something like this:

    XPathNavigator itemNav = domNav.SelectSingleNode("/my:myFields/my:Memory/my:Ram[my:slot = \"\"]";

    To get the Ram group where slot is blank. Of course, no guarantees that will return only one row. I think, looking at your code, since this runs on load, you could also set the form not to include a 'Ram' row on open, thus solving your empty row problem -- under Tools / Default Values you can choose which nodes are included when the form is created. If you do that, though, none of these lines will work:

    // Set the fields in the form.

    xnMyForm.SelectSingleNode("/my:myFields/my:Memory/my:Ram/my:slot", ns)

    .SetValue(slot);

    xnMyForm.SelectSingleNode("/my:myFields/my:Memory/my:Ram/my:capacity", ns)

    .SetValue(capacity);

    xnMyForm.SelectSingleNode("/my:myFields/my:Memory/my:Ram/my:speed", ns)

    .SetValue(speed);

    I'm a little perplexed by those lines (and by the counter...). It seems as if you are setting the existing row in the form to values, then using another method to create a new group with the values, and appending it. You have a counter -- but I don't see it being used for anything, since you are using a for each loop. Each time through the loop, you'll be setting the values in the first row in the repeating table to the first set of values from your secondary data source.

    Without actually having your form or having tested your code, I'd think your loading code could go to:

            public void FormEvents_Loading(object sender, LoadingEventArgs e)        {             foreach (ManagementObject queryObj in searcherMemory.Get())            {                      string slot = queryObj["DeviceLocator"].ToString();                     string capacity = queryObj["Capacity"].ToString();                     string speed = queryObj["Speed"].ToString();                     // Add the item to the repeating table                     AddItemMemory(slot, capacity, speed);             }              // Remove the first empty item from the repeating table             DeleteFirstEmptyItemMemory(); 

            }

    Changing the DeleteFirstEmptyItemMemory() method to be more specific about what to delete, or leaving it out all together and setting the form not to include that repeating group when it is opened....

    Hilary Stoupa

  • 03-25-2009 03:43 PM In reply to

    Re: Programmatically removing the first row actually removes 2 rows

    Your suggestions worked perfectly.  I had that counter in there from the sample code i grabbed off (http://www.bizsupportonline.net/infopath2007/how-to-submit-items-rows-repeating-table-infopath-sharepoint-list.htm), but now that i read it over again, that was some code i had used for another form i did and didnt realize it didnt apply here.  I'm new to C# and am fumbling my way through it as i've had no real training.  Just headbutting code samples i find out on the internet and trying to get them to work the way i need.  I'm researching some classes to take to get a better grasp on programming, but am still a little lost as to what classes would help the best.

     

    Thank you again, that helped me with the very last step in getting this form to work properly, not just have to work on the submitting to a Sharepoint list portion, but i've done that before and should be OK.

  • 03-25-2009 04:27 PM In reply to

    Re: Programmatically removing the first row actually removes 2 rows

    Actually, Google University isn't that bad -- working from code samples can definitely get you started. As you have time, may I suggest the C# tutorials on MSDN? Located here, they may help you with the basics, so that the InfoPath code samples you find and adapt won't be as perplexing.

    Hilary Stoupa

Page 1 of 1 (4 items)
Copyright © 2003-2019 Qdabra Software. All rights reserved.
View our Terms of Use.